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 27 matching lines...) Expand all Loading... |
38 #include "platform/heap/ThreadState.h" | 38 #include "platform/heap/ThreadState.h" |
39 #include "platform/heap/Visitor.h" | 39 #include "platform/heap/Visitor.h" |
40 #include "wtf/AddressSanitizer.h" | 40 #include "wtf/AddressSanitizer.h" |
41 #include "wtf/Allocator.h" | 41 #include "wtf/Allocator.h" |
42 #include "wtf/Assertions.h" | 42 #include "wtf/Assertions.h" |
43 #include "wtf/Atomics.h" | 43 #include "wtf/Atomics.h" |
44 #include "wtf/Forward.h" | 44 #include "wtf/Forward.h" |
45 | 45 |
46 namespace blink { | 46 namespace blink { |
47 | 47 |
| 48 class PLATFORM_EXPORT HeapAllocHooks { |
| 49 public: |
| 50 // TODO(hajimehoshi): Pass a type name of the allocated object. |
| 51 typedef void AllocationHook(Address, size_t); |
| 52 typedef void FreeHook(Address); |
| 53 |
| 54 static void setAllocationHook(AllocationHook* hook) { m_allocationHook = hoo
k; } |
| 55 static void setFreeHook(FreeHook* hook) { m_freeHook = hook; } |
| 56 |
| 57 static void allocationHookIfEnabled(Address address, size_t size) |
| 58 { |
| 59 AllocationHook* allocationHook = m_allocationHook; |
| 60 if (UNLIKELY(!!allocationHook)) |
| 61 allocationHook(address, size); |
| 62 } |
| 63 |
| 64 static void freeHookIfEnabled(Address address) |
| 65 { |
| 66 FreeHook* freeHook = m_freeHook; |
| 67 if (UNLIKELY(!!freeHook)) |
| 68 freeHook(address); |
| 69 } |
| 70 |
| 71 static void reallocHookIfEnabled(Address oldAddress, Address newAddress, siz
e_t size) |
| 72 { |
| 73 // Report a reallocation as a free followed by an allocation. |
| 74 AllocationHook* allocationHook = m_allocationHook; |
| 75 FreeHook* freeHook = m_freeHook; |
| 76 if (UNLIKELY(allocationHook && freeHook)) { |
| 77 freeHook(oldAddress); |
| 78 allocationHook(newAddress, size); |
| 79 } |
| 80 } |
| 81 |
| 82 private: |
| 83 static AllocationHook* m_allocationHook; |
| 84 static FreeHook* m_freeHook; |
| 85 }; |
| 86 |
48 class CrossThreadPersistentRegion; | 87 class CrossThreadPersistentRegion; |
49 template<typename T> class Member; | 88 template<typename T> class Member; |
50 template<typename T> class WeakMember; | 89 template<typename T> class WeakMember; |
51 template<typename T> class UntracedMember; | 90 template<typename T> class UntracedMember; |
52 | 91 |
53 template<typename T, bool = NeedsAdjustAndMark<T>::value> class ObjectAliveTrait
; | 92 template<typename T, bool = NeedsAdjustAndMark<T>::value> class ObjectAliveTrait
; |
54 | 93 |
55 template<typename T> | 94 template<typename T> |
56 class ObjectAliveTrait<T, false> { | 95 class ObjectAliveTrait<T, false> { |
57 STATIC_ONLY(ObjectAliveTrait); | 96 STATIC_ONLY(ObjectAliveTrait); |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 ASSERT(state->isAllocationAllowed()); | 488 ASSERT(state->isAllocationAllowed()); |
450 ASSERT(heapIndex != BlinkGC::LargeObjectHeapIndex); | 489 ASSERT(heapIndex != BlinkGC::LargeObjectHeapIndex); |
451 NormalPageHeap* heap = static_cast<NormalPageHeap*>(state->heap(heapIndex)); | 490 NormalPageHeap* heap = static_cast<NormalPageHeap*>(state->heap(heapIndex)); |
452 return heap->allocateObject(allocationSizeFromSize(size), gcInfoIndex); | 491 return heap->allocateObject(allocationSizeFromSize(size), gcInfoIndex); |
453 } | 492 } |
454 | 493 |
455 template<typename T> | 494 template<typename T> |
456 Address Heap::allocate(size_t size, bool eagerlySweep) | 495 Address Heap::allocate(size_t size, bool eagerlySweep) |
457 { | 496 { |
458 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(); | 497 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(); |
459 return Heap::allocateOnHeapIndex(state, size, eagerlySweep ? BlinkGC::EagerS
weepHeapIndex : Heap::heapIndexForObjectSize(size), GCInfoTrait<T>::index()); | 498 Address address = Heap::allocateOnHeapIndex(state, size, eagerlySweep ? Blin
kGC::EagerSweepHeapIndex : Heap::heapIndexForObjectSize(size), GCInfoTrait<T>::i
ndex()); |
| 499 HeapAllocHooks::allocationHookIfEnabled(address, size); |
| 500 return address; |
460 } | 501 } |
461 | 502 |
462 template<typename T> | 503 template<typename T> |
463 Address Heap::reallocate(void* previous, size_t size) | 504 Address Heap::reallocate(void* previous, size_t size) |
464 { | 505 { |
465 // Not intended to be a full C realloc() substitute; | 506 // Not intended to be a full C realloc() substitute; |
466 // realloc(nullptr, size) is not a supported alias for malloc(size). | 507 // realloc(nullptr, size) is not a supported alias for malloc(size). |
467 | 508 |
468 // TODO(sof): promptly free the previous object. | 509 // TODO(sof): promptly free the previous object. |
469 if (!size) { | 510 if (!size) { |
(...skipping 12 matching lines...) Expand all Loading... |
482 heapIndex = heapIndexForObjectSize(size); | 523 heapIndex = heapIndexForObjectSize(size); |
483 | 524 |
484 // TODO(haraken): We don't support reallocate() for finalizable objects. | 525 // TODO(haraken): We don't support reallocate() for finalizable objects. |
485 ASSERT(!Heap::gcInfo(previousHeader->gcInfoIndex())->hasFinalizer()); | 526 ASSERT(!Heap::gcInfo(previousHeader->gcInfoIndex())->hasFinalizer()); |
486 ASSERT(previousHeader->gcInfoIndex() == GCInfoTrait<T>::index()); | 527 ASSERT(previousHeader->gcInfoIndex() == GCInfoTrait<T>::index()); |
487 Address address = Heap::allocateOnHeapIndex(state, size, heapIndex, GCInfoTr
ait<T>::index()); | 528 Address address = Heap::allocateOnHeapIndex(state, size, heapIndex, GCInfoTr
ait<T>::index()); |
488 size_t copySize = previousHeader->payloadSize(); | 529 size_t copySize = previousHeader->payloadSize(); |
489 if (copySize > size) | 530 if (copySize > size) |
490 copySize = size; | 531 copySize = size; |
491 memcpy(address, previous, copySize); | 532 memcpy(address, previous, copySize); |
| 533 HeapAllocHooks::reallocHookIfEnabled(static_cast<Address>(previous), address
, size); |
492 return address; | 534 return address; |
493 } | 535 } |
494 | 536 |
495 template<typename Derived> | 537 template<typename Derived> |
496 template<typename T> | 538 template<typename T> |
497 void VisitorHelper<Derived>::handleWeakCell(Visitor* self, void* object) | 539 void VisitorHelper<Derived>::handleWeakCell(Visitor* self, void* object) |
498 { | 540 { |
499 T** cell = reinterpret_cast<T**>(object); | 541 T** cell = reinterpret_cast<T**>(object); |
500 if (*cell && !ObjectAliveTrait<T>::isHeapObjectAlive(*cell)) | 542 if (*cell && !ObjectAliveTrait<T>::isHeapObjectAlive(*cell)) |
501 *cell = nullptr; | 543 *cell = nullptr; |
502 } | 544 } |
503 | 545 |
504 } // namespace blink | 546 } // namespace blink |
505 | 547 |
506 #endif // Heap_h | 548 #endif // Heap_h |
OLD | NEW |