diff options
author | mread <qt-info@nokia.com> | 2010-10-08 14:31:09 (GMT) |
---|---|---|
committer | mread <qt-info@nokia.com> | 2010-10-11 11:37:51 (GMT) |
commit | c27f1586d7c4c56af1f46fa09ad77f03b7736e5d (patch) | |
tree | bf375bd9b206bc07e110b9c104056a96c7a35e2f /src/s60main/newallocator_hook.cpp | |
parent | 3c2296647d2e7ddda4df6679a622b0bf46b34c35 (diff) | |
download | Qt-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.cpp | 87 |
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 |