| 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_
|
|
|