Changeset 2845 in webkit for trunk/JavaScriptCore/kjs/collector.cpp
- Timestamp:
- Nov 23, 2002, 4:04:08 PM (23 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/collector.cpp
r2843 r2845 2 2 /* 3 3 * This file is part of the KDE libraries 4 * Copyright (C) 2002 Apple Computer, Inc .4 * Copyright (C) 2002 Apple Computer, Inc 5 5 * 6 6 * This library is free software; you can redistribute it and/or … … 30 30 #endif 31 31 32 #include <collector.h> 33 #include <value.h> 34 #include <internal.h> 35 32 36 namespace KJS { 33 37 34 38 // tunable parameters 35 static const int CELL_SIZE = 56; 36 static const int BLOCK_SIZE = (4 * 4096); 37 static const int SPARE_EMPTY_BLOCKS = 1; 38 static const int MIN_ARRAY_SIZE = 14; 39 static const int GROWTH_FACTOR = 2; 40 static const int LOW_WATER_FACTOR = 4; 39 const int MINIMUM_CELL_SIZE = 56; 40 const int BLOCK_SIZE = (8 * 4096); 41 const int SPARE_EMPTY_BLOCKS = 2; 42 const int MIN_ARRAY_SIZE = 14; 43 const int GROWTH_FACTOR = 2; 44 const int LOW_WATER_FACTOR = 4; 45 const int ALLOCATIONS_PER_COLLECTION = 1000; 41 46 42 47 // derived constants 43 static const int WORD_SIZE = sizeof(uint32_t); 44 static const int BITS_PER_WORD = WORD_SIZE * 8; 45 static const uint32_t ALL_BITS_ON = 0xffffffff; 46 static const int CELLS_PER_BLOCK = ((BLOCK_SIZE * 8 - 32) / (CELL_SIZE * 8 + 1)); 47 static const int BITMAP_SIZE = (CELLS_PER_BLOCK / BITS_PER_WORD) + (CELLS_PER_BLOCK % BITS_PER_WORD != 0 ? 1 : 0); 48 const int CELL_ARRAY_LENGTH = (MINIMUM_CELL_SIZE / sizeof(double)) + (MINIMUM_CELL_SIZE % sizeof(double) != 0 ? sizeof(double) : 0); 49 const int CELL_SIZE = CELL_ARRAY_LENGTH * sizeof(double); 50 const int CELLS_PER_BLOCK = ((BLOCK_SIZE * 8 - sizeof(int32_t) * 8 - sizeof(void *) * 8) / (CELL_SIZE * 8)); 51 48 52 49 53 50 54 struct CollectorCell { 51 char memory[CELL_SIZE]; 55 union { 56 double memory[CELL_ARRAY_LENGTH]; 57 struct { 58 void *zeroIfFree; 59 CollectorCell *next; 60 } freeCell; 61 } u; 52 62 }; 53 63 54 static const int ALLOCATIONS_PER_COLLECTION = 1000;55 64 56 65 struct CollectorBlock { 57 CollectorBlock() : usedCells(0) { memset(bitmap, 0, BITMAP_SIZE * WORD_SIZE); } 58 59 uint32_t bitmap[BITMAP_SIZE]; 66 CollectorCell cells[CELLS_PER_BLOCK]; 60 67 int32_t usedCells; 61 CollectorCell cells[CELLS_PER_BLOCK];68 CollectorCell *freeList; 62 69 }; 63 70 … … 66 73 int numBlocks; 67 74 int usedBlocks; 75 int firstBlockWithPossibleSpace; 68 76 69 77 CollectorCell **oversizeCells; … … 75 83 }; 76 84 77 static CollectorHeap heap = {NULL, 0, 0, NULL, 0, 0, 0, 0};85 static CollectorHeap heap = {NULL, 0, 0, 0, NULL, 0, 0, 0, 0}; 78 86 79 87 bool Collector::memoryFull = false; 80 81 88 82 89 void* Collector::allocate(size_t s) … … 86 93 87 94 // collect if needed 88 if (++heap.numAllocationsSinceLastCollect >= ALLOCATIONS_PER_COLLECTION) 95 if (++heap.numAllocationsSinceLastCollect >= ALLOCATIONS_PER_COLLECTION) { 89 96 collect(); 97 } 90 98 91 99 if (s > (unsigned)CELL_SIZE) { … … 109 117 CollectorBlock *targetBlock = NULL; 110 118 111 // try to find free space in an existing block112 for (i nt i = 0; i < heap.usedBlocks; i++) {119 int i; 120 for (i = heap.firstBlockWithPossibleSpace; i < heap.usedBlocks; i++) { 113 121 if (heap.blocks[i]->usedCells < CELLS_PER_BLOCK) { 114 122 targetBlock = heap.blocks[i]; … … 116 124 } 117 125 } 126 127 heap.firstBlockWithPossibleSpace = i; 118 128 119 129 if (targetBlock == NULL) { … … 125 135 } 126 136 127 targetBlock = new CollectorBlock(); 137 targetBlock = (CollectorBlock *)calloc(1, sizeof(CollectorBlock)); 138 targetBlock->freeList = targetBlock->cells; 128 139 heap.blocks[heap.usedBlocks] = targetBlock; 129 140 heap.usedBlocks++; 130 141 } 131 142 132 // find a free spot in the block 133 for (int wordInBitmap = 0; wordInBitmap < BITMAP_SIZE; wordInBitmap++) { 134 uint32_t word = targetBlock->bitmap[wordInBitmap]; 135 if (word == ALL_BITS_ON) { 136 continue; 137 } 138 for (int bitInWord = 0; bitInWord < BITS_PER_WORD; bitInWord++) { 139 if ((word & (1 << bitInWord)) == 0) { 140 int cellPos = BITS_PER_WORD * wordInBitmap + bitInWord; 141 if (cellPos < CELLS_PER_BLOCK) { 142 targetBlock->bitmap[wordInBitmap] |= (1 << bitInWord); 143 targetBlock->usedCells++; 144 heap.numLiveObjects++; 145 146 ((ValueImp *)(targetBlock->cells + cellPos))->_flags = 0; 147 return (void *)(targetBlock->cells + cellPos); 148 } 149 } 150 } 151 } 152 // unreachable, if the free count wasn't 0 there has to be a free 153 // cell in the block 154 assert(false); 155 156 return false; 143 // find a free spot in the block and detach it from the free list 144 CollectorCell *newCell = targetBlock->freeList; 145 146 if (newCell->u.freeCell.next != NULL) { 147 targetBlock->freeList = newCell->u.freeCell.next; 148 } else if (targetBlock->usedCells == (CELLS_PER_BLOCK - 1)) { 149 // last cell in this block 150 targetBlock->freeList = NULL; 151 } else { 152 // all next pointers are initially 0, meaning "next cell" 153 targetBlock->freeList = newCell + 1; 154 } 155 156 targetBlock->usedCells++; 157 heap.numLiveObjects++; 158 159 ((ValueImp *)(newCell))->_flags = 0; 160 return (void *)(newCell); 157 161 } 158 162 … … 174 178 // mark any other objects that we wouldn't delete anyway 175 179 for (int block = 0; block < heap.usedBlocks; block++) { 176 for (int wordInBitmap = 0; wordInBitmap < BITMAP_SIZE; wordInBitmap++) { 177 uint32_t word = heap.blocks[block]->bitmap[wordInBitmap]; 178 for (int bitInWord = 0; bitInWord < BITS_PER_WORD; bitInWord++) { 179 ValueImp *imp = (ValueImp *)(heap.blocks[block]->cells + BITS_PER_WORD * wordInBitmap + bitInWord); 180 181 int minimumCellsToProcess = heap.blocks[block]->usedCells; 182 CollectorBlock *curBlock = heap.blocks[block]; 183 184 for (int cell = 0; cell < CELLS_PER_BLOCK; cell++) { 185 if (minimumCellsToProcess < cell) { 186 goto skip_block_mark; 187 } 180 188 181 if ((word & (1 << bitInWord)) && 182 (imp->_flags & (ValueImp::VI_CREATED|ValueImp::VI_MARKED)) == ValueImp::VI_CREATED && 189 ValueImp *imp = (ValueImp *)(curBlock->cells + cell); 190 191 if (((CollectorCell *)imp)->u.freeCell.zeroIfFree != 0) { 192 193 if ((imp->_flags & (ValueImp::VI_CREATED|ValueImp::VI_MARKED)) == ValueImp::VI_CREATED && 183 194 ((imp->_flags & ValueImp::VI_GCALLOWED) == 0 || imp->refcount != 0)) { 184 195 imp->mark(); 185 196 } 186 } 187 } 197 } else { 198 minimumCellsToProcess++; 199 } 200 } 201 skip_block_mark: ; 188 202 } 189 203 … … 201 215 202 216 for (int block = 0; block < heap.usedBlocks; block++) { 203 for (int wordInBitmap = 0; wordInBitmap < BITMAP_SIZE; wordInBitmap++) { 204 uint32_t word = heap.blocks[block]->bitmap[wordInBitmap]; 205 for (int bitInWord = 0; bitInWord < BITS_PER_WORD; bitInWord++) { 206 207 if (word & (1 << bitInWord)) { 208 ValueImp *imp = (ValueImp *)(heap.blocks[block]->cells + BITS_PER_WORD * wordInBitmap + bitInWord); 209 if (!imp->refcount && imp->_flags == (ValueImp::VI_GCALLOWED | ValueImp::VI_CREATED)) { 210 //fprintf( stderr, "Collector::deleting ValueImp %p (%s)\n", (void*)imp, typeid(*imp).name()); 211 // emulate destructing part of 'operator delete()' 212 imp->~ValueImp(); 213 heap.blocks[block]->bitmap[wordInBitmap] &= ~(1 << bitInWord); 214 heap.blocks[block]->usedCells--; 215 heap.numLiveObjects--; 216 deleted = true; 217 } else { 218 imp->_flags &= ~ValueImp::VI_MARKED; 219 } 217 CollectorBlock *curBlock = heap.blocks[block]; 218 219 int minimumCellsToProcess = curBlock->usedCells; 220 221 for (int cell = 0; cell < CELLS_PER_BLOCK; cell++) { 222 if (minimumCellsToProcess < cell) { 223 goto skip_block_sweep; 224 } 225 226 ValueImp *imp = (ValueImp *)(curBlock->cells + cell); 227 228 if (((CollectorCell *)imp)->u.freeCell.zeroIfFree != 0) { 229 if (!imp->refcount && imp->_flags == (ValueImp::VI_GCALLOWED | ValueImp::VI_CREATED)) { 230 //fprintf( stderr, "Collector::deleting ValueImp %p (%s)\n", (void*)imp, typeid(*imp).name()); 231 // emulate destructing part of 'operator delete()' 232 imp->~ValueImp(); 233 curBlock->usedCells--; 234 heap.numLiveObjects--; 235 deleted = true; 236 237 // put it on the free list 238 ((CollectorCell *)imp)->u.freeCell.zeroIfFree = 0; 239 ((CollectorCell *)imp)->u.freeCell.next = curBlock->freeList; 240 curBlock->freeList = (CollectorCell *)imp; 241 242 } else { 243 imp->_flags &= ~ValueImp::VI_MARKED; 220 244 } 221 } 222 } 245 } else { 246 minimumCellsToProcess++; 247 } 248 } 249 250 skip_block_sweep: 223 251 224 252 if (heap.blocks[block]->usedCells == 0) { … … 240 268 } 241 269 270 if (deleted) { 271 heap.firstBlockWithPossibleSpace = 0; 272 } 242 273 243 274 int cell = 0; … … 269 300 } 270 301 271 // possibly free some completely empty collector blocks ?272 // compact array of collector blocks273 274 302 heap.numAllocationsSinceLastCollect = 0; 275 303 … … 309 337 int count = 0; 310 338 for (int block = 0; block < heap.usedBlocks; block++) { 311 for (int wordInBitmap = 0; wordInBitmap < BITMAP_SIZE; wordInBitmap++) { 312 uint32_t word = heap.blocks[block]->bitmap[wordInBitmap]; 313 for (int bitInWord = 0; bitInWord < BITS_PER_WORD; bitInWord++) { 314 ValueImp *imp = (ValueImp *)(heap.blocks[block]->cells + BITS_PER_WORD * wordInBitmap + bitInWord); 315 316 if ((word & (1 << bitInWord)) && 317 (imp->_flags & ValueImp::VI_GCALLOWED) == 0) { 318 ++count; 319 } 339 CollectorBlock *curBlock = heap.blocks[block]; 340 341 for (int cell = 0; cell < CELLS_PER_BLOCK; cell++) { 342 ValueImp *imp = (ValueImp *)(curBlock->cells + cell); 343 344 if (((CollectorCell *)imp)->u.freeCell.zeroIfFree != 0 && 345 (imp->_flags & ValueImp::VI_GCALLOWED) == 0) { 346 ++count; 320 347 } 321 348 } … … 324 351 for (int cell = 0; cell < heap.usedOversizeCells; cell++) { 325 352 ValueImp *imp = (ValueImp *)heap.oversizeCells[cell]; 326 327 328 353 if ((imp->_flags & ValueImp::VI_GCALLOWED) == 0) { 354 ++count; 355 } 329 356 } 330 357 … … 336 363 int count = 0; 337 364 for (int block = 0; block < heap.usedBlocks; block++) { 338 for (int wordInBitmap = 0; wordInBitmap < BITMAP_SIZE; wordInBitmap++) { 339 uint32_t word = heap.blocks[block]->bitmap[wordInBitmap]; 340 for (int bitInWord = 0; bitInWord < BITS_PER_WORD; bitInWord++) { 341 ValueImp *imp = (ValueImp *)(heap.blocks[block]->cells + BITS_PER_WORD * wordInBitmap + bitInWord); 342 343 if ((word & (1 << bitInWord)) && 344 imp->refcount != 0) { 345 ++count; 346 } 365 CollectorBlock *curBlock = heap.blocks[block]; 366 367 for (int cell = 0; cell < CELLS_PER_BLOCK; cell++) { 368 ValueImp *imp = (ValueImp *)(curBlock->cells + cell); 369 370 if (((CollectorCell *)imp)->u.freeCell.zeroIfFree != 0 && 371 imp->refcount != 0) { 372 ++count; 347 373 } 348 374 } … … 362 388 { 363 389 CFMutableSetRef classes = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks); 364 390 365 391 for (int block = 0; block < heap.usedBlocks; block++) { 366 for (int wordInBitmap = 0; wordInBitmap < BITMAP_SIZE; wordInBitmap++) { 367 uint32_t word = heap.blocks[block]->bitmap[wordInBitmap]; 368 for (int bitInWord = 0; bitInWord < BITS_PER_WORD; bitInWord++) { 369 ValueImp *imp = (ValueImp *)(heap.blocks[block]->cells + BITS_PER_WORD * wordInBitmap + bitInWord); 392 CollectorBlock *curBlock = heap.blocks[block]; 393 for (int cell = 0; cell < CELLS_PER_BLOCK; cell++) { 394 ValueImp *imp = (ValueImp *)(curBlock->cells + cell); 395 396 if (((CollectorCell *)imp)->u.freeCell.zeroIfFree != 0 && 397 ((imp->_flags & ValueImp::VI_GCALLOWED) == 0 || imp->refcount != 0)) { 398 const char *mangled_name = typeid(*imp).name(); 399 int status; 400 char *demangled_name = __cxxabiv1::__cxa_demangle (mangled_name, NULL, NULL, &status); 370 401 371 if (word & (1 << bitInWord) 372 && ((imp->_flags & ValueImp::VI_GCALLOWED) == 0 || imp->refcount != 0)) { 373 const char *mangled_name = typeid(*imp).name(); 374 int status; 375 char *demangled_name = __cxxabiv1::__cxa_demangle (mangled_name, NULL, NULL, &status); 376 377 CFStringRef className = CFStringCreateWithCString(NULL, demangled_name, kCFStringEncodingASCII); 378 free(demangled_name); 379 CFSetAddValue(classes, className); 380 CFRelease(className); 381 } 402 CFStringRef className = CFStringCreateWithCString(NULL, demangled_name, kCFStringEncodingASCII); 403 free(demangled_name); 404 CFSetAddValue(classes, className); 405 CFRelease(className); 382 406 } 383 407 } … … 388 412 389 413 if ((imp->_flags & ValueImp::VI_GCALLOWED) == 0 || imp->refcount != 0) { 390 391 392 393 394 395 396 397 398 } 399 } 400 414 const char *mangled_name = typeid(*imp).name(); 415 int status; 416 char *demangled_name = __cxxabiv1::__cxa_demangle (mangled_name, NULL, NULL, &status); 417 418 CFStringRef className = CFStringCreateWithCString(NULL, demangled_name, kCFStringEncodingASCII); 419 free(demangled_name); 420 CFSetAddValue(classes, className); 421 CFRelease(className); 422 } 423 } 424 401 425 return classes; 402 426 }
Note:
See TracChangeset
for help on using the changeset viewer.