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 |