webengine/osswebengine/MemoryManager/Src/heap.cpp
branchRCL_3
changeset 48 79859ed3eea9
parent 46 30342f40acbf
child 49 919f36ff910f
equal deleted inserted replaced
47:e1bea15f9a39 48:79859ed3eea9
    15 *
    15 *
    16 *
    16 *
    17 */
    17 */
    18 
    18 
    19 #include "common.h"
    19 #include "common.h"
    20 #include "StopScheduler.h"
       
    21 #include <hal.h>
       
    22 
    20 
    23 #ifdef TRACE_CHUNK_USAGE
    21 #ifdef TRACE_CHUNK_USAGE
    24 void TraceChunkUsage(TInt aChunkHandle, TUint8* aBase, TInt aChunkSize)
    22 void TraceChunkUsage(TInt aChunkHandle, TUint8* aBase, TInt aChunkSize)
    25 	{
    23 	{
    26 	RDebug::Print(_L("MEM: c,%d,%d,%d"), aChunkHandle, aBase, aChunkSize);
    24 	RDebug::Print(_L("MEM: c,%d,%d,%d"), aChunkHandle, aBase, aChunkSize);
    30 #endif
    28 #endif
    31 
    29 
    32 #ifdef __NEW_ALLOCATOR__
    30 #ifdef __NEW_ALLOCATOR__
    33 
    31 
    34 #include "MemoryLogger.h"
    32 #include "MemoryLogger.h"
    35 #include "SymbianDLHeap.h"
    33 #include "SymbianDlHeap.h"
    36 
    34 
    37 _LIT(KDLHeapPanicCategory, "DL Heap");
    35 _LIT(KDLHeapPanicCategory, "DL Heap");
    38 #define	GET_PAGE_SIZE(x)			UserHal::PageSizeInBytes(x)
    36 #define	GET_PAGE_SIZE(x)			UserHal::PageSizeInBytes(x)
    39 #define	__CHECK_CELL(p)
    37 #define	__CHECK_CELL(p)
    40 #define __POWER_OF_2(x)				((TUint32)((x)^((x)-1))>=(TUint32)(x))
    38 #define __POWER_OF_2(x)				((TUint32)((x)^((x)-1))>=(TUint32)(x))
   263 		{
   261 		{
   264 		iAlign = 4;
   262 		iAlign = 4;
   265 		}
   263 		}
   266 	iPageSize = 0;
   264 	iPageSize = 0;
   267 	iFlags = aSingleThread ? (ESingleThreaded|EFixedSize) : EFixedSize;
   265 	iFlags = aSingleThread ? (ESingleThreaded|EFixedSize) : EFixedSize;
   268 	isLowSystemMemory = 0;
       
   269 
   266 
   270 	Init(0, 0, 0);
   267 	Init(0, 0, 0);
   271 	}
   268 	}
   272 
   269 
   273 UEXPORT_C RSymbianDLHeap::RSymbianDLHeap(TInt aChunkHandle, TInt aOffset, TInt aMinLength, TInt aMaxLength, TInt aGrowBy,
   270 UEXPORT_C RSymbianDLHeap::RSymbianDLHeap(TInt aChunkHandle, TInt aOffset, TInt aMinLength, TInt aMaxLength, TInt aGrowBy,
   274 			TInt aAlign, TBool aSingleThread)
   271 			TInt aAlign, TBool aSingleThread)
   275 		: iMinLength(aMinLength), iMaxLength(aMaxLength), iOffset(aOffset), iChunkHandle(aChunkHandle), 
   272 		: iMinLength(aMinLength), iMaxLength(aMaxLength), iOffset(aOffset), iChunkHandle(aChunkHandle), iNestingLevel(0), iAllocCount(0),
   276 		  iAlign(aAlign), iNestingLevel(0), iAllocCount(0), iFailType(ENone), iTestData(NULL), iChunkSize(aMinLength)
   273 			iAlign(aAlign),iFailType(ENone), iTestData(NULL), iChunkSize(aMinLength)
   277 	{
   274 	{
   278 	// TODO: Locked the page size to 4 KB - change this to pick up from the OS
   275 	// TODO: Locked the page size to 4 KB - change this to pick up from the OS
   279 	GET_PAGE_SIZE(iPageSize);
   276 	GET_PAGE_SIZE(iPageSize);
   280 	__ASSERT_ALWAYS(aOffset >=0, User::Panic(KDLHeapPanicCategory, ETHeapNewBadOffset));
   277 	__ASSERT_ALWAYS(aOffset >=0, User::Panic(KDLHeapPanicCategory, ETHeapNewBadOffset));
   281 	iGrowBy = _ALIGN_UP(aGrowBy, iPageSize);
   278 	iGrowBy = _ALIGN_UP(aGrowBy, iPageSize);
   282 	iFlags = aSingleThread ? ESingleThreaded : 0;
   279 	iFlags = aSingleThread ? ESingleThreaded : 0;
   283 	isLowSystemMemory = 0;
       
   284 
   280 
   285 	// Initialise
   281 	// Initialise
   286 	// if the heap is created with aMinLength==aMaxLength then it cannot allocate slab or page memory
   282 	// if the heap is created with aMinLength==aMaxLength then it cannot allocate slab or page memory
   287 	// so these sub-allocators should be disabled. Otherwise initialise with default values
   283 	// so these sub-allocators should be disabled. Otherwise initialise with default values
   288 	if (aMinLength == aMaxLength)
   284 	if (aMinLength == aMaxLength)
   659           insert_chunk(m, r, rsize, npages_out);
   655           insert_chunk(m, r, rsize, npages_out);
   660         }
   656         }
   661         return chunk2mem(v);
   657         return chunk2mem(v);
   662       }
   658       }
   663     }
   659     }
   664     //CORRUPTION_ERROR_ACTION(m);
   660     CORRUPTION_ERROR_ACTION(m);
   665   }
   661   }
   666   return 0;
   662   return 0;
   667 }
   663 }
   668 
   664 
   669 /* allocate a small request from the best fitting chunk in a treebin */
   665 /* allocate a small request from the best fitting chunk in a treebin */
   705         insert_chunk(m, r, rsize, 0);      
   701         insert_chunk(m, r, rsize, 0);      
   706       }
   702       }
   707       return chunk2mem(v);
   703       return chunk2mem(v);
   708     }
   704     }
   709   }
   705   }
   710   //CORRUPTION_ERROR_ACTION(m);
   706   CORRUPTION_ERROR_ACTION(m);
   711   //return 0;
   707   return 0;
   712 }
   708 }
   713 
   709 
   714 inline void RSymbianDLHeap::init_top(mstate m, mchunkptr p, size_t psize)
   710 inline void RSymbianDLHeap::init_top(mstate m, mchunkptr p, size_t psize)
   715 {
   711 {
   716 	/* Ensure alignment */
   712 	/* Ensure alignment */
   797         internal_free(m, oldmem);
   793         internal_free(m, oldmem);
   798       }
   794       }
   799       return newmem;
   795       return newmem;
   800     }
   796     }
   801   }
   797   }
   802   //return 0;
   798   return 0;
   803 }
   799 }
   804 /* ----------------------------- statistics ------------------------------ */
   800 /* ----------------------------- statistics ------------------------------ */
   805 mallinfo RSymbianDLHeap::internal_mallinfo(mstate m) {
   801 mallinfo RSymbianDLHeap::internal_mallinfo(mstate m) {
   806   struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   802   struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   807   TInt chunkCnt = 0;
   803   TInt chunkCnt = 0;
   810     if (is_initialized(m)) {
   806     if (is_initialized(m)) {
   811       size_t nfree = SIZE_T_ONE; /* top always free */
   807       size_t nfree = SIZE_T_ONE; /* top always free */
   812       size_t mfree = m->topsize + TOP_FOOT_SIZE;
   808       size_t mfree = m->topsize + TOP_FOOT_SIZE;
   813       size_t sum = mfree;
   809       size_t sum = mfree;
   814       msegmentptr s = &m->seg;
   810       msegmentptr s = &m->seg;
   815     //  TInt tmp = (TUint8*)m->top - (TUint8*)s->base;
   811       TInt tmp = (TUint8*)m->top - (TUint8*)s->base;
   816       while (s != 0) {
   812       while (s != 0) {
   817         mchunkptr q = align_as_chunk(s->base);
   813         mchunkptr q = align_as_chunk(s->base);
   818         chunkCnt++;
   814         chunkCnt++;
   819         while (segment_holds(s, q) &&
   815         while (segment_holds(s, q) &&
   820                q != m->top && q->head != FENCEPOST_HEAD) {
   816                q != m->top && q->head != FENCEPOST_HEAD) {
   842   return nm;
   838   return nm;
   843 }
   839 }
   844 
   840 
   845 void  RSymbianDLHeap::internal_malloc_stats(mstate m) {
   841 void  RSymbianDLHeap::internal_malloc_stats(mstate m) {
   846 if (!PREACTION(m)) {
   842 if (!PREACTION(m)) {
       
   843   size_t maxfp = 0;
   847   size_t fp = 0;
   844   size_t fp = 0;
   848   size_t used = 0;
   845   size_t used = 0;
   849   check_malloc_state(m);
   846   check_malloc_state(m);
   850   if (is_initialized(m)) {
   847   if (is_initialized(m)) {
   851     msegmentptr s = &m->seg;
   848     msegmentptr s = &m->seg;
       
   849     maxfp = m->max_footprint;
   852     fp = m->footprint;
   850     fp = m->footprint;
   853     used = fp - (m->topsize + TOP_FOOT_SIZE);
   851     used = fp - (m->topsize + TOP_FOOT_SIZE);
   854 
   852 
   855     while (s != 0) {
   853     while (s != 0) {
   856       mchunkptr q = align_as_chunk(s->base);
   854       mchunkptr q = align_as_chunk(s->base);
  1738 #endif   
  1736 #endif   
  1739 
  1737 
  1740     return mem;
  1738     return mem;
  1741   }
  1739   }
  1742 
  1740 
  1743   //return 0;
  1741   return 0;
  1744 }
  1742 }
  1745 
  1743 
  1746 void RSymbianDLHeap::dlfree(void* mem) {
  1744 void RSymbianDLHeap::dlfree(void* mem) {
  1747   /*
  1745   /*
  1748      Consolidate freed chunks with preceeding or succeeding bordering
  1746      Consolidate freed chunks with preceeding or succeeding bordering
  1827 							}							    							    
  1825 							}							    							    
  1828 						}
  1826 						}
  1829 						else
  1827 						else
  1830 						{
  1828 						{
  1831                             size_t nsize = chunksize(next);
  1829                             size_t nsize = chunksize(next);
  1832                             //int next_chunk_unmapped = 0;
  1830                             int next_chunk_unmapped = 0;
  1833                             if( page_not_in_memory(next, nsize) ) {
  1831                             if( page_not_in_memory(next, nsize) ) {
  1834                                // next_chunk_unmapped = 1;
  1832                                 next_chunk_unmapped = 1;
  1835                                 unmapped_pages += ((tchunkptr)next)->npages;
  1833                                 unmapped_pages += ((tchunkptr)next)->npages;
  1836                             }
  1834                             }
  1837                             
  1835                             
  1838 							psize += nsize;
  1836 							psize += nsize;
  1839 							unlink_chunk(fm, next, nsize);
  1837 							unlink_chunk(fm, next, nsize);
  2298 // allocate pages in the chunk
  2296 // allocate pages in the chunk
  2299 // if p is NULL, find an allocate the required number of pages (which must lie in the lower half)
  2297 // if p is NULL, find an allocate the required number of pages (which must lie in the lower half)
  2300 // otherwise commit the pages specified
  2298 // otherwise commit the pages specified
  2301 //
  2299 //
  2302 {
  2300 {
  2303     // Check for min threshold in system RAM to be left free
  2301 ASSERT(p == floor(p, pagesize));
  2304     TInt sysFreeRAM = 0;
  2302 ASSERT(sz == ceiling(sz, pagesize));
  2305     if(HAL::Get(HALData::EMemoryRAMFree, sysFreeRAM) == KErrNone)
  2303 ASSERT(sz > 0);
  2306 		{
       
  2307 		if(sysFreeRAM < KStopThreshold) // 1MB
       
  2308         	return 0;
       
  2309 	
       
  2310 	    // check system memory level
       
  2311     	if(sysFreeRAM < KGoodMemoryThreshold)
       
  2312         	isLowSystemMemory = 1; 
       
  2313 	    else
       
  2314     	    isLowSystemMemory = 0;
       
  2315 		}
       
  2316 
       
  2317     
       
  2318     ASSERT(p == floor(p, pagesize));
       
  2319     ASSERT(sz == ceiling(sz, pagesize));
       
  2320     ASSERT(sz > 0);
       
  2321 
  2304 
  2322 	if (iChunkSize + sz > iMaxLength)
  2305 	if (iChunkSize + sz > iMaxLength)
  2323 		return 0;
  2306 		return 0;
  2324 
  2307 
  2325 	RChunk chunk;
  2308 	RChunk chunk;
  2359 		{	// grow, try and do this in place first
  2342 		{	// grow, try and do this in place first
  2360 		if (!map(offset(p, oldsz), sz-oldsz))
  2343 		if (!map(offset(p, oldsz), sz-oldsz))
  2361 			{
  2344 			{
  2362 			// need to allocate-copy-free
  2345 			// need to allocate-copy-free
  2363 			void* newp = map(0, sz);
  2346 			void* newp = map(0, sz);
  2364             if(newp)
  2347 			memcpy(newp, p, oldsz);
  2365                 {
  2348 			unmap(p,oldsz);
  2366                 memcpy(newp, p, oldsz);
  2349 			return newp;
  2367                 unmap(p,oldsz);
       
  2368                 return newp;
       
  2369                 }
       
  2370             else
       
  2371                 {
       
  2372                 return 0;
       
  2373                 }
       
  2374 			}
  2350 			}
  2375 		}
  2351 		}
  2376 	return p;
  2352 	return p;
  2377 }
  2353 }
  2378 
  2354