Chromium Code Reviews| 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..4945fad8b075b7edb7c6c4b4b40cc726a6b19e08 |
| --- /dev/null |
| +++ b/runtime/vm/heap_trace.h |
| @@ -0,0 +1,213 @@ |
| +// Copyright 2012 Google Inc. All Rights Reserved. |
| +// Author: nricci@google.com (Nathan Ricci) |
|
siva
2012/12/05 16:06:40
This copyright doesn't seem to be standard.
cshapiro
2012/12/08 03:23:08
It is standard, but not the standard we use. Fixe
|
| + |
| +#ifndef VM_HEAP_TRACE_H_ |
| +#define VM_HEAP_TRACE_H_ |
| + |
| +#include "include/dart_api.h" |
|
siva
2012/12/05 16:06:40
blank line.
cshapiro
2012/12/08 03:23:08
Done.
|
| +#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 |
| + }; |
|
siva
2012/12/05 16:06:40
These constants don't seem to be an increasing seq
cshapiro
2012/12/08 03:23:08
I think the enum makes it a bit more descriptive w
|
| + |
| + 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' |
| + }; |
|
siva
2012/12/05 16:06:40
Ditto.
|
| + |
| + 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() { return cursor_; } |
|
siva
2012/12/05 16:06:40
intptr_t Length() const { ... }
cshapiro
2012/12/08 03:23:08
Done.
|
| + |
| + const uint8_t* Buffer() { |
|
siva
2012/12/05 16:06:40
Ditto.
cshapiro
2012/12/08 03:23:08
Done.
|
| + ASSERT(cursor_ == N); |
| + return buffer_; |
| + } |
| + |
| + private: |
| + uint8_t buffer_[N]; |
| + intptr_t cursor_; |
| + HeapTrace* trace_; |
|
siva
2012/12/05 16:06:40
Missing DISALLOW stuff?
cshapiro
2012/12/08 03:23:08
Done.
|
| + }; |
| + |
| + 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 isoalte just before EnableGrowthControl. |
| + // Indicates the Isolate is initialized and enables tracing. |
| + void InitializeIsolateTracing(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 Isoalte 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 old_addr, uword forwarding_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(RawClass* klass); |
| + |
| + // 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 InitTracing(Dart_FileOpenCallback open_callback, |
| + Dart_FileWriteCallback write_callback, |
| + Dart_FileCloseCallback close_callback, |
| + const char* prefix); |
| + |
| + // Returns true if tracign is enabled for the VM. |
| + static bool is_enabled() { return tracing_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 isoalte 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 tracing_enabled_; |
| + static const char* file_name_prefix_; |
| + |
| + friend class HeapTraceVisitor; |
| + friend class HeapTraceScopedHandleVisitor; |
| + friend class HeapTraceObjectStoreVisitor; |
| + friend class HeapTraceDebugObjectVisitor; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(HeapTrace); |
| +}; |
| + |
| +} // namespace dart |
| + |
| +#endif // VM_HEAP_TRACE_H_ |