libraries/ltkutils/src/heaphackery.cpp
changeset 59 c9dfb364c2d1
parent 53 17466b56148d
equal deleted inserted replaced
58:377ac716dabb 59:c9dfb364c2d1
   431 
   431 
   432 TInt RAllocatorHelper::OpenChunkHeap(TLinAddr aChunkBase, TInt aChunkMaxSize)
   432 TInt RAllocatorHelper::OpenChunkHeap(TLinAddr aChunkBase, TInt aChunkMaxSize)
   433 	{
   433 	{
   434 #ifdef __KERNEL_MODE__
   434 #ifdef __KERNEL_MODE__
   435 	// Must be in CS
   435 	// Must be in CS
   436 	// Assumes that this only ever gets called for the kernel heap. Otherwise goes through RKernelSideAllocatorHelper::OpenUserHeap.
   436 	// Assumes that this only ever gets called for the kernel heap. Otherwise goes through RUserAllocatorHelper::OpenUserHeap.
   437 	TInt udeb = EFalse; // We can't figure this out until after we've got the heap
   437 	TInt udeb = EFalse; // We can't figure this out until after we've got the heap
   438 	TBool isTheKernelHeap = ETrue;
   438 	TBool isTheKernelHeap = ETrue;
   439 #else
   439 #else
   440 	// Assumes the chunk isn't the kernel heap. It's not a good idea to try messing with the kernel heap from user side...
   440 	// Assumes the chunk isn't the kernel heap. It's not a good idea to try messing with the kernel heap from user side...
   441 	TInt udeb = EuserIsUdeb();
   441 	TInt udeb = EuserIsUdeb();
   442 	if (udeb < 0) return udeb; // error
   442 	if (udeb < 0) return udeb; // error
   443 	TBool isTheKernelHeap = EFalse;
   443 	TBool isTheKernelHeap = EFalse;
   444 #endif
   444 #endif
   445 
   445 
       
   446 	if (iAllocatorAddress == 0)
       
   447 		{
       
   448 		// Subclasses with more knowledge about the layout of the allocator within the chunk may have already set the iAllocatorAddress (eg kernel heap's allocator doesn't start at the chunk base)
       
   449 		iAllocatorAddress = aChunkBase;
       
   450 		}
       
   451 
   446 	TInt err = IdentifyAllocatorType(udeb, isTheKernelHeap);
   452 	TInt err = IdentifyAllocatorType(udeb, isTheKernelHeap);
   447 	if (err == KErrNone && iAllocatorType == EAllocator)
   453 	if (err == KErrNone && iAllocatorType == EAllocator)
   448 		{
   454 		{
   449 		// We've no reason to assume it's an allocator because we don't know the iAllocatorAddress actually is an RAllocator*
   455 		// We've no reason to assume it's an allocator because we don't know the iAllocatorAddress actually is an RAllocator*
   450 		err = KErrNotFound;
   456 		err = KErrNotFound;
   451 		}
   457 		}
   452 	if (err && aChunkMaxSize > 0)
   458 	if (err && aChunkMaxSize > 0 && iAllocatorAddress == aChunkBase)
   453 		{
   459 		{
   454 		TInt oldErr = err;
   460 		TInt oldErr = err;
   455 		TAllocatorType oldType = iAllocatorType;
   461 		TAllocatorType oldType = iAllocatorType;
   456 		// Try middle of chunk, in case it's an RHybridHeap
   462 		// Try middle of chunk, in case it's an RHybridHeap
   457 		iAllocatorAddress += aChunkMaxSize / 2;
   463 		iAllocatorAddress += aChunkMaxSize / 2;
  1685 	}
  1691 	}
  1686 
  1692 
  1687 DChunk* LtkUtils::RUserAllocatorHelper::OpenUnderlyingChunk()
  1693 DChunk* LtkUtils::RUserAllocatorHelper::OpenUnderlyingChunk()
  1688 	{
  1694 	{
  1689 	if (iAllocatorType != EUrelOldRHeap && iAllocatorType != EUdebOldRHeap && iAllocatorType != EUrelHybridHeap && iAllocatorType != EUdebHybridHeap) return NULL;
  1695 	if (iAllocatorType != EUrelOldRHeap && iAllocatorType != EUdebOldRHeap && iAllocatorType != EUrelHybridHeap && iAllocatorType != EUdebHybridHeap) return NULL;
  1690 	// Note RKernelSideAllocatorHelper doesn't use or access RAllocatorHelper::iChunk, because we figure out the chunk handle in a different way.
  1696 	// Note RUserAllocatorHelper doesn't use or access RAllocatorHelper::iChunk, because we figure out the chunk handle in a different way.
  1691 	// It is for this reason that iChunk is private, to remove temptation
  1697 	// It is for this reason that iChunk is private, to remove temptation
  1692 	
  1698 	
  1693 	// Enter and leave in CS and with no locks held. On exit the returned DChunk has been Open()ed.
  1699 	// Enter and leave in CS and with no locks held. On exit the returned DChunk has been Open()ed.
  1694 	TUint32 chunkHandle = 0;
  1700 	TUint32 chunkHandle = 0;
  1695 	TInt err = ReadData(iAllocatorAddress + _FOFF(RHackHeap, iChunkHandle), &chunkHandle, sizeof(TUint32));
  1701 	TInt err = ReadData(iAllocatorAddress + _FOFF(RHackHeap, iChunkHandle), &chunkHandle, sizeof(TUint32));