summaryrefslogtreecommitdiffstats
path: root/src/s60main/newallocator_hook.cpp
diff options
context:
space:
mode:
authormread <qt-info@nokia.com>2010-10-08 14:31:09 (GMT)
committermread <qt-info@nokia.com>2010-10-11 11:37:51 (GMT)
commitc27f1586d7c4c56af1f46fa09ad77f03b7736e5d (patch)
treebf375bd9b206bc07e110b9c104056a96c7a35e2f /src/s60main/newallocator_hook.cpp
parent3c2296647d2e7ddda4df6679a622b0bf46b34c35 (diff)
downloadQt-c27f1586d7c4c56af1f46fa09ad77f03b7736e5d.zip
Qt-c27f1586d7c4c56af1f46fa09ad77f03b7736e5d.tar.gz
Qt-c27f1586d7c4c56af1f46fa09ad77f03b7736e5d.tar.bz2
Making the hybrid allocator change compatible across all 4.7.x
The hybrid allocator introduced a new export to qtcore.dll and made all apps link to it when they linked with the corresponding qtmain.lib. However, this made all apps depend on this new export, and since that export is not present in early 4.7.x release, these apps would not run with the Qt DLLs from those releases, which breaks Qt's compatibility guarantees for patch releases. This change makes apps compatible with all 4.7.x releases again. For export frozen Qt builds (the sort that should be compatible across all 4.7.x releases), qtmain.lib no longer forces a static import link to qt_symbian_SetupThreadHeap(). Instead it dynamically loads qtcore.dll, looks up qt_symbian_SetupThreadHeap(), and calls it if present. If the function is not present, or on emulator builds where we know that qtcore will use the system allocator creation function, we call the system allocator creation function. For export unfrozen builds, there is no compatibility between builds or releases, so we do use a static import link to qt_symbian_SetupThreadHeap(), as we have to use the qtcore dll we have built with it anyway. This has been tested as follows: S60 3.1 SDK, def files not frozen. App compiled against latest code runs on the corresponding DLLs, and does not start with 4.7.0, which is what we expect. S60 3.2 SDK, def files frozen. App compiled against latest code runs on the corresponding DLLs with the new allocator, and runs on 4.7.0 DLLs with the old allocator. Which demonstrates compatibility. S60 5.0 SDK, def files not frozen, debug build. Same result as for the 3.1 SDK, which demonstrates debug build working too (all other tests are release build tests). S60 5.0 SDK, def files frozen, debug build. Same result as on S60 3.2 SDK, which demonstrates debug build working with def files. Symbian^3 SDK, def files frozen. Same result as on S60 3.2 SDK, demonstrating Symbian^3 compatibility. Symbian^4, code and tests compile and does not affect running. *** This change is only required for 4.7. It is not needed for 4.8+ *** *** If this change appears in 4.8+, it can be reverted. *** Task-number: QT-4080 Reviewed-by: Shane Kearns
Diffstat (limited to 'src/s60main/newallocator_hook.cpp')
-rw-r--r--src/s60main/newallocator_hook.cpp87
1 files changed, 86 insertions, 1 deletions
diff --git a/src/s60main/newallocator_hook.cpp b/src/s60main/newallocator_hook.cpp
index 9cc6afb..9ea2ef0 100644
--- a/src/s60main/newallocator_hook.cpp
+++ b/src/s60main/newallocator_hook.cpp
@@ -41,6 +41,11 @@
#include <e32std.h>
#include <qglobal.h>
+#ifdef QT_EXPORTS_NOT_FROZEN
+// If exports in Qt DLLs are not frozen in this build, then we have to pick up the
+// allocator creation function by import link. We know the function will be present
+// in the DLLs we test with, as we have to use the DLLs we have built.
+
struct SStdEpocThreadCreateInfo;
Q_CORE_EXPORT TInt qt_symbian_SetupThreadHeap(TBool aNotFirst, SStdEpocThreadCreateInfo& aInfo);
@@ -51,8 +56,88 @@ Q_CORE_EXPORT TInt qt_symbian_SetupThreadHeap(TBool aNotFirst, SStdEpocThreadCre
* Uses link-time symbol preemption to capture a call from the application
* startup. On return, there is some kind of heap allocator installed on the
* thread.
-*/
+*/
TInt UserHeap::SetupThreadHeap(TBool aNotFirst, SStdEpocThreadCreateInfo& aInfo)
{
return qt_symbian_SetupThreadHeap(aNotFirst, aInfo);
}
+
+#else // QT_EXPORTS_NOT_FROZEN
+// If we are using an export frozen build, it should be compatible with all 4.7.x Qt releases.
+// We want to use the allocator creation function introduced in qtcore.dll after 4.7.1. But we
+// can't import link to it, as it may not be present in whatever 4.7.x DLLs we are running with.
+// So the function is found and called dynamically, by library lookup. If it is not found, we
+// use the OS allocator creation functions instead.
+
+struct SThreadCreateInfo
+ {
+ TAny* iHandle;
+ TInt iType;
+ TThreadFunction iFunction;
+ TAny* iPtr;
+ TAny* iSupervisorStack;
+ TInt iSupervisorStackSize;
+ TAny* iUserStack;
+ TInt iUserStackSize;
+ TInt iInitialThreadPriority;
+ TPtrC iName;
+ TInt iTotalSize; // Size including any extras (must be a multiple of 8 bytes)
+ };
+
+struct SStdEpocThreadCreateInfo : public SThreadCreateInfo
+ {
+ RAllocator* iAllocator;
+ TInt iHeapInitialSize;
+ TInt iHeapMaxSize;
+ TInt iPadding; // Make structure size a multiple of 8 bytes
+ };
+
+
+/* \internal
+ *
+ * Uses link-time symbol preemption to capture a call from the application
+ * startup. On return, there is some kind of heap allocator installed on the
+ * thread.
+*/
+TInt UserHeap::SetupThreadHeap(TBool aNotFirst, SStdEpocThreadCreateInfo& aInfo)
+{
+ TInt r = KErrNone;
+
+#ifndef __WINS__
+ // attempt to create the fast allocator through a known export ordinal in qtcore.dll
+ RLibrary qtcore;
+ if (qtcore.Load(_L("qtcore.dll")) == KErrNone)
+ {
+ const int qt_symbian_SetupThreadHeap_eabi_ordinal = 3713;
+ TLibraryFunction libFunc = qtcore.Lookup(qt_symbian_SetupThreadHeap_eabi_ordinal);
+ if (libFunc)
+ {
+ typedef int (*TSetupThreadHeapFunc)(TBool aNotFirst, SStdEpocThreadCreateInfo& aInfo);
+ TSetupThreadHeapFunc p_qt_symbian_SetupThreadHeap = TSetupThreadHeapFunc(libFunc);
+ r = (*p_qt_symbian_SetupThreadHeap)(aNotFirst, aInfo);
+ }
+ qtcore.Close();
+ if (libFunc)
+ return r;
+ }
+#endif
+
+ // no fast allocator support - use default allocator creation
+ if (!aInfo.iAllocator && aInfo.iHeapInitialSize>0)
+ {
+ // new heap required
+ RHeap* pH = NULL;
+ r = UserHeap::CreateThreadHeap(aInfo, pH);
+ }
+ else if (aInfo.iAllocator)
+ {
+ // sharing a heap
+ RAllocator* pA = aInfo.iAllocator;
+ pA->Open();
+ User::SwitchAllocator(pA);
+ r = KErrNone;
+ }
+ return r;
+}
+
+#endif // QT_EXPORTS_NOT_FROZEN