Index: runtime/vm/heap_trace.h |
diff --git a/runtime/vm/heap_trace.h b/runtime/vm/heap_trace.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..983f7df0daacb72e7e811ec4c7f4b7f9b0cc7673 |
--- /dev/null |
+++ b/runtime/vm/heap_trace.h |
@@ -0,0 +1,213 @@ |
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+#ifndef VM_HEAP_TRACE_H_ |
+#define VM_HEAP_TRACE_H_ |
+ |
+#include "include/dart_api.h" |
+#include "vm/globals.h" |
+#include "vm/object_set.h" |
+ |
+namespace dart { |
+ |
+// Forward declarations. |
+class HeapTraceVisitor; |
+class Isolate; |
+class RawClass; |
+class RawObject; |
+class RawString; |
+class BaseZone; |
+ |
+class HeapTrace { |
+ public: |
+ enum RecordSize { |
+ kRootSize = 5, |
+ kAllocSize = 9, |
+ kSnapshotAllocSize = 9, |
+ kCopySize = 9, |
+ kStoreSize = 13, |
+ kSweepSize = 5, |
+ kDeathRangeSize = 9, |
+ kPromotionSize = 9, |
+ kAllocZoneHandleSize = 9, |
+ kDeleteZoneSize = 5, |
+ kRegisterClassSize = 5, |
+ kAllocScopedHandleSize = 5, |
+ kDeleteScopedHandlesSize = 1, |
+ kMarkSweepStartSize = 1, |
+ kMarkSweepFinishSize = 1, |
+ kObjectStoreSize = 5 |
+ }; |
+ |
+ enum RecordType { |
+ kRootType = 'R', |
+ kAllocType = 'A', |
+ kSnapshotAllocType = 'B', |
+ kCopyType = 'C', |
+ kStoreType = 'U', |
+ kSweepType = 'S', |
+ kDeathRangeType = 'L', |
+ kPromotionType = 'P', |
+ kAllocZoneHandleType = 'Z', |
+ kDeleteZoneType = 'z', |
+ kRegisterClassType = 'K', |
+ kAllocScopedHandleType = 'H', |
+ kDeleteScopedHandlesType = 'h', |
+ kMarkSweepStartType = '{', |
+ kMarkSweepFinishType = '}', |
+ kObjectStoreType = 'O' |
+ }; |
+ |
+ template <RecordType T, RecordSize N> |
+ class Record { |
+ public: |
+ explicit Record(HeapTrace* trace): cursor_(0), trace_(trace) { |
+ ASSERT(N >= 1); |
+ buffer_[0] = T; |
+ ++cursor_; |
+ } |
+ ~Record() { |
+ (*trace_->write_callback_)(Buffer(), Length(), trace_->output_stream_); |
+ } |
+ |
+ void Write(uword word) { |
+ ASSERT(cursor_ + sizeof(word) <= N); |
+ memmove(&buffer_[cursor_], &word, sizeof(word)); |
+ cursor_ += sizeof(word); |
+ } |
+ |
+ intptr_t Length() const { return cursor_; } |
+ |
+ const uint8_t* Buffer() const { |
+ ASSERT(cursor_ == N); |
+ return buffer_; |
+ } |
+ |
+ private: |
+ uint8_t buffer_[N]; |
+ intptr_t cursor_; |
+ HeapTrace* trace_; |
+ DISALLOW_COPY_AND_ASSIGN(Record); |
+ }; |
+ |
+ typedef Record<kRootType, kRootSize> RootRecord; |
+ typedef Record<kAllocType, kAllocSize> AllocationRecord; |
+ typedef Record<kSnapshotAllocType, kSnapshotAllocSize> |
+ SnapshotAllocationRecord; |
+ typedef Record<kCopyType, kCopySize> CopyRecord; |
+ typedef Record<kStoreType, kStoreSize> StoreRecord; |
+ typedef Record<kSweepType, kSweepSize> SweepRecord; |
+ typedef Record<kDeathRangeType, kDeathRangeSize> DeathRangeRecord; |
+ typedef Record<kPromotionType, kPromotionSize> PromotionRecord; |
+ typedef Record<kAllocZoneHandleType, kAllocZoneHandleSize> |
+ AllocZoneHandleRecord; |
+ typedef Record<kDeleteZoneType, kDeleteZoneSize> |
+ DeleteZoneRecord; |
+ typedef Record<kRegisterClassType, kRegisterClassSize> RegisterClassRecord; |
+ typedef Record<kAllocScopedHandleType, kAllocScopedHandleSize> |
+ AllocScopedHandleRecord; |
+ typedef Record<kDeleteScopedHandlesType, kDeleteScopedHandlesSize> |
+ DeleteScopedHandlesRecord; |
+ typedef Record<kMarkSweepStartType, kMarkSweepStartSize> MarkSweepStartRecord; |
+ typedef Record<kMarkSweepFinishType, kMarkSweepFinishSize> |
+ MarkSweepFinishRecord; |
+ typedef Record<kObjectStoreType, kObjectStoreSize> ObjectStoreRecord; |
+ |
+ HeapTrace(); |
+ ~HeapTrace(); |
+ |
+ // Called by the isolate just before EnableGrowthControl. Indicates |
+ // the Isolate is initialized and enables tracing. |
+ void Init(Isolate* isolate); |
+ |
+ // Called when an object is allocated in the heap. |
+ void TraceAllocation(uword addr, intptr_t size); |
+ |
+ // Invoked after the snapshot is loaded at Isolate startup time. |
+ void TraceSnapshotAlloc(RawObject* obj, intptr_t size); |
+ |
+ // Rename to something like TraceAllocateZoneHandle (or whatever) |
+ void TraceAllocateZoneHandle(uword handle, uword zone_addr); |
+ |
+ // Invoked when a Zone block is deleted. |
+ void TraceDeleteZone(Zone* zone); |
+ |
+ // Invoked whenever the scoped handles are delelted. |
+ void TraceDeleteScopedHandles(); |
+ |
+ // Invoked when objects are coped from the from space to the to space |
+ // by the scavenger. |
+ void TraceCopy(uword from_addr, uword to_addr); |
+ |
+ // Invoked on each pointer in the object store. |
+ void TraceObjectStorePointer(uword addr); |
+ |
+ // Invoked when an object is promoted from the new space to the old space. |
+ void TracePromotion(uword old_addr, uword promoted_addr); |
+ |
+ // Invoked after a scavenge with the addressed range of from-space |
+ void TraceDeathRange(uword inclusive_start, uword exclusive_end); |
+ |
+ // Invoked whenever a class is registered in the class table. |
+ void TraceRegisterClass(const Class& cls); |
+ |
+ // Invoked when an address is swept. |
+ void TraceSweep(uword sweept_addr); |
+ |
+ // Invoked when storing value into origin, and value is an object. |
+ void TraceStoreIntoObject(uword origin_object_addr, |
+ uword slot_addr, |
+ uword value); |
+ |
+ // Invoked when starting a mark-sweep collection on old space |
+ void TraceMarkSweepStart(); |
+ |
+ // Invoked after finishing a mark sweep collection on old space. |
+ void TraceMarkSweepFinish(); |
+ |
+ // Initialize tracing globablly across the VM. Invidual isolates |
+ // will still have to initialized themselves when they are started. |
+ static void InitOnce(Dart_FileOpenCallback open_callback, |
+ Dart_FileWriteCallback write_callback, |
+ Dart_FileCloseCallback close_callback); |
+ |
+ // Returns true if tracign is enabled for the VM. |
+ static bool is_enabled() { return is_enabled_; } |
+ |
+ private: |
+ ObjectSet* CreateEmptyObjectSet() const; |
+ void ResizeObjectSet(); |
+ |
+ void TraceScopedHandle(uword handle); |
+ |
+ // A helper for PutRoots, called by HeapTraceVisitor. |
+ void TraceSingleRoot(uword root); |
+ |
+ // Invoked while tracing an allocation. |
+ void TraceRoots(Isolate* isolate); |
+ |
+ // Is the isolate we are tracing initialized? |
+ bool isolate_initialized_; |
+ |
+ void* output_stream_; |
+ |
+ ObjectSet object_set_; |
+ |
+ static Dart_FileOpenCallback open_callback_; |
+ static Dart_FileWriteCallback write_callback_; |
+ static Dart_FileCloseCallback close_callback_; |
+ |
+ static bool is_enabled_; |
+ |
+ friend class HeapTraceVisitor; |
+ friend class HeapTraceScopedHandleVisitor; |
+ friend class HeapTraceObjectStoreVisitor; |
+ friend class HeapTraceDebugObjectVisitor; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(HeapTrace); |
+}; |
+ |
+} // namespace dart |
+ |
+#endif // VM_HEAP_TRACE_H_ |