49f6f9f36d
Review URL: https://codereview.chromium.org//11428067 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@16199 260f80e4-7a28-3924-810f-c04153c831b5
214 lines
6.3 KiB
C++
214 lines
6.3 KiB
C++
// 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_
|