| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 } | 83 } |
| 84 | 84 |
| 85 // Blink heap pages are aligned to the Blink heap page size. | 85 // Blink heap pages are aligned to the Blink heap page size. |
| 86 // Therefore, the start of a Blink page can be obtained by | 86 // Therefore, the start of a Blink page can be obtained by |
| 87 // rounding down to the Blink page size. | 87 // rounding down to the Blink page size. |
| 88 inline Address roundToBlinkPageStart(Address address) | 88 inline Address roundToBlinkPageStart(Address address) |
| 89 { | 89 { |
| 90 return reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address) & blin
kPageBaseMask); | 90 return reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address) & blin
kPageBaseMask); |
| 91 } | 91 } |
| 92 | 92 |
| 93 inline Address roundToBlinkPageEnd(Address address) |
| 94 { |
| 95 return reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address - 1) &
blinkPageBaseMask) + blinkPageSize; |
| 96 } |
| 97 |
| 93 // Compute the amount of padding we have to add to a header to make | 98 // Compute the amount of padding we have to add to a header to make |
| 94 // the size of the header plus the padding a multiple of 8 bytes. | 99 // the size of the header plus the padding a multiple of 8 bytes. |
| 95 template<typename Header> | 100 template<typename Header> |
| 96 inline size_t headerPadding() | 101 inline size_t headerPadding() |
| 97 { | 102 { |
| 98 return (allocationGranularity - (sizeof(Header) % allocationGranularity)) %
allocationGranularity; | 103 return (allocationGranularity - (sizeof(Header) % allocationGranularity)) %
allocationGranularity; |
| 99 } | 104 } |
| 100 | 105 |
| 101 // Masks an address down to the enclosing blink page base address. | 106 // Masks an address down to the enclosing blink page base address. |
| 102 inline Address blinkPageAddress(Address address) | 107 inline Address blinkPageAddress(Address address) |
| (...skipping 26 matching lines...) Expand all Loading... |
| 129 public: | 134 public: |
| 130 BaseHeapPage(PageMemory* storage, const GCInfo* gcInfo, ThreadState* state) | 135 BaseHeapPage(PageMemory* storage, const GCInfo* gcInfo, ThreadState* state) |
| 131 : m_storage(storage) | 136 : m_storage(storage) |
| 132 , m_gcInfo(gcInfo) | 137 , m_gcInfo(gcInfo) |
| 133 , m_threadState(state) | 138 , m_threadState(state) |
| 134 , m_padding(0) | 139 , m_padding(0) |
| 135 { | 140 { |
| 136 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this))); | 141 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this))); |
| 137 } | 142 } |
| 138 | 143 |
| 139 // Check if the given address could point to an object in this | 144 // Check if the given address points to an object in this |
| 140 // heap page. If so, find the start of that object and mark it | 145 // heap page. If so, find the start of that object and mark it |
| 141 // using the given Visitor. | 146 // using the given Visitor. Otherwise do nothing. The pointer must |
| 142 // | 147 // be within the same aligned blinkPageSize as the this-pointer. |
| 143 // Returns true if the object was found and marked, returns false | |
| 144 // otherwise. | |
| 145 // | 148 // |
| 146 // This is used during conservative stack scanning to | 149 // This is used during conservative stack scanning to |
| 147 // conservatively mark all objects that could be referenced from | 150 // conservatively mark all objects that could be referenced from |
| 148 // the stack. | 151 // the stack. |
| 149 virtual bool checkAndMarkPointer(Visitor*, Address) = 0; | 152 virtual void checkAndMarkPointer(Visitor*, Address) = 0; |
| 150 | 153 |
| 151 #if ENABLE(GC_TRACING) | 154 #if ENABLE(GC_TRACING) |
| 152 virtual const GCInfo* findGCInfo(Address) = 0; | 155 virtual const GCInfo* findGCInfo(Address) = 0; |
| 153 #endif | 156 #endif |
| 154 | 157 |
| 155 Address address() { return reinterpret_cast<Address>(this); } | 158 Address address() { return reinterpret_cast<Address>(this); } |
| 156 PageMemory* storage() const { return m_storage; } | 159 PageMemory* storage() const { return m_storage; } |
| 157 ThreadState* threadState() const { return m_threadState; } | 160 ThreadState* threadState() const { return m_threadState; } |
| 158 const GCInfo* gcInfo() { return m_gcInfo; } | 161 const GCInfo* gcInfo() { return m_gcInfo; } |
| 162 virtual bool isLargeObject() { return false; } |
| 159 | 163 |
| 160 private: | 164 private: |
| 161 // Accessor to silence unused warnings. | 165 // Accessor to silence unused warnings. |
| 162 void* padding() const { return m_padding; } | 166 void* padding() const { return m_padding; } |
| 163 | 167 |
| 164 PageMemory* m_storage; | 168 PageMemory* m_storage; |
| 165 const GCInfo* m_gcInfo; | 169 const GCInfo* m_gcInfo; |
| 166 ThreadState* m_threadState; | 170 ThreadState* m_threadState; |
| 167 // Free word only needed to ensure proper alignment of the | 171 // Free word only needed to ensure proper alignment of the |
| 168 // HeapPage header. | 172 // HeapPage header. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 180 // | 184 // |
| 181 // | BaseHeapPage | next pointer | FinalizedHeapObjectHeader or HeapObjectHeader
| payload | | 185 // | BaseHeapPage | next pointer | FinalizedHeapObjectHeader or HeapObjectHeader
| payload | |
| 182 template<typename Header> | 186 template<typename Header> |
| 183 class LargeHeapObject : public BaseHeapPage { | 187 class LargeHeapObject : public BaseHeapPage { |
| 184 public: | 188 public: |
| 185 LargeHeapObject(PageMemory* storage, const GCInfo* gcInfo, ThreadState* stat
e) : BaseHeapPage(storage, gcInfo, state) | 189 LargeHeapObject(PageMemory* storage, const GCInfo* gcInfo, ThreadState* stat
e) : BaseHeapPage(storage, gcInfo, state) |
| 186 { | 190 { |
| 187 COMPILE_ASSERT(!(sizeof(LargeHeapObject<Header>) & allocationMask), larg
e_heap_object_header_misaligned); | 191 COMPILE_ASSERT(!(sizeof(LargeHeapObject<Header>) & allocationMask), larg
e_heap_object_header_misaligned); |
| 188 } | 192 } |
| 189 | 193 |
| 190 virtual bool checkAndMarkPointer(Visitor*, Address); | 194 virtual void checkAndMarkPointer(Visitor*, Address) OVERRIDE; |
| 195 virtual bool isLargeObject() OVERRIDE { return true; } |
| 191 | 196 |
| 192 #if ENABLE(GC_TRACING) | 197 #if ENABLE(GC_TRACING) |
| 193 virtual const GCInfo* findGCInfo(Address) | 198 virtual const GCInfo* findGCInfo(Address address) |
| 194 { | 199 { |
| 200 if (!objectContains(address)) |
| 201 return 0; |
| 195 return gcInfo(); | 202 return gcInfo(); |
| 196 } | 203 } |
| 197 #endif | 204 #endif |
| 198 | 205 |
| 199 void link(LargeHeapObject<Header>** previousNext) | 206 void link(LargeHeapObject<Header>** previousNext) |
| 200 { | 207 { |
| 201 m_next = *previousNext; | 208 m_next = *previousNext; |
| 202 *previousNext = this; | 209 *previousNext = this; |
| 203 } | 210 } |
| 204 | 211 |
| 205 void unlink(LargeHeapObject<Header>** previousNext) | 212 void unlink(LargeHeapObject<Header>** previousNext) |
| 206 { | 213 { |
| 207 *previousNext = m_next; | 214 *previousNext = m_next; |
| 208 } | 215 } |
| 209 | 216 |
| 217 // The LargeHeapObject pseudo-page contains one actual object. Determine |
| 218 // whether the pointer is within that object. |
| 219 bool objectContains(Address object) |
| 220 { |
| 221 return (payload() <= object) && (object < address() + size()); |
| 222 } |
| 223 |
| 224 // Returns true for any address that is on one of the pages that this |
| 225 // large object uses. That ensures that we can use a negative result to |
| 226 // populate the negative page cache. |
| 210 bool contains(Address object) | 227 bool contains(Address object) |
| 211 { | 228 { |
| 212 return (address() <= object) && (object <= (address() + size())); | 229 return roundToBlinkPageStart(address()) <= object && object < roundToBli
nkPageEnd(address() + size()); |
| 213 } | 230 } |
| 214 | 231 |
| 215 LargeHeapObject<Header>* next() | 232 LargeHeapObject<Header>* next() |
| 216 { | 233 { |
| 217 return m_next; | 234 return m_next; |
| 218 } | 235 } |
| 219 | 236 |
| 220 size_t size() | 237 size_t size() |
| 221 { | 238 { |
| 222 return heapObjectHeader()->size() + sizeof(LargeHeapObject<Header>) + he
aderPadding<Header>(); | 239 return heapObjectHeader()->size() + sizeof(LargeHeapObject<Header>) + he
aderPadding<Header>(); |
| 223 } | 240 } |
| 224 | 241 |
| 225 Address payload() { return heapObjectHeader()->payload(); } | 242 Address payload() { return heapObjectHeader()->payload(); } |
| 226 size_t payloadSize() { return heapObjectHeader()->payloadSize(); } | 243 size_t payloadSize() { return heapObjectHeader()->payloadSize(); } |
| 227 | 244 |
| 228 Header* heapObjectHeader() | 245 Header* heapObjectHeader() |
| 229 { | 246 { |
| 230 Address headerAddress = address() + sizeof(LargeHeapObject<Header>) + he
aderPadding<Header>(); | 247 Address headerAddress = address() + sizeof(LargeHeapObject<Header>) + he
aderPadding<Header>(); |
| 231 return reinterpret_cast<Header*>(headerAddress); | 248 return reinterpret_cast<Header*>(headerAddress); |
| 232 } | 249 } |
| 233 | 250 |
| 234 bool isMarked(); | 251 bool isMarked(); |
| 235 void unmark(); | 252 void unmark(); |
| 236 void getStats(HeapStats&); | 253 void getStats(HeapStats&); |
| 237 void mark(Visitor*); | 254 void mark(Visitor*); |
| 238 void finalize(); | 255 void finalize(); |
| 239 | 256 |
| 240 private: | 257 private: |
| 241 friend class Heap; | |
| 242 friend class ThreadHeap<Header>; | 258 friend class ThreadHeap<Header>; |
| 243 | 259 |
| 244 LargeHeapObject<Header>* m_next; | 260 LargeHeapObject<Header>* m_next; |
| 245 }; | 261 }; |
| 246 | 262 |
| 247 // The BasicObjectHeader is the minimal object header. It is used when | 263 // The BasicObjectHeader is the minimal object header. It is used when |
| 248 // encountering heap space of size allocationGranularity to mark it as | 264 // encountering heap space of size allocationGranularity to mark it as |
| 249 // as freelist entry. | 265 // as freelist entry. |
| 250 class PLATFORM_EXPORT BasicObjectHeader { | 266 class PLATFORM_EXPORT BasicObjectHeader { |
| 251 public: | 267 public: |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 template<typename Header> | 450 template<typename Header> |
| 435 class HeapPage : public BaseHeapPage { | 451 class HeapPage : public BaseHeapPage { |
| 436 public: | 452 public: |
| 437 HeapPage(PageMemory*, ThreadHeap<Header>*, const GCInfo*); | 453 HeapPage(PageMemory*, ThreadHeap<Header>*, const GCInfo*); |
| 438 | 454 |
| 439 void link(HeapPage**); | 455 void link(HeapPage**); |
| 440 static void unlink(HeapPage*, HeapPage**); | 456 static void unlink(HeapPage*, HeapPage**); |
| 441 | 457 |
| 442 bool isEmpty(); | 458 bool isEmpty(); |
| 443 | 459 |
| 460 // Returns true for the whole blinkPageSize page that the page is on, even |
| 461 // for the header, and the unmapped guard page at the start. That ensures |
| 462 // the result can be used to populate the negative page cache. |
| 444 bool contains(Address addr) | 463 bool contains(Address addr) |
| 445 { | 464 { |
| 446 Address blinkPageStart = roundToBlinkPageStart(address()); | 465 Address blinkPageStart = roundToBlinkPageStart(address()); |
| 447 return blinkPageStart <= addr && (blinkPageStart + blinkPageSize) > addr
; | 466 ASSERT(blinkPageStart = address() - osPageSize()); // Page is at aligned
address plus guard page size. |
| 467 return blinkPageStart <= addr && addr < blinkPageStart + blinkPageSize; |
| 448 } | 468 } |
| 449 | 469 |
| 450 HeapPage* next() { return m_next; } | 470 HeapPage* next() { return m_next; } |
| 451 | 471 |
| 452 Address payload() | 472 Address payload() |
| 453 { | 473 { |
| 454 return address() + sizeof(*this) + headerPadding<Header>(); | 474 return address() + sizeof(*this) + headerPadding<Header>(); |
| 455 } | 475 } |
| 456 | 476 |
| 457 static size_t payloadSize() | 477 static size_t payloadSize() |
| 458 { | 478 { |
| 459 return (blinkPagePayloadSize() - sizeof(HeapPage) - headerPadding<Header
>()) & ~allocationMask; | 479 return (blinkPagePayloadSize() - sizeof(HeapPage) - headerPadding<Header
>()) & ~allocationMask; |
| 460 } | 480 } |
| 461 | 481 |
| 462 Address end() { return payload() + payloadSize(); } | 482 Address end() { return payload() + payloadSize(); } |
| 463 | 483 |
| 464 void getStats(HeapStats&); | 484 void getStats(HeapStats&); |
| 465 void clearMarks(); | 485 void clearMarks(); |
| 466 void sweep(); | 486 void sweep(); |
| 467 void clearObjectStartBitMap(); | 487 void clearObjectStartBitMap(); |
| 468 void finalize(Header*); | 488 void finalize(Header*); |
| 469 virtual bool checkAndMarkPointer(Visitor*, Address); | 489 virtual void checkAndMarkPointer(Visitor*, Address) OVERRIDE; |
| 470 #if ENABLE(GC_TRACING) | 490 #if ENABLE(GC_TRACING) |
| 471 const GCInfo* findGCInfo(Address) OVERRIDE; | 491 const GCInfo* findGCInfo(Address) OVERRIDE; |
| 472 #endif | 492 #endif |
| 473 ThreadHeap<Header>* heap() { return m_heap; } | 493 ThreadHeap<Header>* heap() { return m_heap; } |
| 474 #if defined(ADDRESS_SANITIZER) | 494 #if defined(ADDRESS_SANITIZER) |
| 475 void poisonUnmarkedObjects(); | 495 void poisonUnmarkedObjects(); |
| 476 #endif | 496 #endif |
| 477 | 497 |
| 478 protected: | 498 protected: |
| 479 Header* findHeaderFromAddress(Address); | 499 Header* findHeaderFromAddress(Address); |
| 480 void populateObjectStartBitMap(); | 500 void populateObjectStartBitMap(); |
| 481 bool isObjectStartBitMapComputed() { return m_objectStartBitMapComputed; } | 501 bool isObjectStartBitMapComputed() { return m_objectStartBitMapComputed; } |
| 482 TraceCallback traceCallback(Header*); | 502 TraceCallback traceCallback(Header*); |
| 483 bool hasVTable(Header*); | 503 bool hasVTable(Header*); |
| 484 | 504 |
| 485 HeapPage<Header>* m_next; | 505 HeapPage<Header>* m_next; |
| 486 ThreadHeap<Header>* m_heap; | 506 ThreadHeap<Header>* m_heap; |
| 487 bool m_objectStartBitMapComputed; | 507 bool m_objectStartBitMapComputed; |
| 488 uint8_t m_objectStartBitMap[reservedForObjectBitMap]; | 508 uint8_t m_objectStartBitMap[reservedForObjectBitMap]; |
| 489 | 509 |
| 490 friend class ThreadHeap<Header>; | 510 friend class ThreadHeap<Header>; |
| 491 }; | 511 }; |
| 492 | 512 |
| 493 // A HeapContainsCache provides a fast way of taking an arbitrary | 513 class AddressEntry { |
| 514 public: |
| 515 AddressEntry() : m_address(0) { } |
| 516 |
| 517 explicit AddressEntry(Address address) : m_address(address) { } |
| 518 |
| 519 Address address() const { return m_address; } |
| 520 |
| 521 private: |
| 522 Address m_address; |
| 523 }; |
| 524 |
| 525 class PositiveEntry : public AddressEntry { |
| 526 public: |
| 527 PositiveEntry() |
| 528 : AddressEntry() |
| 529 , m_containingPage(0) |
| 530 { |
| 531 } |
| 532 |
| 533 PositiveEntry(Address address, BaseHeapPage* containingPage) |
| 534 : AddressEntry(address) |
| 535 , m_containingPage(containingPage) |
| 536 { |
| 537 } |
| 538 |
| 539 BaseHeapPage* result() const { return m_containingPage; } |
| 540 |
| 541 typedef BaseHeapPage* LookupResult; |
| 542 |
| 543 private: |
| 544 BaseHeapPage* m_containingPage; |
| 545 }; |
| 546 |
| 547 class NegativeEntry : public AddressEntry { |
| 548 public: |
| 549 NegativeEntry() : AddressEntry() { } |
| 550 |
| 551 NegativeEntry(Address address, bool) : AddressEntry(address) { } |
| 552 |
| 553 bool result() const { return true; } |
| 554 |
| 555 typedef bool LookupResult; |
| 556 }; |
| 557 |
| 558 // A HeapExtentCache provides a fast way of taking an arbitrary |
| 494 // pointer-sized word, and determining whether it can be interpreted | 559 // pointer-sized word, and determining whether it can be interpreted |
| 495 // as a pointer to an area that is managed by the garbage collected | 560 // as a pointer to an area that is managed by the garbage collected |
| 496 // Blink heap. There is a cache of 'pages' that have previously been | 561 // Blink heap. There is a cache of 'pages' that have previously been |
| 497 // determined to be either wholly inside or wholly outside the | 562 // determined to be wholly inside the heap. The size of these pages must be |
| 498 // heap. The size of these pages must be smaller than the allocation | 563 // smaller than the allocation alignment of the heap pages. We determine |
| 499 // alignment of the heap pages. We determine on-heap-ness by rounding | 564 // on-heap-ness by rounding down the pointer to the nearest page and looking up |
| 500 // down the pointer to the nearest page and looking up the page in the | 565 // the page in the cache. If there is a miss in the cache we can ask the heap |
| 501 // cache. If there is a miss in the cache we ask the heap to determine | 566 // to determine the status of the pointer by iterating over all of the heap. |
| 502 // the status of the pointer by iterating over all of the heap. The | 567 // The result is then cached in the two-way associative page cache. |
| 503 // result is then cached in the two-way associative page cache. | |
| 504 // | 568 // |
| 505 // A HeapContainsCache is both a positive and negative | 569 // A HeapContainsCache is a positive cache. Therefore, it must be flushed when |
| 506 // cache. Therefore, it must be flushed both when new memory is added | 570 // memory is removed from the Blink heap. The HeapDoesNotContainCache is a |
| 507 // and when memory is removed from the Blink heap. | 571 // negative cache, so it must be flushed when memory is added to the heap. |
| 508 class HeapContainsCache { | 572 template<typename Entry> |
| 573 class HeapExtentCache { |
| 509 public: | 574 public: |
| 510 HeapContainsCache(); | 575 HeapExtentCache() |
| 576 : m_entries(adoptArrayPtr(new Entry[HeapExtentCache::numberOfEntries])) |
| 577 , m_hasEntries(false) |
| 578 { |
| 579 } |
| 511 | 580 |
| 512 void flush(); | 581 void flush(); |
| 513 bool contains(Address); | 582 bool contains(Address); |
| 583 bool isEmpty() { return !m_hasEntries; } |
| 514 | 584 |
| 515 // Perform a lookup in the cache. | 585 // Perform a lookup in the cache. |
| 516 // | 586 // |
| 517 // If lookup returns false the argument address was not found in | 587 // If lookup returns null/false the argument address was not found in |
| 518 // the cache and it is unknown if the address is in the Blink | 588 // the cache and it is unknown if the address is in the Blink |
| 519 // heap. | 589 // heap. |
| 520 // | 590 // |
| 521 // If lookup returns true the argument address was found in the | 591 // If lookup returns true/a page, the argument address was found in the |
| 522 // cache. In that case, the address is in the heap if the base | 592 // cache. For the HeapContainsCache this means the address is in the heap. |
| 523 // heap page out parameter is different from 0 and is not in the | 593 // For the HeapDoesNotContainCache this means the address is not in the |
| 524 // heap if the base heap page out parameter is 0. | 594 // heap. |
| 525 bool lookup(Address, BaseHeapPage**); | 595 PLATFORM_EXPORT typename Entry::LookupResult lookup(Address); |
| 526 | 596 |
| 527 // Add an entry to the cache. Use a 0 base heap page pointer to | 597 // Add an entry to the cache. |
| 528 // add a negative entry. | 598 PLATFORM_EXPORT void addEntry(Address, typename Entry::LookupResult); |
| 529 void addEntry(Address, BaseHeapPage*); | |
| 530 | 599 |
| 531 private: | 600 private: |
| 532 class Entry { | |
| 533 public: | |
| 534 Entry() | |
| 535 : m_address(0) | |
| 536 , m_containingPage(0) | |
| 537 { | |
| 538 } | |
| 539 | |
| 540 Entry(Address address, BaseHeapPage* containingPage) | |
| 541 : m_address(address) | |
| 542 , m_containingPage(containingPage) | |
| 543 { | |
| 544 } | |
| 545 | |
| 546 BaseHeapPage* containingPage() { return m_containingPage; } | |
| 547 Address address() { return m_address; } | |
| 548 | |
| 549 private: | |
| 550 Address m_address; | |
| 551 BaseHeapPage* m_containingPage; | |
| 552 }; | |
| 553 | |
| 554 static const int numberOfEntriesLog2 = 12; | 601 static const int numberOfEntriesLog2 = 12; |
| 555 static const int numberOfEntries = 1 << numberOfEntriesLog2; | 602 static const int numberOfEntries = 1 << numberOfEntriesLog2; |
| 556 | 603 |
| 557 static size_t hash(Address); | 604 static size_t hash(Address); |
| 558 | 605 |
| 559 WTF::OwnPtr<HeapContainsCache::Entry[]> m_entries; | 606 WTF::OwnPtr<Entry[]> m_entries; |
| 607 bool m_hasEntries; |
| 560 | 608 |
| 561 friend class ThreadState; | 609 friend class ThreadState; |
| 562 }; | 610 }; |
| 563 | 611 |
| 612 // Normally these would be typedefs instead of subclasses, but that makes them |
| 613 // very hard to forward declare. |
| 614 class HeapContainsCache : public HeapExtentCache<PositiveEntry> { |
| 615 public: |
| 616 BaseHeapPage* lookup(Address); |
| 617 void addEntry(Address, BaseHeapPage*); |
| 618 }; |
| 619 |
| 620 class HeapDoesNotContainCache : public HeapExtentCache<NegativeEntry> { }; |
| 621 |
| 564 // FIXME: This is currently used by the WebAudio code. | 622 // FIXME: This is currently used by the WebAudio code. |
| 565 // We should attempt to restructure the WebAudio code so that the main thread | 623 // We should attempt to restructure the WebAudio code so that the main thread |
| 566 // alone determines life-time and receives messages about life-time from the | 624 // alone determines life-time and receives messages about life-time from the |
| 567 // audio thread. | 625 // audio thread. |
| 568 template<typename T> | 626 template<typename T> |
| 569 class ThreadSafeRefCountedGarbageCollected : public GarbageCollectedFinalized<T>
, public WTF::ThreadSafeRefCountedBase { | 627 class ThreadSafeRefCountedGarbageCollected : public GarbageCollectedFinalized<T>
, public WTF::ThreadSafeRefCountedBase { |
| 570 WTF_MAKE_NONCOPYABLE(ThreadSafeRefCountedGarbageCollected); | 628 WTF_MAKE_NONCOPYABLE(ThreadSafeRefCountedGarbageCollected); |
| 571 | 629 |
| 572 public: | 630 public: |
| 573 ThreadSafeRefCountedGarbageCollected() | 631 ThreadSafeRefCountedGarbageCollected() |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 674 // Non-template super class used to pass a heap around to other classes. | 732 // Non-template super class used to pass a heap around to other classes. |
| 675 class BaseHeap { | 733 class BaseHeap { |
| 676 public: | 734 public: |
| 677 virtual ~BaseHeap() { } | 735 virtual ~BaseHeap() { } |
| 678 | 736 |
| 679 // Find the page in this thread heap containing the given | 737 // Find the page in this thread heap containing the given |
| 680 // address. Returns 0 if the address is not contained in any | 738 // address. Returns 0 if the address is not contained in any |
| 681 // page in this thread heap. | 739 // page in this thread heap. |
| 682 virtual BaseHeapPage* heapPageFromAddress(Address) = 0; | 740 virtual BaseHeapPage* heapPageFromAddress(Address) = 0; |
| 683 | 741 |
| 684 // Find the large object in this thread heap containing the given | |
| 685 // address. Returns 0 if the address is not contained in any | |
| 686 // page in this thread heap. | |
| 687 virtual BaseHeapPage* largeHeapObjectFromAddress(Address) = 0; | |
| 688 | |
| 689 #if ENABLE(GC_TRACING) | 742 #if ENABLE(GC_TRACING) |
| 690 virtual const GCInfo* findGCInfoOfLargeHeapObject(Address) = 0; | 743 virtual const GCInfo* findGCInfoOfLargeHeapObject(Address) = 0; |
| 691 #endif | 744 #endif |
| 692 | 745 |
| 693 // Check if the given address could point to an object in this | |
| 694 // heap. If so, find the start of that object and mark it using | |
| 695 // the given Visitor. | |
| 696 // | |
| 697 // Returns true if the object was found and marked, returns false | |
| 698 // otherwise. | |
| 699 // | |
| 700 // This is used during conservative stack scanning to | |
| 701 // conservatively mark all objects that could be referenced from | |
| 702 // the stack. | |
| 703 virtual bool checkAndMarkLargeHeapObject(Visitor*, Address) = 0; | |
| 704 | |
| 705 // Sweep this part of the Blink heap. This finalizes dead objects | 746 // Sweep this part of the Blink heap. This finalizes dead objects |
| 706 // and builds freelists for all the unused memory. | 747 // and builds freelists for all the unused memory. |
| 707 virtual void sweep() = 0; | 748 virtual void sweep() = 0; |
| 708 | 749 |
| 709 // Forcefully finalize all objects in this part of the Blink heap | 750 // Forcefully finalize all objects in this part of the Blink heap |
| 710 // (potentially with the exception of one object). This is used | 751 // (potentially with the exception of one object). This is used |
| 711 // during thread termination to make sure that all objects for the | 752 // during thread termination to make sure that all objects for the |
| 712 // dying thread are finalized. | 753 // dying thread are finalized. |
| 713 virtual void assertEmpty() = 0; | 754 virtual void assertEmpty() = 0; |
| 714 | 755 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 737 // (potentially adding new pages to the heap), to find and mark | 778 // (potentially adding new pages to the heap), to find and mark |
| 738 // objects during conservative stack scanning and to sweep the set of | 779 // objects during conservative stack scanning and to sweep the set of |
| 739 // pages after a GC. | 780 // pages after a GC. |
| 740 template<typename Header> | 781 template<typename Header> |
| 741 class ThreadHeap : public BaseHeap { | 782 class ThreadHeap : public BaseHeap { |
| 742 public: | 783 public: |
| 743 ThreadHeap(ThreadState*); | 784 ThreadHeap(ThreadState*); |
| 744 virtual ~ThreadHeap(); | 785 virtual ~ThreadHeap(); |
| 745 | 786 |
| 746 virtual BaseHeapPage* heapPageFromAddress(Address); | 787 virtual BaseHeapPage* heapPageFromAddress(Address); |
| 747 virtual BaseHeapPage* largeHeapObjectFromAddress(Address); | |
| 748 #if ENABLE(GC_TRACING) | 788 #if ENABLE(GC_TRACING) |
| 749 virtual const GCInfo* findGCInfoOfLargeHeapObject(Address); | 789 virtual const GCInfo* findGCInfoOfLargeHeapObject(Address); |
| 750 #endif | 790 #endif |
| 751 virtual bool checkAndMarkLargeHeapObject(Visitor*, Address); | |
| 752 virtual void sweep(); | 791 virtual void sweep(); |
| 753 virtual void assertEmpty(); | 792 virtual void assertEmpty(); |
| 754 virtual void clearFreeLists(); | 793 virtual void clearFreeLists(); |
| 755 virtual void clearMarks(); | 794 virtual void clearMarks(); |
| 756 #ifndef NDEBUG | 795 #ifndef NDEBUG |
| 757 virtual void getScannedStats(HeapStats&); | 796 virtual void getScannedStats(HeapStats&); |
| 758 #endif | 797 #endif |
| 759 | 798 |
| 760 virtual void makeConsistentForGC(); | 799 virtual void makeConsistentForGC(); |
| 761 virtual bool isConsistentForGC(); | 800 virtual bool isConsistentForGC(); |
| 762 | 801 |
| 763 ThreadState* threadState() { return m_threadState; } | 802 ThreadState* threadState() { return m_threadState; } |
| 764 HeapStats& stats() { return m_threadState->stats(); } | 803 HeapStats& stats() { return m_threadState->stats(); } |
| 765 HeapContainsCache* heapContainsCache() { return m_threadState->heapContainsC
ache(); } | 804 void flushHeapContainsCache() |
| 805 { |
| 806 m_threadState->heapContainsCache()->flush(); |
| 807 } |
| 766 | 808 |
| 767 inline Address allocate(size_t, const GCInfo*); | 809 inline Address allocate(size_t, const GCInfo*); |
| 768 void addToFreeList(Address, size_t); | 810 void addToFreeList(Address, size_t); |
| 769 void addPageToPool(HeapPage<Header>*); | 811 void addPageToPool(HeapPage<Header>*); |
| 770 inline static size_t roundedAllocationSize(size_t size) | 812 inline static size_t roundedAllocationSize(size_t size) |
| 771 { | 813 { |
| 772 return allocationSizeFromSize(size) - sizeof(Header); | 814 return allocationSizeFromSize(size) - sizeof(Header); |
| 773 } | 815 } |
| 774 | 816 |
| 775 private: | 817 private: |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 #endif | 941 #endif |
| 900 | 942 |
| 901 // Collect heap stats for all threads attached to the Blink | 943 // Collect heap stats for all threads attached to the Blink |
| 902 // garbage collector. Should only be called during garbage | 944 // garbage collector. Should only be called during garbage |
| 903 // collection where threads are known to be at safe points. | 945 // collection where threads are known to be at safe points. |
| 904 static void getStats(HeapStats*); | 946 static void getStats(HeapStats*); |
| 905 | 947 |
| 906 static bool isConsistentForGC(); | 948 static bool isConsistentForGC(); |
| 907 static void makeConsistentForGC(); | 949 static void makeConsistentForGC(); |
| 908 | 950 |
| 951 static void flushHeapDoesNotContainCache(); |
| 952 static bool heapDoesNotContainCacheIsEmpty() { return s_heapDoesNotContainCa
che->isEmpty(); } |
| 953 |
| 954 private: |
| 909 static Visitor* s_markingVisitor; | 955 static Visitor* s_markingVisitor; |
| 910 | 956 |
| 911 static CallbackStack* s_markingStack; | 957 static CallbackStack* s_markingStack; |
| 912 static CallbackStack* s_weakCallbackStack; | 958 static CallbackStack* s_weakCallbackStack; |
| 959 static HeapDoesNotContainCache* s_heapDoesNotContainCache; |
| 913 static bool s_shutdownCalled; | 960 static bool s_shutdownCalled; |
| 961 friend class ThreadState; |
| 914 }; | 962 }; |
| 915 | 963 |
| 916 // The NoAllocationScope class is used in debug mode to catch unwanted | 964 // The NoAllocationScope class is used in debug mode to catch unwanted |
| 917 // allocations. E.g. allocations during GC. | 965 // allocations. E.g. allocations during GC. |
| 918 template<ThreadAffinity Affinity> | 966 template<ThreadAffinity Affinity> |
| 919 class NoAllocationScope { | 967 class NoAllocationScope { |
| 920 public: | 968 public: |
| 921 NoAllocationScope() : m_active(true) { enter(); } | 969 NoAllocationScope() : m_active(true) { enter(); } |
| 922 | 970 |
| 923 explicit NoAllocationScope(bool active) : m_active(active) { enter(); } | 971 explicit NoAllocationScope(bool active) : m_active(active) { enter(); } |
| (...skipping 1331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2255 // to export. This forces it to export all the methods from ThreadHeap. | 2303 // to export. This forces it to export all the methods from ThreadHeap. |
| 2256 template<> void ThreadHeap<FinalizedHeapObjectHeader>::addPageToHeap(const GCInf
o*); | 2304 template<> void ThreadHeap<FinalizedHeapObjectHeader>::addPageToHeap(const GCInf
o*); |
| 2257 template<> void ThreadHeap<HeapObjectHeader>::addPageToHeap(const GCInfo*); | 2305 template<> void ThreadHeap<HeapObjectHeader>::addPageToHeap(const GCInfo*); |
| 2258 extern template class PLATFORM_EXPORT ThreadHeap<FinalizedHeapObjectHeader>; | 2306 extern template class PLATFORM_EXPORT ThreadHeap<FinalizedHeapObjectHeader>; |
| 2259 extern template class PLATFORM_EXPORT ThreadHeap<HeapObjectHeader>; | 2307 extern template class PLATFORM_EXPORT ThreadHeap<HeapObjectHeader>; |
| 2260 #endif | 2308 #endif |
| 2261 | 2309 |
| 2262 } | 2310 } |
| 2263 | 2311 |
| 2264 #endif // Heap_h | 2312 #endif // Heap_h |
| OLD | NEW |