OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1368 return reinterpret_cast<FreeListNode*>(maybe); | 1368 return reinterpret_cast<FreeListNode*>(maybe); |
1369 } | 1369 } |
1370 | 1370 |
1371 private: | 1371 private: |
1372 static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize); | 1372 static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize); |
1373 | 1373 |
1374 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListNode); | 1374 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListNode); |
1375 }; | 1375 }; |
1376 | 1376 |
1377 | 1377 |
1378 struct FreeListCategorie { | |
Michael Starzinger
2012/11/27 13:51:53
This should be a proper class with the helper func
Hannes Payer (out of office)
2012/11/29 13:17:42
Done. I refactored the whole free list implementat
| |
1379 FreeListNode* top; | |
1380 FreeListNode* end; | |
1381 }; | |
1382 | |
1383 | |
1378 // The free list for the old space. The free list is organized in such a way | 1384 // The free list for the old space. The free list is organized in such a way |
1379 // as to encourage objects allocated around the same time to be near each | 1385 // as to encourage objects allocated around the same time to be near each |
1380 // other. The normal way to allocate is intended to be by bumping a 'top' | 1386 // other. The normal way to allocate is intended to be by bumping a 'top' |
1381 // pointer until it hits a 'limit' pointer. When the limit is hit we need to | 1387 // pointer until it hits a 'limit' pointer. When the limit is hit we need to |
1382 // find a new space to allocate from. This is done with the free list, which | 1388 // find a new space to allocate from. This is done with the free list, which |
1383 // is divided up into rough categories to cut down on waste. Having finer | 1389 // is divided up into rough categories to cut down on waste. Having finer |
1384 // categories would scatter allocation more. | 1390 // categories would scatter allocation more. |
1385 | 1391 |
1386 // The old space free list is organized in categories. | 1392 // The old space free list is organized in categories. |
1387 // 1-31 words: Such small free areas are discarded for efficiency reasons. | 1393 // 1-31 words: Such small free areas are discarded for efficiency reasons. |
(...skipping 10 matching lines...) Expand all Loading... | |
1398 // These spaces are call large. | 1404 // These spaces are call large. |
1399 // At least 16384 words. This list is for objects of 2048 words or larger. | 1405 // At least 16384 words. This list is for objects of 2048 words or larger. |
1400 // Empty pages are added to this list. These spaces are called huge. | 1406 // Empty pages are added to this list. These spaces are called huge. |
1401 class FreeList BASE_EMBEDDED { | 1407 class FreeList BASE_EMBEDDED { |
1402 public: | 1408 public: |
1403 explicit FreeList(PagedSpace* owner); | 1409 explicit FreeList(PagedSpace* owner); |
1404 | 1410 |
1405 // Clear the free list. | 1411 // Clear the free list. |
1406 void Reset(); | 1412 void Reset(); |
1407 | 1413 |
1414 void Reset(struct FreeListCategorie *categorie); | |
Michael Starzinger
2012/11/27 13:51:53
Move all of these helper functions into FreeListCa
Hannes Payer (out of office)
2012/11/29 13:17:42
Done.
| |
1415 | |
1416 // ConcurrentGetList is just safe to call when there is just one producer | |
1417 // thread which only adds elements to the free list. ABA problem can be | |
1418 // ignored in the given setup. | |
1419 void ConcurrentGetList(struct FreeListCategorie *categorie, | |
1420 FreeListNode** top, | |
1421 FreeListNode** end); | |
1422 | |
1423 void ConcurrentAddList(struct FreeListCategorie *categorie, | |
1424 FreeListNode* top, | |
1425 FreeListNode* end); | |
1426 | |
1427 void GetList(struct FreeListCategorie *categorie, | |
1428 FreeListNode** top, | |
1429 FreeListNode** end); | |
1430 | |
1431 void AddList(struct FreeListCategorie *categorie, | |
1432 FreeListNode* top, | |
1433 FreeListNode* end); | |
1434 | |
1408 // Return the number of bytes available on the free list. | 1435 // Return the number of bytes available on the free list. |
1409 intptr_t available() { return available_; } | 1436 intptr_t available() { return available_; } |
1410 | 1437 |
1411 // Place a node on the free list. The block of size 'size_in_bytes' | 1438 // Place a node on the free list. The block of size 'size_in_bytes' |
1412 // starting at 'start' is placed on the free list. The return value is the | 1439 // starting at 'start' is placed on the free list. The return value is the |
1413 // number of bytes that have been lost due to internal fragmentation by | 1440 // number of bytes that have been lost due to internal fragmentation by |
1414 // freeing the block. Bookkeeping information will be written to the block, | 1441 // freeing the block. Bookkeeping information will be written to the block, |
1415 // i.e., its contents will be destroyed. The start address should be word | 1442 // i.e., its contents will be destroyed. The start address should be word |
1416 // aligned, and the size should be a non-zero multiple of the word size. | 1443 // aligned, and the size should be a non-zero multiple of the word size. |
1417 int Free(Address start, int size_in_bytes); | 1444 int Free(Address start, int size_in_bytes); |
1418 | 1445 |
1419 // Allocate a block of size 'size_in_bytes' from the free list. The block | 1446 // Allocate a block of size 'size_in_bytes' from the free list. The block |
1420 // is unitialized. A failure is returned if no block is available. The | 1447 // is unitialized. A failure is returned if no block is available. The |
1421 // number of bytes lost to fragmentation is returned in the output parameter | 1448 // number of bytes lost to fragmentation is returned in the output parameter |
1422 // 'wasted_bytes'. The size should be a non-zero multiple of the word size. | 1449 // 'wasted_bytes'. The size should be a non-zero multiple of the word size. |
1423 MUST_USE_RESULT HeapObject* Allocate(int size_in_bytes); | 1450 MUST_USE_RESULT HeapObject* Allocate(int size_in_bytes); |
1424 | 1451 |
1425 #ifdef DEBUG | 1452 #ifdef DEBUG |
1426 void Zap(); | 1453 void Zap(); |
1427 static intptr_t SumFreeList(FreeListNode* node); | 1454 static intptr_t SumFreeList(FreeListCategorie* categorie); |
1428 static int FreeListLength(FreeListNode* cur); | 1455 static int FreeListLength(FreeListCategorie* categorie); |
1429 intptr_t SumFreeLists(); | 1456 intptr_t SumFreeLists(); |
1430 bool IsVeryLong(); | 1457 bool IsVeryLong(); |
1431 #endif | 1458 #endif |
1432 | 1459 |
1433 // Used after booting the VM. | 1460 // Used after booting the VM. |
1434 void RepairLists(Heap* heap); | 1461 void RepairLists(Heap* heap); |
1435 | 1462 |
1436 struct SizeStats { | 1463 struct SizeStats { |
1437 intptr_t Total() { | 1464 intptr_t Total() { |
1438 return small_size_ + medium_size_ + large_size_ + huge_size_; | 1465 return small_size_ + medium_size_ + large_size_ + huge_size_; |
1439 } | 1466 } |
1440 | 1467 |
1441 intptr_t small_size_; | 1468 intptr_t small_size_; |
1442 intptr_t medium_size_; | 1469 intptr_t medium_size_; |
1443 intptr_t large_size_; | 1470 intptr_t large_size_; |
1444 intptr_t huge_size_; | 1471 intptr_t huge_size_; |
1445 }; | 1472 }; |
1446 | 1473 |
1447 void CountFreeListItems(Page* p, SizeStats* sizes); | 1474 void CountFreeListItems(Page* p, SizeStats* sizes); |
1448 | 1475 |
1449 intptr_t EvictFreeListItems(Page* p); | 1476 intptr_t EvictFreeListItems(Page* p); |
1450 | 1477 |
1451 private: | 1478 private: |
1452 // The size range of blocks, in bytes. | 1479 // The size range of blocks, in bytes. |
1453 static const int kMinBlockSize = 3 * kPointerSize; | 1480 static const int kMinBlockSize = 3 * kPointerSize; |
1454 static const int kMaxBlockSize = Page::kMaxNonCodeHeapObjectSize; | 1481 static const int kMaxBlockSize = Page::kMaxNonCodeHeapObjectSize; |
1455 | 1482 |
1456 FreeListNode* PickNodeFromList(FreeListNode** list, int* node_size); | 1483 FreeListNode* PickNodeFromList(FreeListCategorie* categorie, |
1484 int* node_size); | |
1457 | 1485 |
1458 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); | 1486 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); |
1459 | 1487 |
1460 PagedSpace* owner_; | 1488 PagedSpace* owner_; |
1461 Heap* heap_; | 1489 Heap* heap_; |
1462 | 1490 |
1463 // Total available bytes in all blocks on this free list. | 1491 // Total available bytes in all blocks on this free list. |
1464 int available_; | 1492 int available_; |
1465 | 1493 |
1466 static const int kSmallListMin = 0x20 * kPointerSize; | 1494 static const int kSmallListMin = 0x20 * kPointerSize; |
1467 static const int kSmallListMax = 0xff * kPointerSize; | 1495 static const int kSmallListMax = 0xff * kPointerSize; |
1468 static const int kMediumListMax = 0x7ff * kPointerSize; | 1496 static const int kMediumListMax = 0x7ff * kPointerSize; |
1469 static const int kLargeListMax = 0x3fff * kPointerSize; | 1497 static const int kLargeListMax = 0x3fff * kPointerSize; |
1470 static const int kSmallAllocationMax = kSmallListMin - kPointerSize; | 1498 static const int kSmallAllocationMax = kSmallListMin - kPointerSize; |
1471 static const int kMediumAllocationMax = kSmallListMax; | 1499 static const int kMediumAllocationMax = kSmallListMax; |
1472 static const int kLargeAllocationMax = kMediumListMax; | 1500 static const int kLargeAllocationMax = kMediumListMax; |
1473 FreeListNode* small_list_; | 1501 struct FreeListCategorie small_list_; |
1474 FreeListNode* medium_list_; | 1502 struct FreeListCategorie medium_list_; |
1475 FreeListNode* large_list_; | 1503 struct FreeListCategorie large_list_; |
1476 FreeListNode* huge_list_; | 1504 struct FreeListCategorie huge_list_; |
1477 | 1505 |
1478 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeList); | 1506 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeList); |
1479 }; | 1507 }; |
1480 | 1508 |
1481 | 1509 |
1482 class PagedSpace : public Space { | 1510 class PagedSpace : public Space { |
1483 public: | 1511 public: |
1484 // Creates a space with a maximum capacity, and an id. | 1512 // Creates a space with a maximum capacity, and an id. |
1485 PagedSpace(Heap* heap, | 1513 PagedSpace(Heap* heap, |
1486 intptr_t max_capacity, | 1514 intptr_t max_capacity, |
(...skipping 1235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2722 } | 2750 } |
2723 // Must be small, since an iteration is used for lookup. | 2751 // Must be small, since an iteration is used for lookup. |
2724 static const int kMaxComments = 64; | 2752 static const int kMaxComments = 64; |
2725 }; | 2753 }; |
2726 #endif | 2754 #endif |
2727 | 2755 |
2728 | 2756 |
2729 } } // namespace v8::internal | 2757 } } // namespace v8::internal |
2730 | 2758 |
2731 #endif // V8_SPACES_H_ | 2759 #endif // V8_SPACES_H_ |
OLD | NEW |