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 != nullptr)) | |
haraken
2016/02/12 10:29:19
UNLIKELY(!allocationHook)
hajimehoshi
2016/02/15 07:14:46
I guess UNLIKELY(!!allocationHook). Done.
UNLIKEL
| |
61 allocationHook(address, size); | |
62 } | |
63 | |
64 static void freeHookIfEnabled(Address address) | |
65 { | |
66 FreeHook* freeHook = m_freeHook; | |
67 if (UNLIKELY(freeHook != nullptr)) | |
haraken
2016/02/12 10:29:18
UNLIKELY(!freeHook)
hajimehoshi
2016/02/15 07:14:46
UNLIKELY(!!freeHook). Done.
| |
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 // Pointers to hook functions that HeapAlloc will call on allocation and | |
84 // free if the pointers are non-null. | |
haraken
2016/02/12 10:29:19
I'd remove this comment.
hajimehoshi
2016/02/15 07:14:46
Done.
| |
85 static AllocationHook* m_allocationHook; | |
86 static FreeHook* m_freeHook; | |
87 }; | |
88 | |
48 class CrossThreadPersistentRegion; | 89 class CrossThreadPersistentRegion; |
49 template<typename T> class Member; | 90 template<typename T> class Member; |
50 template<typename T> class WeakMember; | 91 template<typename T> class WeakMember; |
51 template<typename T> class UntracedMember; | 92 template<typename T> class UntracedMember; |
52 | 93 |
53 template<typename T, bool = NeedsAdjustAndMark<T>::value> class ObjectAliveTrait ; | 94 template<typename T, bool = NeedsAdjustAndMark<T>::value> class ObjectAliveTrait ; |
54 | 95 |
55 template<typename T> | 96 template<typename T> |
56 class ObjectAliveTrait<T, false> { | 97 class ObjectAliveTrait<T, false> { |
57 STATIC_ONLY(ObjectAliveTrait); | 98 STATIC_ONLY(ObjectAliveTrait); |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
446 ASSERT(state->isAllocationAllowed()); | 487 ASSERT(state->isAllocationAllowed()); |
447 ASSERT(heapIndex != BlinkGC::LargeObjectHeapIndex); | 488 ASSERT(heapIndex != BlinkGC::LargeObjectHeapIndex); |
448 NormalPageHeap* heap = static_cast<NormalPageHeap*>(state->heap(heapIndex)); | 489 NormalPageHeap* heap = static_cast<NormalPageHeap*>(state->heap(heapIndex)); |
449 return heap->allocateObject(allocationSizeFromSize(size), gcInfoIndex); | 490 return heap->allocateObject(allocationSizeFromSize(size), gcInfoIndex); |
450 } | 491 } |
451 | 492 |
452 template<typename T> | 493 template<typename T> |
453 Address Heap::allocate(size_t size, bool eagerlySweep) | 494 Address Heap::allocate(size_t size, bool eagerlySweep) |
454 { | 495 { |
455 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(); | 496 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(); |
456 return Heap::allocateOnHeapIndex(state, size, eagerlySweep ? BlinkGC::EagerS weepHeapIndex : Heap::heapIndexForObjectSize(size), GCInfoTrait<T>::index()); | 497 Address address = Heap::allocateOnHeapIndex(state, size, eagerlySweep ? Blin kGC::EagerSweepHeapIndex : Heap::heapIndexForObjectSize(size), GCInfoTrait<T>::i ndex()); |
498 HeapAllocHooks::allocationHookIfEnabled(address, size); | |
499 return address; | |
457 } | 500 } |
458 | 501 |
459 template<typename T> | 502 template<typename T> |
460 Address Heap::reallocate(void* previous, size_t size) | 503 Address Heap::reallocate(void* previous, size_t size) |
461 { | 504 { |
462 // Not intended to be a full C realloc() substitute; | 505 // Not intended to be a full C realloc() substitute; |
463 // realloc(nullptr, size) is not a supported alias for malloc(size). | 506 // realloc(nullptr, size) is not a supported alias for malloc(size). |
464 | 507 |
465 // TODO(sof): promptly free the previous object. | 508 // TODO(sof): promptly free the previous object. |
466 if (!size) { | 509 if (!size) { |
(...skipping 12 matching lines...) Expand all Loading... | |
479 heapIndex = heapIndexForObjectSize(size); | 522 heapIndex = heapIndexForObjectSize(size); |
480 | 523 |
481 // TODO(haraken): We don't support reallocate() for finalizable objects. | 524 // TODO(haraken): We don't support reallocate() for finalizable objects. |
482 ASSERT(!Heap::gcInfo(previousHeader->gcInfoIndex())->hasFinalizer()); | 525 ASSERT(!Heap::gcInfo(previousHeader->gcInfoIndex())->hasFinalizer()); |
483 ASSERT(previousHeader->gcInfoIndex() == GCInfoTrait<T>::index()); | 526 ASSERT(previousHeader->gcInfoIndex() == GCInfoTrait<T>::index()); |
484 Address address = Heap::allocateOnHeapIndex(state, size, heapIndex, GCInfoTr ait<T>::index()); | 527 Address address = Heap::allocateOnHeapIndex(state, size, heapIndex, GCInfoTr ait<T>::index()); |
485 size_t copySize = previousHeader->payloadSize(); | 528 size_t copySize = previousHeader->payloadSize(); |
486 if (copySize > size) | 529 if (copySize > size) |
487 copySize = size; | 530 copySize = size; |
488 memcpy(address, previous, copySize); | 531 memcpy(address, previous, copySize); |
532 HeapAllocHooks::reallocHookIfEnabled(static_cast<Address>(previous), address , size); | |
489 return address; | 533 return address; |
490 } | 534 } |
491 | 535 |
492 template<typename Derived> | 536 template<typename Derived> |
493 template<typename T> | 537 template<typename T> |
494 void VisitorHelper<Derived>::handleWeakCell(Visitor* self, void* object) | 538 void VisitorHelper<Derived>::handleWeakCell(Visitor* self, void* object) |
495 { | 539 { |
496 T** cell = reinterpret_cast<T**>(object); | 540 T** cell = reinterpret_cast<T**>(object); |
497 if (*cell && !ObjectAliveTrait<T>::isHeapObjectAlive(*cell)) | 541 if (*cell && !ObjectAliveTrait<T>::isHeapObjectAlive(*cell)) |
498 *cell = nullptr; | 542 *cell = nullptr; |
499 } | 543 } |
500 | 544 |
501 } // namespace blink | 545 } // namespace blink |
502 | 546 |
503 #endif // Heap_h | 547 #endif // Heap_h |
OLD | NEW |