| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 #ifndef VM_HEAP_TRACE_H_ | |
| 6 #define VM_HEAP_TRACE_H_ | |
| 7 | |
| 8 #include "include/dart_api.h" | |
| 9 #include "vm/globals.h" | |
| 10 #include "vm/object_set.h" | |
| 11 | |
| 12 namespace dart { | |
| 13 | |
| 14 // Forward declarations. | |
| 15 class HeapTraceVisitor; | |
| 16 class Isolate; | |
| 17 class RawClass; | |
| 18 class RawObject; | |
| 19 class RawString; | |
| 20 class BaseZone; | |
| 21 | |
| 22 class HeapTrace { | |
| 23 public: | |
| 24 enum RecordSize { | |
| 25 kRootSize = 5, | |
| 26 kAllocSize = 9, | |
| 27 kSnapshotAllocSize = 9, | |
| 28 kCopySize = 9, | |
| 29 kStoreSize = 13, | |
| 30 kSweepSize = 5, | |
| 31 kDeathRangeSize = 9, | |
| 32 kPromotionSize = 9, | |
| 33 kAllocZoneHandleSize = 9, | |
| 34 kDeleteZoneSize = 5, | |
| 35 kRegisterClassSize = 5, | |
| 36 kAllocScopedHandleSize = 5, | |
| 37 kDeleteScopedHandlesSize = 1, | |
| 38 kMarkSweepStartSize = 1, | |
| 39 kMarkSweepFinishSize = 1, | |
| 40 kObjectStoreSize = 5 | |
| 41 }; | |
| 42 | |
| 43 enum RecordType { | |
| 44 kRootType = 'R', | |
| 45 kAllocType = 'A', | |
| 46 kSnapshotAllocType = 'B', | |
| 47 kCopyType = 'C', | |
| 48 kStoreType = 'U', | |
| 49 kSweepType = 'S', | |
| 50 kDeathRangeType = 'L', | |
| 51 kPromotionType = 'P', | |
| 52 kAllocZoneHandleType = 'Z', | |
| 53 kDeleteZoneType = 'z', | |
| 54 kRegisterClassType = 'K', | |
| 55 kAllocScopedHandleType = 'H', | |
| 56 kDeleteScopedHandlesType = 'h', | |
| 57 kMarkSweepStartType = '{', | |
| 58 kMarkSweepFinishType = '}', | |
| 59 kObjectStoreType = 'O' | |
| 60 }; | |
| 61 | |
| 62 template <RecordType T, RecordSize N> | |
| 63 class Record { | |
| 64 public: | |
| 65 explicit Record(HeapTrace* trace): cursor_(0), trace_(trace) { | |
| 66 ASSERT(N >= 1); | |
| 67 buffer_[0] = T; | |
| 68 ++cursor_; | |
| 69 } | |
| 70 ~Record() { | |
| 71 (*trace_->write_callback_)(Buffer(), Length(), trace_->output_stream_); | |
| 72 } | |
| 73 | |
| 74 void Write(uword word) { | |
| 75 ASSERT(cursor_ + sizeof(word) <= N); | |
| 76 memmove(&buffer_[cursor_], &word, sizeof(word)); | |
| 77 cursor_ += sizeof(word); | |
| 78 } | |
| 79 | |
| 80 intptr_t Length() const { return cursor_; } | |
| 81 | |
| 82 const uint8_t* Buffer() const { | |
| 83 ASSERT(cursor_ == N); | |
| 84 return buffer_; | |
| 85 } | |
| 86 | |
| 87 private: | |
| 88 uint8_t buffer_[N]; | |
| 89 intptr_t cursor_; | |
| 90 HeapTrace* trace_; | |
| 91 DISALLOW_COPY_AND_ASSIGN(Record); | |
| 92 }; | |
| 93 | |
| 94 typedef Record<kRootType, kRootSize> RootRecord; | |
| 95 typedef Record<kAllocType, kAllocSize> AllocationRecord; | |
| 96 typedef Record<kSnapshotAllocType, kSnapshotAllocSize> | |
| 97 SnapshotAllocationRecord; | |
| 98 typedef Record<kCopyType, kCopySize> CopyRecord; | |
| 99 typedef Record<kStoreType, kStoreSize> StoreRecord; | |
| 100 typedef Record<kSweepType, kSweepSize> SweepRecord; | |
| 101 typedef Record<kDeathRangeType, kDeathRangeSize> DeathRangeRecord; | |
| 102 typedef Record<kPromotionType, kPromotionSize> PromotionRecord; | |
| 103 typedef Record<kAllocZoneHandleType, kAllocZoneHandleSize> | |
| 104 AllocZoneHandleRecord; | |
| 105 typedef Record<kDeleteZoneType, kDeleteZoneSize> | |
| 106 DeleteZoneRecord; | |
| 107 typedef Record<kRegisterClassType, kRegisterClassSize> RegisterClassRecord; | |
| 108 typedef Record<kAllocScopedHandleType, kAllocScopedHandleSize> | |
| 109 AllocScopedHandleRecord; | |
| 110 typedef Record<kDeleteScopedHandlesType, kDeleteScopedHandlesSize> | |
| 111 DeleteScopedHandlesRecord; | |
| 112 typedef Record<kMarkSweepStartType, kMarkSweepStartSize> MarkSweepStartRecord; | |
| 113 typedef Record<kMarkSweepFinishType, kMarkSweepFinishSize> | |
| 114 MarkSweepFinishRecord; | |
| 115 typedef Record<kObjectStoreType, kObjectStoreSize> ObjectStoreRecord; | |
| 116 | |
| 117 HeapTrace(); | |
| 118 ~HeapTrace(); | |
| 119 | |
| 120 // Called by the isolate just before EnableGrowthControl. Indicates | |
| 121 // the Isolate is initialized and enables tracing. | |
| 122 void Init(Isolate* isolate); | |
| 123 | |
| 124 // Called when an object is allocated in the heap. | |
| 125 void TraceAllocation(uword addr, intptr_t size); | |
| 126 | |
| 127 // Invoked after the snapshot is loaded at Isolate startup time. | |
| 128 void TraceSnapshotAlloc(RawObject* obj, intptr_t size); | |
| 129 | |
| 130 // Rename to something like TraceAllocateZoneHandle (or whatever) | |
| 131 void TraceAllocateZoneHandle(uword handle, uword zone_addr); | |
| 132 | |
| 133 // Invoked when a Zone block is deleted. | |
| 134 void TraceDeleteZone(Zone* zone); | |
| 135 | |
| 136 // Invoked whenever the scoped handles are delelted. | |
| 137 void TraceDeleteScopedHandles(); | |
| 138 | |
| 139 // Invoked when objects are coped from the from space to the to space | |
| 140 // by the scavenger. | |
| 141 void TraceCopy(uword from_addr, uword to_addr); | |
| 142 | |
| 143 // Invoked on each pointer in the object store. | |
| 144 void TraceObjectStorePointer(uword addr); | |
| 145 | |
| 146 // Invoked when an object is promoted from the new space to the old space. | |
| 147 void TracePromotion(uword old_addr, uword promoted_addr); | |
| 148 | |
| 149 // Invoked after a scavenge with the addressed range of from-space | |
| 150 void TraceDeathRange(uword inclusive_start, uword exclusive_end); | |
| 151 | |
| 152 // Invoked whenever a class is registered in the class table. | |
| 153 void TraceRegisterClass(const Class& cls); | |
| 154 | |
| 155 // Invoked when an address is swept. | |
| 156 void TraceSweep(uword sweept_addr); | |
| 157 | |
| 158 // Invoked when storing value into origin, and value is an object. | |
| 159 void TraceStoreIntoObject(uword origin_object_addr, | |
| 160 uword slot_addr, | |
| 161 uword value); | |
| 162 | |
| 163 // Invoked when starting a mark-sweep collection on old space | |
| 164 void TraceMarkSweepStart(); | |
| 165 | |
| 166 // Invoked after finishing a mark sweep collection on old space. | |
| 167 void TraceMarkSweepFinish(); | |
| 168 | |
| 169 // Initialize tracing globablly across the VM. Invidual isolates | |
| 170 // will still have to initialized themselves when they are started. | |
| 171 static void InitOnce(Dart_FileOpenCallback open_callback, | |
| 172 Dart_FileWriteCallback write_callback, | |
| 173 Dart_FileCloseCallback close_callback); | |
| 174 | |
| 175 // Returns true if tracign is enabled for the VM. | |
| 176 static bool is_enabled() { return is_enabled_; } | |
| 177 | |
| 178 private: | |
| 179 ObjectSet* CreateEmptyObjectSet() const; | |
| 180 void ResizeObjectSet(); | |
| 181 | |
| 182 void TraceScopedHandle(uword handle); | |
| 183 | |
| 184 // A helper for PutRoots, called by HeapTraceVisitor. | |
| 185 void TraceSingleRoot(uword root); | |
| 186 | |
| 187 // Invoked while tracing an allocation. | |
| 188 void TraceRoots(Isolate* isolate); | |
| 189 | |
| 190 // Is the isolate we are tracing initialized? | |
| 191 bool isolate_initialized_; | |
| 192 | |
| 193 void* output_stream_; | |
| 194 | |
| 195 ObjectSet object_set_; | |
| 196 | |
| 197 static Dart_FileOpenCallback open_callback_; | |
| 198 static Dart_FileWriteCallback write_callback_; | |
| 199 static Dart_FileCloseCallback close_callback_; | |
| 200 | |
| 201 static bool is_enabled_; | |
| 202 | |
| 203 friend class HeapTraceVisitor; | |
| 204 friend class HeapTraceScopedHandleVisitor; | |
| 205 friend class HeapTraceObjectStoreVisitor; | |
| 206 friend class HeapTraceDebugObjectVisitor; | |
| 207 | |
| 208 DISALLOW_COPY_AND_ASSIGN(HeapTrace); | |
| 209 }; | |
| 210 | |
| 211 } // namespace dart | |
| 212 | |
| 213 #endif // VM_HEAP_TRACE_H_ | |
| OLD | NEW |