Enable iterating over roots from helper threads by moving stack walking.

This will be needed for helper threads to invoke GC.

BUG=
R=johnmccutchan@google.com

Review URL: https://codereview.chromium.org//1282423003 .
This commit is contained in:
Daniel Andersson 2015-08-11 09:41:06 -07:00
parent ba7bfcd47d
commit faaf60801f
7 changed files with 27 additions and 19 deletions

View file

@ -231,12 +231,15 @@ HeapIterationScope::HeapIterationScope()
MonitorLocker ml(old_space_->tasks_lock());
#if defined(DEBUG)
// We currently don't support nesting of HeapIterationScopes.
ASSERT(!old_space_->is_iterating_);
old_space_->is_iterating_ = true;
ASSERT(old_space_->iterating_thread_ != thread());
#endif
while (old_space_->tasks() > 0) {
ml.Wait();
}
#if defined(DEBUG)
ASSERT(old_space_->iterating_thread_ == NULL);
old_space_->iterating_thread_ = thread();
#endif
old_space_->set_tasks(1);
}
@ -244,8 +247,8 @@ HeapIterationScope::HeapIterationScope()
HeapIterationScope::~HeapIterationScope() {
MonitorLocker ml(old_space_->tasks_lock());
#if defined(DEBUG)
ASSERT(old_space_->is_iterating_);
old_space_->is_iterating_ = false;
ASSERT(old_space_->iterating_thread_ == thread());
old_space_->iterating_thread_ = NULL;
#endif
ASSERT(old_space_->tasks() == 1);
old_space_->set_tasks(0);

View file

@ -1598,14 +1598,6 @@ void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor,
// Visit objects in isolate specific handles area.
reusable_handles_.VisitObjectPointers(visitor);
// Iterate over all the stack frames and visit objects on the stack.
StackFrameIterator frames_iterator(validate_frames);
StackFrame* frame = frames_iterator.NextFrame();
while (frame != NULL) {
frame->VisitObjectPointers(visitor);
frame = frames_iterator.NextFrame();
}
// Visit the dart api state for all local and persistent handles.
if (api_state() != NULL) {
api_state()->VisitObjectPointers(visitor, visit_prologue_weak_handles);

View file

@ -161,7 +161,7 @@ PageSpace::PageSpace(Heap* heap,
tasks_lock_(new Monitor()),
tasks_(0),
#if defined(DEBUG)
is_iterating_(false),
iterating_thread_(NULL),
#endif
page_space_controller_(heap,
FLAG_old_gen_growth_space_ratio,

View file

@ -427,7 +427,7 @@ class PageSpace {
Monitor* tasks_lock_;
intptr_t tasks_;
#if defined(DEBUG)
bool is_iterating_;
Thread* iterating_thread_;
#endif
PageSpaceController page_space_controller_;

View file

@ -262,6 +262,7 @@ CACHED_CONSTANTS_LIST(DECLARE_MEMBERS)
friend class ApiZone;
friend class Isolate;
friend class StackZone;
friend class ThreadRegistry;
DISALLOW_COPY_AND_ASSIGN(Thread);
};

View file

@ -9,6 +9,7 @@
#include "vm/growable_array.h"
#include "vm/isolate.h"
#include "vm/lockers.h"
#include "vm/stack_frame.h"
#include "vm/thread.h"
namespace dart {
@ -118,9 +119,19 @@ class ThreadRegistry {
MonitorLocker ml(monitor_);
for (int i = 0; i < entries_.length(); ++i) {
const Entry& entry = entries_[i];
Zone* zone = entry.scheduled ? entry.thread->zone() : entry.state.zone;
if (zone != NULL) {
zone->VisitObjectPointers(visitor);
const Thread::State& state =
entry.scheduled ? entry.thread->state_ : entry.state;
if (state.zone != NULL) {
state.zone->VisitObjectPointers(visitor);
}
// Iterate over all the stack frames and visit objects on the stack.
uword efi = state.top_exit_frame_info;
if (efi == 0) continue;
StackFrameIterator frames_iterator(efi, false);
StackFrame* frame = frames_iterator.NextFrame();
while (frame != NULL) {
frame->VisitObjectPointers(visitor);
frame = frames_iterator.NextFrame();
}
}
}

View file

@ -133,8 +133,9 @@ class TaskWithZoneAllocation : public ThreadPool::Task {
EXPECT(smi.Value() == unique_smi);
ObjectCounter counter(isolate_, &smi);
// Ensure that our particular zone is visited.
// TODO(koda): Remove "->thread_registry()" after updating stack walker.
isolate_->thread_registry()->VisitObjectPointers(&counter);
isolate_->IterateObjectPointers(&counter,
/* visit_prologue_weak_handles = */ true,
/* validate_frames = */ true);
EXPECT_EQ(1, counter.count());
char* unique_chars = zone->PrintToString("unique_str_%" Pd, id_);