Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: src/spaces.h

Issue 11348174: Prepare FreeList for parallel and concurrent sweeping. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/spaces.cc » ('j') | src/spaces.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1363 matching lines...) Expand 10 before | Expand all | Expand 10 after
1374 return reinterpret_cast<FreeListNode*>(maybe); 1374 return reinterpret_cast<FreeListNode*>(maybe);
1375 } 1375 }
1376 1376
1377 private: 1377 private:
1378 static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize); 1378 static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize);
1379 1379
1380 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListNode); 1380 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListNode);
1381 }; 1381 };
1382 1382
1383 1383
1384 // The free list category holds a pointer to the top element and a pointer to
1385 // the end element of the linked list of free memory blocks.
1386 class FreeListCategory {
1387 public:
1388 FreeListCategory() : top_(NULL), end_(NULL), available_(0) {}
1389
1390 // ConcatenateListsConcurrentAdd adds the category list to this list.
1391 // The add operation on the target list is non-blocking using atomic
1392 // operations. The resetting operation on the source list is done without
1393 // synchronization. ConcatenateListsConcurrentAdd is just safe to call
1394 // when there is just one producer thread which only adds elements to
1395 // the target list and one consumer thread which only removes elements
1396 // from the target list. The ABA problem can be ignored in the given setup.
1397 void ConcatenateListsConcurrentAdd(FreeListCategory* category);
1398
1399 // ConcatenateListsConcurrentRemove adds the category list to this list.
1400 // The add operation on the target list is done without synchronization.
1401 // The resetting operation on the source list is non-blocking using atomic
1402 // operations. ConcatenateListsConcurrentRemove is just safe to call
1403 // when there is just one consumer thread which only removes elements from
1404 // the source list and one producer thread which only adds elements to the
1405 // source list. The ABA problem can be ignored in the given setup.
1406 void ConcatenateListsConcurrentRemove(FreeListCategory* category);
1407
1408 void Reset();
1409
1410 void Free(FreeListNode* node, int size_in_bytes);
1411
1412 FreeListNode* PickNodeFromList(int *node_size);
1413
1414 intptr_t CountFreeListItemsInList(Page* p);
1415
1416 intptr_t EvictFreeListItemsInList(Page* p);
1417
1418 void RepairFreeList(Heap* heap);
1419
1420 FreeListNode** GetTopAddress() {
1421 return &top_;
1422 }
1423
1424 FreeListNode** GetEndAddress() {
1425 return &end_;
1426 }
1427
1428 FreeListNode* top() const {
Michael Starzinger 2012/11/29 14:31:20 Let's compact the simple accessors a little by usi
Hannes Payer (out of office) 2012/11/29 15:55:02 Done.
1429 return top_;
1430 }
1431
1432 void set_top(FreeListNode* top) {
1433 top_ = top;
1434 }
1435
1436 FreeListNode* end() const {
1437 return end_;
1438 }
1439
1440 void set_end(FreeListNode* end) {
1441 end_ = end;
1442 }
1443
1444 int available() const {
1445 return available_;
1446 }
1447
1448 void set_available(int available) {
1449 available_ = available;
1450 }
1451
1452 int* GetAvailableAddress() {
1453 return &available_;
1454 }
1455
1456 #ifdef DEBUG
1457 intptr_t SumFreeList();
1458 int FreeListLength();
1459 #endif
1460
1461 private:
1462 FreeListNode* top_;
1463 FreeListNode* end_;
1464
1465 // Total available bytes in all blocks of this free list category.
1466 int available_;
1467 };
1468
1469
1384 // The free list for the old space. The free list is organized in such a way 1470 // The free list for the old space. The free list is organized in such a way
1385 // as to encourage objects allocated around the same time to be near each 1471 // as to encourage objects allocated around the same time to be near each
1386 // other. The normal way to allocate is intended to be by bumping a 'top' 1472 // other. The normal way to allocate is intended to be by bumping a 'top'
1387 // pointer until it hits a 'limit' pointer. When the limit is hit we need to 1473 // pointer until it hits a 'limit' pointer. When the limit is hit we need to
1388 // find a new space to allocate from. This is done with the free list, which 1474 // find a new space to allocate from. This is done with the free list, which
1389 // is divided up into rough categories to cut down on waste. Having finer 1475 // is divided up into rough categories to cut down on waste. Having finer
1390 // categories would scatter allocation more. 1476 // categories would scatter allocation more.
1391 1477
1392 // The old space free list is organized in categories. 1478 // The old space free list is organized in categories.
1393 // 1-31 words: Such small free areas are discarded for efficiency reasons. 1479 // 1-31 words: Such small free areas are discarded for efficiency reasons.
(...skipping 11 matching lines...) Expand all
1405 // At least 16384 words. This list is for objects of 2048 words or larger. 1491 // At least 16384 words. This list is for objects of 2048 words or larger.
1406 // Empty pages are added to this list. These spaces are called huge. 1492 // Empty pages are added to this list. These spaces are called huge.
1407 class FreeList BASE_EMBEDDED { 1493 class FreeList BASE_EMBEDDED {
1408 public: 1494 public:
1409 explicit FreeList(PagedSpace* owner); 1495 explicit FreeList(PagedSpace* owner);
1410 1496
1411 // Clear the free list. 1497 // Clear the free list.
1412 void Reset(); 1498 void Reset();
1413 1499
1414 // Return the number of bytes available on the free list. 1500 // Return the number of bytes available on the free list.
1415 intptr_t available() { return available_; } 1501 intptr_t available() {
1502 return small_list_.available() + medium_list_.available() +
1503 large_list_.available() + huge_list_.available();
1504 }
1416 1505
1417 // Place a node on the free list. The block of size 'size_in_bytes' 1506 // Place a node on the free list. The block of size 'size_in_bytes'
1418 // starting at 'start' is placed on the free list. The return value is the 1507 // starting at 'start' is placed on the free list. The return value is the
1419 // number of bytes that have been lost due to internal fragmentation by 1508 // number of bytes that have been lost due to internal fragmentation by
1420 // freeing the block. Bookkeeping information will be written to the block, 1509 // freeing the block. Bookkeeping information will be written to the block,
1421 // i.e., its contents will be destroyed. The start address should be word 1510 // i.e., its contents will be destroyed. The start address should be word
1422 // aligned, and the size should be a non-zero multiple of the word size. 1511 // aligned, and the size should be a non-zero multiple of the word size.
1423 int Free(Address start, int size_in_bytes); 1512 int Free(Address start, int size_in_bytes);
1424 1513
1425 // Allocate a block of size 'size_in_bytes' from the free list. The block 1514 // Allocate a block of size 'size_in_bytes' from the free list. The block
1426 // is unitialized. A failure is returned if no block is available. The 1515 // is unitialized. A failure is returned if no block is available. The
1427 // number of bytes lost to fragmentation is returned in the output parameter 1516 // number of bytes lost to fragmentation is returned in the output parameter
1428 // 'wasted_bytes'. The size should be a non-zero multiple of the word size. 1517 // 'wasted_bytes'. The size should be a non-zero multiple of the word size.
1429 MUST_USE_RESULT HeapObject* Allocate(int size_in_bytes); 1518 MUST_USE_RESULT HeapObject* Allocate(int size_in_bytes);
1430 1519
1431 #ifdef DEBUG 1520 #ifdef DEBUG
1432 void Zap(); 1521 void Zap();
1433 static intptr_t SumFreeList(FreeListNode* node);
1434 static int FreeListLength(FreeListNode* cur);
1435 intptr_t SumFreeLists(); 1522 intptr_t SumFreeLists();
1436 bool IsVeryLong(); 1523 bool IsVeryLong();
1437 #endif 1524 #endif
1438 1525
1439 // Used after booting the VM. 1526 // Used after booting the VM.
1440 void RepairLists(Heap* heap); 1527 void RepairLists(Heap* heap);
1441 1528
1442 struct SizeStats { 1529 struct SizeStats {
1443 intptr_t Total() { 1530 intptr_t Total() {
1444 return small_size_ + medium_size_ + large_size_ + huge_size_; 1531 return small_size_ + medium_size_ + large_size_ + huge_size_;
1445 } 1532 }
1446 1533
1447 intptr_t small_size_; 1534 intptr_t small_size_;
1448 intptr_t medium_size_; 1535 intptr_t medium_size_;
1449 intptr_t large_size_; 1536 intptr_t large_size_;
1450 intptr_t huge_size_; 1537 intptr_t huge_size_;
1451 }; 1538 };
1452 1539
1453 void CountFreeListItems(Page* p, SizeStats* sizes); 1540 void CountFreeListItems(Page* p, SizeStats* sizes);
1454 1541
1455 intptr_t EvictFreeListItems(Page* p); 1542 intptr_t EvictFreeListItems(Page* p);
1456 1543
1457 private: 1544 private:
1458 // The size range of blocks, in bytes. 1545 // The size range of blocks, in bytes.
1459 static const int kMinBlockSize = 3 * kPointerSize; 1546 static const int kMinBlockSize = 3 * kPointerSize;
1460 static const int kMaxBlockSize = Page::kMaxNonCodeHeapObjectSize; 1547 static const int kMaxBlockSize = Page::kMaxNonCodeHeapObjectSize;
1461 1548
1462 FreeListNode* PickNodeFromList(FreeListNode** list, int* node_size);
1463
1464 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); 1549 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size);
1465 1550
1466 PagedSpace* owner_; 1551 PagedSpace* owner_;
1467 Heap* heap_; 1552 Heap* heap_;
1468 1553
1469 // Total available bytes in all blocks on this free list.
1470 int available_;
1471
1472 static const int kSmallListMin = 0x20 * kPointerSize; 1554 static const int kSmallListMin = 0x20 * kPointerSize;
1473 static const int kSmallListMax = 0xff * kPointerSize; 1555 static const int kSmallListMax = 0xff * kPointerSize;
1474 static const int kMediumListMax = 0x7ff * kPointerSize; 1556 static const int kMediumListMax = 0x7ff * kPointerSize;
1475 static const int kLargeListMax = 0x3fff * kPointerSize; 1557 static const int kLargeListMax = 0x3fff * kPointerSize;
1476 static const int kSmallAllocationMax = kSmallListMin - kPointerSize; 1558 static const int kSmallAllocationMax = kSmallListMin - kPointerSize;
1477 static const int kMediumAllocationMax = kSmallListMax; 1559 static const int kMediumAllocationMax = kSmallListMax;
1478 static const int kLargeAllocationMax = kMediumListMax; 1560 static const int kLargeAllocationMax = kMediumListMax;
1479 FreeListNode* small_list_; 1561 FreeListCategory small_list_;
1480 FreeListNode* medium_list_; 1562 FreeListCategory medium_list_;
1481 FreeListNode* large_list_; 1563 FreeListCategory large_list_;
1482 FreeListNode* huge_list_; 1564 FreeListCategory huge_list_;
1483 1565
1484 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeList); 1566 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeList);
1485 }; 1567 };
1486 1568
1487 1569
1488 class PagedSpace : public Space { 1570 class PagedSpace : public Space {
1489 public: 1571 public:
1490 // Creates a space with a maximum capacity, and an id. 1572 // Creates a space with a maximum capacity, and an id.
1491 PagedSpace(Heap* heap, 1573 PagedSpace(Heap* heap,
1492 intptr_t max_capacity, 1574 intptr_t max_capacity,
(...skipping 1235 matching lines...) Expand 10 before | Expand all | Expand 10 after
2728 } 2810 }
2729 // Must be small, since an iteration is used for lookup. 2811 // Must be small, since an iteration is used for lookup.
2730 static const int kMaxComments = 64; 2812 static const int kMaxComments = 64;
2731 }; 2813 };
2732 #endif 2814 #endif
2733 2815
2734 2816
2735 } } // namespace v8::internal 2817 } } // namespace v8::internal
2736 2818
2737 #endif // V8_SPACES_H_ 2819 #endif // V8_SPACES_H_
OLDNEW
« no previous file with comments | « no previous file | src/spaces.cc » ('j') | src/spaces.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698