Don't use TLS for space iterators.

This is not only inherently slow, but it also forces the caller to enter an
Isolate before. Both is bad, so we have to do some heap plumbing.

BUG=v8:2531

Review URL: https://codereview.chromium.org/12217106

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13638 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
svenpanne@chromium.org 2013-02-11 13:02:20 +00:00
parent ec0b001543
commit 7b45ab9501
14 changed files with 159 additions and 125 deletions

View File

@ -2005,14 +2005,15 @@ void Debug::PrepareForBreakPoints() {
{
// We are going to iterate heap to find all functions without
// debug break slots.
isolate_->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask,
"preparing for breakpoints");
Heap* heap = isolate_->heap();
heap->CollectAllGarbage(Heap::kMakeHeapIterableMask,
"preparing for breakpoints");
// Ensure no GC in this scope as we are going to use gc_metadata
// field in the Code object to mark active functions.
AssertNoAllocation no_allocation;
Object* active_code_marker = isolate_->heap()->the_hole_value();
Object* active_code_marker = heap->the_hole_value();
CollectActiveFunctionsFromThread(isolate_,
isolate_->thread_local_top(),
@ -2026,7 +2027,7 @@ void Debug::PrepareForBreakPoints() {
// Scan the heap for all non-optimized functions which have no
// debug break slots and are not active or inlined into an active
// function and mark them for lazy compilation.
HeapIterator iterator;
HeapIterator iterator(heap);
HeapObject* obj = NULL;
while (((obj = iterator.next()) != NULL)) {
if (obj->IsJSFunction()) {
@ -2121,11 +2122,12 @@ Object* Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
int target_start_position = RelocInfo::kNoPosition;
Handle<JSFunction> target_function;
Handle<SharedFunctionInfo> target;
Heap* heap = isolate_->heap();
while (!done) {
{ // Extra scope for iterator and no-allocation.
isolate_->heap()->EnsureHeapIsIterable();
heap->EnsureHeapIsIterable();
AssertNoAllocation no_alloc_during_heap_iteration;
HeapIterator iterator;
HeapIterator iterator(heap);
for (HeapObject* obj = iterator.next();
obj != NULL; obj = iterator.next()) {
bool found_next_candidate = false;
@ -2185,9 +2187,7 @@ Object* Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
} // End for loop.
} // End no-allocation scope.
if (target.is_null()) {
return isolate_->heap()->undefined_value();
}
if (target.is_null()) return heap->undefined_value();
// There will be at least one break point when we are done.
has_break_points_ = true;
@ -2461,7 +2461,7 @@ void Debug::CreateScriptCache() {
// Scan heap for Script objects.
int count = 0;
HeapIterator iterator;
HeapIterator iterator(heap);
AssertNoAllocation no_allocation;
for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {

View File

@ -33,8 +33,8 @@
namespace v8 {
namespace internal {
HeapProfiler::HeapProfiler()
: snapshots_(new HeapSnapshotsCollection()),
HeapProfiler::HeapProfiler(Heap* heap)
: snapshots_(new HeapSnapshotsCollection(heap)),
next_snapshot_uid_(1) {
}
@ -45,15 +45,16 @@ HeapProfiler::~HeapProfiler() {
void HeapProfiler::ResetSnapshots() {
Heap* the_heap = heap();
delete snapshots_;
snapshots_ = new HeapSnapshotsCollection();
snapshots_ = new HeapSnapshotsCollection(the_heap);
}
void HeapProfiler::SetUp() {
Isolate* isolate = Isolate::Current();
if (isolate->heap_profiler() == NULL) {
isolate->set_heap_profiler(new HeapProfiler());
isolate->set_heap_profiler(new HeapProfiler(isolate->heap()));
}
}
@ -139,7 +140,7 @@ HeapSnapshot* HeapProfiler::TakeSnapshotImpl(
bool generation_completed = true;
switch (s_type) {
case HeapSnapshot::kFull: {
HeapSnapshotGenerator generator(result, control, resolver);
HeapSnapshotGenerator generator(result, control, resolver, heap());
generation_completed = generator.GenerateSnapshot();
break;
}

View File

@ -83,7 +83,7 @@ class HeapProfiler {
}
private:
HeapProfiler();
explicit HeapProfiler(Heap* heap);
~HeapProfiler();
HeapSnapshot* TakeSnapshotImpl(
const char* name,
@ -101,6 +101,8 @@ class HeapProfiler {
void StopHeapObjectsTrackingImpl();
SnapshotObjectId PushHeapObjectsStatsImpl(OutputStream* stream);
Heap* heap() const { return snapshots_->heap(); }
HeapSnapshotsCollection* snapshots_;
unsigned next_snapshot_uid_;
List<v8::HeapProfiler::WrapperInfoCallback> wrapper_callbacks_;

View File

@ -449,7 +449,7 @@ void Heap::GarbageCollectionPrologue() {
intptr_t Heap::SizeOfObjects() {
intptr_t total = 0;
AllSpaces spaces;
AllSpaces spaces(this);
for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
total += space->SizeOfObjects();
}
@ -458,7 +458,7 @@ intptr_t Heap::SizeOfObjects() {
void Heap::RepairFreeListsAfterBoot() {
PagedSpaces spaces;
PagedSpaces spaces(this);
for (PagedSpace* space = spaces.next();
space != NULL;
space = spaces.next()) {
@ -5537,9 +5537,10 @@ bool Heap::IdleGlobalGC() {
void Heap::Print() {
if (!HasBeenSetUp()) return;
isolate()->PrintStack();
AllSpaces spaces;
for (Space* space = spaces.next(); space != NULL; space = spaces.next())
AllSpaces spaces(this);
for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
space->Print();
}
}
@ -6167,7 +6168,7 @@ void Heap::RecordStats(HeapStats* stats, bool take_snapshot) {
*stats->os_error = OS::GetLastError();
isolate()->memory_allocator()->Available();
if (take_snapshot) {
HeapIterator iterator;
HeapIterator iterator(this);
for (HeapObject* obj = iterator.next();
obj != NULL;
obj = iterator.next()) {
@ -6412,7 +6413,7 @@ void Heap::TearDown() {
void Heap::Shrink() {
// Try to shrink all paged spaces.
PagedSpaces spaces;
PagedSpaces spaces(this);
for (PagedSpace* space = spaces.next();
space != NULL;
space = spaces.next()) {
@ -6485,19 +6486,19 @@ void Heap::PrintHandles() {
Space* AllSpaces::next() {
switch (counter_++) {
case NEW_SPACE:
return HEAP->new_space();
return heap_->new_space();
case OLD_POINTER_SPACE:
return HEAP->old_pointer_space();
return heap_->old_pointer_space();
case OLD_DATA_SPACE:
return HEAP->old_data_space();
return heap_->old_data_space();
case CODE_SPACE:
return HEAP->code_space();
return heap_->code_space();
case MAP_SPACE:
return HEAP->map_space();
return heap_->map_space();
case CELL_SPACE:
return HEAP->cell_space();
return heap_->cell_space();
case LO_SPACE:
return HEAP->lo_space();
return heap_->lo_space();
default:
return NULL;
}
@ -6507,15 +6508,15 @@ Space* AllSpaces::next() {
PagedSpace* PagedSpaces::next() {
switch (counter_++) {
case OLD_POINTER_SPACE:
return HEAP->old_pointer_space();
return heap_->old_pointer_space();
case OLD_DATA_SPACE:
return HEAP->old_data_space();
return heap_->old_data_space();
case CODE_SPACE:
return HEAP->code_space();
return heap_->code_space();
case MAP_SPACE:
return HEAP->map_space();
return heap_->map_space();
case CELL_SPACE:
return HEAP->cell_space();
return heap_->cell_space();
default:
return NULL;
}
@ -6526,26 +6527,28 @@ PagedSpace* PagedSpaces::next() {
OldSpace* OldSpaces::next() {
switch (counter_++) {
case OLD_POINTER_SPACE:
return HEAP->old_pointer_space();
return heap_->old_pointer_space();
case OLD_DATA_SPACE:
return HEAP->old_data_space();
return heap_->old_data_space();
case CODE_SPACE:
return HEAP->code_space();
return heap_->code_space();
default:
return NULL;
}
}
SpaceIterator::SpaceIterator()
: current_space_(FIRST_SPACE),
SpaceIterator::SpaceIterator(Heap* heap)
: heap_(heap),
current_space_(FIRST_SPACE),
iterator_(NULL),
size_func_(NULL) {
}
SpaceIterator::SpaceIterator(HeapObjectCallback size_func)
: current_space_(FIRST_SPACE),
SpaceIterator::SpaceIterator(Heap* heap, HeapObjectCallback size_func)
: heap_(heap),
current_space_(FIRST_SPACE),
iterator_(NULL),
size_func_(size_func) {
}
@ -6585,25 +6588,26 @@ ObjectIterator* SpaceIterator::CreateIterator() {
switch (current_space_) {
case NEW_SPACE:
iterator_ = new SemiSpaceIterator(HEAP->new_space(), size_func_);
iterator_ = new SemiSpaceIterator(heap_->new_space(), size_func_);
break;
case OLD_POINTER_SPACE:
iterator_ = new HeapObjectIterator(HEAP->old_pointer_space(), size_func_);
iterator_ =
new HeapObjectIterator(heap_->old_pointer_space(), size_func_);
break;
case OLD_DATA_SPACE:
iterator_ = new HeapObjectIterator(HEAP->old_data_space(), size_func_);
iterator_ = new HeapObjectIterator(heap_->old_data_space(), size_func_);
break;
case CODE_SPACE:
iterator_ = new HeapObjectIterator(HEAP->code_space(), size_func_);
iterator_ = new HeapObjectIterator(heap_->code_space(), size_func_);
break;
case MAP_SPACE:
iterator_ = new HeapObjectIterator(HEAP->map_space(), size_func_);
iterator_ = new HeapObjectIterator(heap_->map_space(), size_func_);
break;
case CELL_SPACE:
iterator_ = new HeapObjectIterator(HEAP->cell_space(), size_func_);
iterator_ = new HeapObjectIterator(heap_->cell_space(), size_func_);
break;
case LO_SPACE:
iterator_ = new LargeObjectIterator(HEAP->lo_space(), size_func_);
iterator_ = new LargeObjectIterator(heap_->lo_space(), size_func_);
break;
}
@ -6674,15 +6678,18 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
};
HeapIterator::HeapIterator()
: filtering_(HeapIterator::kNoFiltering),
HeapIterator::HeapIterator(Heap* heap)
: heap_(heap),
filtering_(HeapIterator::kNoFiltering),
filter_(NULL) {
Init();
}
HeapIterator::HeapIterator(HeapIterator::HeapObjectsFiltering filtering)
: filtering_(filtering),
HeapIterator::HeapIterator(Heap* heap,
HeapIterator::HeapObjectsFiltering filtering)
: heap_(heap),
filtering_(filtering),
filter_(NULL) {
Init();
}
@ -6695,7 +6702,7 @@ HeapIterator::~HeapIterator() {
void HeapIterator::Init() {
// Start the iteration.
space_iterator_ = new SpaceIterator;
space_iterator_ = new SpaceIterator(heap_);
switch (filtering_) {
case kFilterUnreachable:
filter_ = new UnreachableObjectsFilter;
@ -6960,9 +6967,9 @@ void Heap::TracePathToGlobal() {
#endif
static intptr_t CountTotalHolesSize() {
static intptr_t CountTotalHolesSize(Heap* heap) {
intptr_t holes_size = 0;
OldSpaces spaces;
OldSpaces spaces(heap);
for (OldSpace* space = spaces.next();
space != NULL;
space = spaces.next()) {
@ -6998,7 +7005,7 @@ GCTracer::GCTracer(Heap* heap,
scopes_[i] = 0;
}
in_free_list_or_wasted_before_gc_ = CountTotalHolesSize();
in_free_list_or_wasted_before_gc_ = CountTotalHolesSize(heap);
allocated_since_last_gc_ =
heap_->SizeOfObjects() - heap_->alive_after_last_gc_;
@ -7125,7 +7132,7 @@ GCTracer::~GCTracer() {
PrintF("total_size_after=%" V8_PTR_PREFIX "d ", heap_->SizeOfObjects());
PrintF("holes_size_before=%" V8_PTR_PREFIX "d ",
in_free_list_or_wasted_before_gc_);
PrintF("holes_size_after=%" V8_PTR_PREFIX "d ", CountTotalHolesSize());
PrintF("holes_size_after=%" V8_PTR_PREFIX "d ", CountTotalHolesSize(heap_));
PrintF("allocated=%" V8_PTR_PREFIX "d ", allocated_since_last_gc_);
PrintF("promoted=%" V8_PTR_PREFIX "d ", promoted_objects_size_);

View File

@ -2339,37 +2339,40 @@ class VerifyPointersVisitor: public ObjectVisitor {
};
// Space iterator for iterating over all spaces of the heap.
// Returns each space in turn, and null when it is done.
// Space iterator for iterating over all spaces of the heap. Returns each space
// in turn, and null when it is done.
class AllSpaces BASE_EMBEDDED {
public:
explicit AllSpaces(Heap* heap) : heap_(heap), counter_(FIRST_SPACE) {}
Space* next();
AllSpaces() { counter_ = FIRST_SPACE; }
private:
Heap* heap_;
int counter_;
};
// Space iterator for iterating over all old spaces of the heap: Old pointer
// space, old data space and code space.
// Returns each space in turn, and null when it is done.
// space, old data space and code space. Returns each space in turn, and null
// when it is done.
class OldSpaces BASE_EMBEDDED {
public:
explicit OldSpaces(Heap* heap) : heap_(heap), counter_(OLD_POINTER_SPACE) {}
OldSpace* next();
OldSpaces() { counter_ = OLD_POINTER_SPACE; }
private:
Heap* heap_;
int counter_;
};
// Space iterator for iterating over all the paged spaces of the heap:
// Map space, old pointer space, old data space, code space and cell space.
// Returns each space in turn, and null when it is done.
// Space iterator for iterating over all the paged spaces of the heap: Map
// space, old pointer space, old data space, code space and cell space. Returns
// each space in turn, and null when it is done.
class PagedSpaces BASE_EMBEDDED {
public:
explicit PagedSpaces(Heap* heap) : heap_(heap), counter_(OLD_POINTER_SPACE) {}
PagedSpace* next();
PagedSpaces() { counter_ = OLD_POINTER_SPACE; }
private:
Heap* heap_;
int counter_;
};
@ -2379,8 +2382,8 @@ class PagedSpaces BASE_EMBEDDED {
// returned object iterators is handled by the space iterator.
class SpaceIterator : public Malloced {
public:
SpaceIterator();
explicit SpaceIterator(HeapObjectCallback size_func);
explicit SpaceIterator(Heap* heap);
SpaceIterator(Heap* heap, HeapObjectCallback size_func);
virtual ~SpaceIterator();
bool has_next();
@ -2389,6 +2392,7 @@ class SpaceIterator : public Malloced {
private:
ObjectIterator* CreateIterator();
Heap* heap_;
int current_space_; // from enum AllocationSpace.
ObjectIterator* iterator_; // object iterator for the current space.
HeapObjectCallback size_func_;
@ -2413,8 +2417,8 @@ class HeapIterator BASE_EMBEDDED {
kFilterUnreachable
};
HeapIterator();
explicit HeapIterator(HeapObjectsFiltering filtering);
explicit HeapIterator(Heap* heap);
HeapIterator(Heap* heap, HeapObjectsFiltering filtering);
~HeapIterator();
HeapObject* next();
@ -2427,6 +2431,7 @@ class HeapIterator BASE_EMBEDDED {
void Shutdown();
HeapObject* NextObject();
Heap* heap_;
HeapObjectsFiltering filtering_;
HeapObjectsFilter* filter_;
// Space iterator for iterating all the spaces.

View File

@ -1047,10 +1047,11 @@ static void ReplaceCodeObject(Handle<Code> original,
// Since we are not in an incremental marking phase we can write pointers
// to code objects (that are never in new space) without worrying about
// write barriers.
HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask,
Heap* heap = original->GetHeap();
heap->CollectAllGarbage(Heap::kMakeHeapIterableMask,
"liveedit.cc ReplaceCodeObject");
ASSERT(!HEAP->InNewSpace(*substitution));
ASSERT(!heap->InNewSpace(*substitution));
AssertNoAllocation no_allocations_please;
@ -1059,11 +1060,11 @@ static void ReplaceCodeObject(Handle<Code> original,
// Iterate over all roots. Stack frames may have pointer into original code,
// so temporary replace the pointers with offset numbers
// in prologue/epilogue.
HEAP->IterateRoots(&visitor, VISIT_ALL);
heap->IterateRoots(&visitor, VISIT_ALL);
// Now iterate over all pointers of all objects, including code_target
// implicit pointers.
HeapIterator iterator;
HeapIterator iterator(heap);
for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
obj->Iterate(&visitor);
}
@ -1129,7 +1130,7 @@ class LiteralFixer {
Visitor* visitor) {
AssertNoAllocation no_allocations_please;
HeapIterator iterator;
HeapIterator iterator(shared_info->GetHeap());
for (HeapObject* obj = iterator.next(); obj != NULL;
obj = iterator.next()) {
if (obj->IsJSFunction()) {

View File

@ -1394,9 +1394,10 @@ class EnumerateOptimizedFunctionsVisitor: public OptimizedFunctionVisitor {
};
static int EnumerateCompiledFunctions(Handle<SharedFunctionInfo>* sfis,
static int EnumerateCompiledFunctions(Heap* heap,
Handle<SharedFunctionInfo>* sfis,
Handle<Code>* code_objects) {
HeapIterator iterator;
HeapIterator iterator(heap);
AssertNoAllocation no_alloc;
int compiled_funcs_count = 0;
@ -1562,9 +1563,10 @@ void Logger::LowLevelLogWriteBytes(const char* bytes, int size) {
void Logger::LogCodeObjects() {
HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask,
Heap* heap = HEAP;
heap->CollectAllGarbage(Heap::kMakeHeapIterableMask,
"Logger::LogCodeObjects");
HeapIterator iterator;
HeapIterator iterator(heap);
AssertNoAllocation no_alloc;
for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
if (obj->IsCode()) LogCodeObject(obj);
@ -1618,13 +1620,14 @@ void Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared,
void Logger::LogCompiledFunctions() {
HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask,
Heap* heap = HEAP;
heap->CollectAllGarbage(Heap::kMakeHeapIterableMask,
"Logger::LogCompiledFunctions");
HandleScope scope;
const int compiled_funcs_count = EnumerateCompiledFunctions(NULL, NULL);
const int compiled_funcs_count = EnumerateCompiledFunctions(heap, NULL, NULL);
ScopedVector< Handle<SharedFunctionInfo> > sfis(compiled_funcs_count);
ScopedVector< Handle<Code> > code_objects(compiled_funcs_count);
EnumerateCompiledFunctions(sfis.start(), code_objects.start());
EnumerateCompiledFunctions(heap, sfis.start(), code_objects.start());
// During iteration, there can be heap allocation due to
// GetScriptLineNumber call.
@ -1638,9 +1641,10 @@ void Logger::LogCompiledFunctions() {
void Logger::LogAccessorCallbacks() {
HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask,
Heap* heap = HEAP;
heap->CollectAllGarbage(Heap::kMakeHeapIterableMask,
"Logger::LogAccessorCallbacks");
HeapIterator iterator;
HeapIterator iterator(heap);
AssertNoAllocation no_alloc;
for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
if (!obj->IsAccessorInfo()) continue;

View File

@ -901,7 +901,7 @@ void MarkCompactCollector::Prepare(GCTracer* tracer) {
StartCompaction(NON_INCREMENTAL_COMPACTION);
}
PagedSpaces spaces;
PagedSpaces spaces(heap());
for (PagedSpace* space = spaces.next();
space != NULL;
space = spaces.next()) {

View File

@ -1095,7 +1095,7 @@ template <size_t ptr_size> struct SnapshotSizeConstants;
template <> struct SnapshotSizeConstants<4> {
static const int kExpectedHeapGraphEdgeSize = 12;
static const int kExpectedHeapEntrySize = 24;
static const int kExpectedHeapSnapshotsCollectionSize = 96;
static const int kExpectedHeapSnapshotsCollectionSize = 100;
static const int kExpectedHeapSnapshotSize = 136;
static const size_t kMaxSerializableSnapshotRawSize = 256 * MB;
};
@ -1103,7 +1103,7 @@ template <> struct SnapshotSizeConstants<4> {
template <> struct SnapshotSizeConstants<8> {
static const int kExpectedHeapGraphEdgeSize = 24;
static const int kExpectedHeapEntrySize = 32;
static const int kExpectedHeapSnapshotsCollectionSize = 144;
static const int kExpectedHeapSnapshotsCollectionSize = 152;
static const int kExpectedHeapSnapshotSize = 168;
static const uint64_t kMaxSerializableSnapshotRawSize =
static_cast<uint64_t>(6000) * MB;
@ -1286,9 +1286,10 @@ const SnapshotObjectId HeapObjectsMap::kFirstAvailableObjectId =
HeapObjectsMap::kGcRootsFirstSubrootId +
VisitorSynchronization::kNumberOfSyncTags * HeapObjectsMap::kObjectIdStep;
HeapObjectsMap::HeapObjectsMap()
HeapObjectsMap::HeapObjectsMap(Heap* heap)
: next_id_(kFirstAvailableObjectId),
entries_map_(AddressesMatch) {
entries_map_(AddressesMatch),
heap_(heap) {
// This dummy element solves a problem with entries_map_.
// When we do lookup in HashMap we see no difference between two cases:
// it has an entry with NULL as the value or it has created
@ -1366,7 +1367,7 @@ void HeapObjectsMap::StopHeapObjectsTracking() {
void HeapObjectsMap::UpdateHeapObjectsMap() {
HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask,
"HeapSnapshotsCollection::UpdateHeapObjectsMap");
HeapIterator iterator;
HeapIterator iterator(heap_);
for (HeapObject* obj = iterator.next();
obj != NULL;
obj = iterator.next()) {
@ -1474,10 +1475,11 @@ size_t HeapObjectsMap::GetUsedMemorySize() const {
}
HeapSnapshotsCollection::HeapSnapshotsCollection()
HeapSnapshotsCollection::HeapSnapshotsCollection(Heap* heap)
: is_tracking_objects_(false),
snapshots_uids_(HeapSnapshotsMatch),
token_enumerator_(new TokenEnumerator()) {
token_enumerator_(new TokenEnumerator()),
ids_(heap) {
}
@ -1538,7 +1540,7 @@ Handle<HeapObject> HeapSnapshotsCollection::FindHeapObjectById(
"HeapSnapshotsCollection::FindHeapObjectById");
AssertNoAllocation no_allocation;
HeapObject* object = NULL;
HeapIterator iterator(HeapIterator::kFilterUnreachable);
HeapIterator iterator(heap(), HeapIterator::kFilterUnreachable);
// Make sure that object with the given id is still reachable.
for (HeapObject* obj = iterator.next();
obj != NULL;
@ -2428,7 +2430,7 @@ class RootsReferencesExtractor : public ObjectVisitor {
bool V8HeapExplorer::IterateAndExtractReferences(
SnapshotFillerInterface* filler) {
HeapIterator iterator(HeapIterator::kFilterUnreachable);
HeapIterator iterator(heap_, HeapIterator::kFilterUnreachable);
filler_ = filler;
bool interrupted = false;
@ -3079,11 +3081,13 @@ class SnapshotFiller : public SnapshotFillerInterface {
HeapSnapshotGenerator::HeapSnapshotGenerator(
HeapSnapshot* snapshot,
v8::ActivityControl* control,
v8::HeapProfiler::ObjectNameResolver* resolver)
v8::HeapProfiler::ObjectNameResolver* resolver,
Heap* heap)
: snapshot_(snapshot),
control_(control),
v8_heap_explorer_(snapshot_, this, resolver),
dom_explorer_(snapshot_, this) {
dom_explorer_(snapshot_, this),
heap_(heap) {
}
@ -3154,7 +3158,7 @@ bool HeapSnapshotGenerator::ProgressReport(bool force) {
void HeapSnapshotGenerator::SetProgressTotal(int iterations_count) {
if (control_ == NULL) return;
HeapIterator iterator(HeapIterator::kFilterUnreachable);
HeapIterator iterator(heap_, HeapIterator::kFilterUnreachable);
progress_total_ = iterations_count * (
v8_heap_explorer_.EstimateObjectsCount(&iterator) +
dom_explorer_.EstimateObjectsCount());

View File

@ -640,7 +640,9 @@ class HeapSnapshot {
class HeapObjectsMap {
public:
HeapObjectsMap();
explicit HeapObjectsMap(Heap* heap);
Heap* heap() const { return heap_; }
void SnapshotGenerationFinished();
SnapshotObjectId FindEntry(Address addr);
@ -699,6 +701,7 @@ class HeapObjectsMap {
HashMap entries_map_;
List<EntryInfo> entries_;
List<TimeInterval> time_intervals_;
Heap* heap_;
DISALLOW_COPY_AND_ASSIGN(HeapObjectsMap);
};
@ -706,9 +709,11 @@ class HeapObjectsMap {
class HeapSnapshotsCollection {
public:
HeapSnapshotsCollection();
explicit HeapSnapshotsCollection(Heap* heap);
~HeapSnapshotsCollection();
Heap* heap() const { return ids_.heap(); }
bool is_tracking_objects() { return is_tracking_objects_; }
SnapshotObjectId PushHeapObjectsStats(OutputStream* stream) {
return ids_.PushHeapObjectsStats(stream);
@ -1025,7 +1030,8 @@ class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface {
public:
HeapSnapshotGenerator(HeapSnapshot* snapshot,
v8::ActivityControl* control,
v8::HeapProfiler::ObjectNameResolver* resolver);
v8::HeapProfiler::ObjectNameResolver* resolver,
Heap* heap);
bool GenerateSnapshot();
private:
@ -1043,6 +1049,7 @@ class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface {
// Used during snapshot generation.
int progress_counter_;
int progress_total_;
Heap* heap_;
DISALLOW_COPY_AND_ASSIGN(HeapSnapshotGenerator);
};

View File

@ -12446,29 +12446,30 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) {
// Get the number of referencing objects.
int count;
HeapIterator heap_iterator;
Heap* heap = isolate->heap();
HeapIterator heap_iterator(heap);
count = DebugReferencedBy(&heap_iterator,
target, instance_filter, max_references,
NULL, 0, arguments_function);
// Allocate an array to hold the result.
Object* object;
{ MaybeObject* maybe_object = isolate->heap()->AllocateFixedArray(count);
{ MaybeObject* maybe_object = heap->AllocateFixedArray(count);
if (!maybe_object->ToObject(&object)) return maybe_object;
}
FixedArray* instances = FixedArray::cast(object);
// Fill the referencing objects.
// AllocateFixedArray above does not make the heap non-iterable.
ASSERT(HEAP->IsHeapIterable());
HeapIterator heap_iterator2;
ASSERT(heap->IsHeapIterable());
HeapIterator heap_iterator2(heap);
count = DebugReferencedBy(&heap_iterator2,
target, instance_filter, max_references,
instances, count, arguments_function);
// Return result as JS array.
Object* result;
MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
MaybeObject* maybe_result = heap->AllocateJSObject(
isolate->context()->native_context()->array_function());
if (!maybe_result->ToObject(&result)) return maybe_result;
return JSArray::cast(result)->SetContent(instances);
@ -12514,8 +12515,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
ASSERT(args.length() == 2);
// First perform a full GC in order to avoid dead objects.
isolate->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask,
"%DebugConstructedBy");
Heap* heap = isolate->heap();
heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
// Check parameters.
CONVERT_ARG_CHECKED(JSFunction, constructor, 0);
@ -12524,7 +12525,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
// Get the number of referencing objects.
int count;
HeapIterator heap_iterator;
HeapIterator heap_iterator(heap);
count = DebugConstructedBy(&heap_iterator,
constructor,
max_references,
@ -12533,14 +12534,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
// Allocate an array to hold the result.
Object* object;
{ MaybeObject* maybe_object = isolate->heap()->AllocateFixedArray(count);
{ MaybeObject* maybe_object = heap->AllocateFixedArray(count);
if (!maybe_object->ToObject(&object)) return maybe_object;
}
FixedArray* instances = FixedArray::cast(object);
ASSERT(HEAP->IsHeapIterable());
// Fill the referencing objects.
HeapIterator heap_iterator2;
HeapIterator heap_iterator2(heap);
count = DebugConstructedBy(&heap_iterator2,
constructor,
max_references,
@ -12550,7 +12551,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
// Return result as JS array.
Object* result;
{ MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
isolate->context()->native_context()->array_function());
isolate->context()->native_context()->array_function());
if (!maybe_result->ToObject(&result)) return maybe_result;
}
return JSArray::cast(result)->SetContent(instances);
@ -12677,19 +12678,20 @@ RUNTIME_FUNCTION(MaybeObject*,
Handle<FixedArray> array;
array = isolate->factory()->NewFixedArray(kBufferSize);
int number;
Heap* heap = isolate->heap();
{
isolate->heap()->EnsureHeapIsIterable();
heap->EnsureHeapIsIterable();
AssertNoAllocation no_allocations;
HeapIterator heap_iterator;
HeapIterator heap_iterator(heap);
Script* scr = *script;
FixedArray* arr = *array;
number = FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
}
if (number > kBufferSize) {
array = isolate->factory()->NewFixedArray(number);
isolate->heap()->EnsureHeapIsIterable();
heap->EnsureHeapIsIterable();
AssertNoAllocation no_allocations;
HeapIterator heap_iterator;
HeapIterator heap_iterator(heap);
Script* scr = *script;
FixedArray* arr = *array;
FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
@ -13026,9 +13028,10 @@ static Handle<Object> Runtime_GetScriptFromScriptName(
// Scan the heap for Script objects to find the script with the requested
// script data.
Handle<Script> script;
script_name->GetHeap()->EnsureHeapIsIterable();
Heap* heap = script_name->GetHeap();
heap->EnsureHeapIsIterable();
AssertNoAllocation no_allocation_during_heap_iteration;
HeapIterator iterator;
HeapIterator iterator(heap);
HeapObject* obj = NULL;
while (script.is_null() && ((obj = iterator.next()) != NULL)) {
// If a script is found check if it has the script data requested.

View File

@ -11283,7 +11283,7 @@ THREADED_TEST(LockUnlockLock) {
static int GetGlobalObjectsCount() {
i::Isolate::Current()->heap()->EnsureHeapIsIterable();
int count = 0;
i::HeapIterator it;
i::HeapIterator it(HEAP);
for (i::HeapObject* object = it.next(); object != NULL; object = it.next())
if (object->IsJSGlobalObject()) count++;
return count;

View File

@ -426,7 +426,7 @@ void CheckDebuggerUnloaded(bool check_functions) {
HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask);
// Iterate the head and check that there are no debugger related objects left.
HeapIterator iterator;
HeapIterator iterator(HEAP);
for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
CHECK(!obj->IsDebugInfo());
CHECK(!obj->IsBreakPointInfo());

View File

@ -820,10 +820,10 @@ TEST(StringAllocation) {
}
static int ObjectsFoundInHeap(Handle<Object> objs[], int size) {
static int ObjectsFoundInHeap(Heap* heap, Handle<Object> objs[], int size) {
// Count the number of objects found in the heap.
int found_count = 0;
HeapIterator iterator;
HeapIterator iterator(heap);
for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
for (int i = 0; i < size; i++) {
if (*objs[i] == obj) {
@ -869,7 +869,7 @@ TEST(Iteration) {
objs[next_objs_index++] = Handle<Map>(HeapObject::cast(*objs[0])->map());
CHECK_EQ(objs_count, next_objs_index);
CHECK_EQ(objs_count, ObjectsFoundInHeap(objs, objs_count));
CHECK_EQ(objs_count, ObjectsFoundInHeap(HEAP, objs, objs_count));
}
@ -1465,7 +1465,7 @@ TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
InitializeVM();
HEAP->EnsureHeapIsIterable();
intptr_t size_of_objects_1 = HEAP->SizeOfObjects();
HeapIterator iterator;
HeapIterator iterator(HEAP);
intptr_t size_of_objects_2 = 0;
for (HeapObject* obj = iterator.next();
obj != NULL;
@ -1586,7 +1586,7 @@ TEST(CollectingAllAvailableGarbageShrinksNewSpace) {
static int NumberOfGlobalObjects() {
int count = 0;
HeapIterator iterator;
HeapIterator iterator(HEAP);
for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
if (obj->IsGlobalObject()) count++;
}