Add safepointing to the GC

BUG=
R=iposva@google.com

Review URL: https://codereview.chromium.org//1292353004 .
This commit is contained in:
Daniel Andersson 2015-08-25 18:20:27 -07:00
parent 6f197ac7ff
commit cab0033667
4 changed files with 29 additions and 7 deletions

View file

@ -10,6 +10,7 @@
#include "vm/lockers.h"
#include "vm/pages.h"
#include "vm/thread_pool.h"
#include "vm/thread_registry.h"
namespace dart {
@ -120,6 +121,7 @@ class SweeperTask : public ThreadPool::Task {
HeapPage* prev_page = NULL;
while (page != NULL) {
task_isolate_->thread_registry()->CheckSafepoint();
HeapPage* next_page = page->next();
ASSERT(page->type() == HeapPage::kData);
bool page_in_use = sweeper.SweepPage(page, freelist_, false);

View file

@ -11,6 +11,7 @@
#include "vm/lockers.h"
#include "vm/object.h"
#include "vm/os_thread.h"
#include "vm/thread_registry.h"
#include "vm/verified_memory.h"
#include "vm/virtual_memory.h"
@ -767,6 +768,12 @@ void PageSpace::MarkSweep(bool invoke_api_callbacks) {
}
set_tasks(1);
}
// Ensure that all threads for this isolate are at a safepoint (either stopped
// or in native code). If two threads are racing at this point, the loser
// will continue with its collection after waiting for the winner to complete.
// TODO(koda): Consider moving SafepointThreads into allocation failure/retry
// logic to avoid needless collections.
isolate->thread_registry()->SafepointThreads();
// Perform various cleanup that relies on no tasks interfering.
isolate->class_table()->FreeOldTables();
@ -907,6 +914,8 @@ void PageSpace::MarkSweep(bool invoke_api_callbacks) {
freelist_[HeapPage::kExecutable].Print();
}
isolate->thread_registry()->ResumeAllThreads();
// Done, reset the task count.
{
MonitorLocker ml(tasks_lock());

View file

@ -16,6 +16,7 @@
#include "vm/object_id_ring.h"
#include "vm/stack_frame.h"
#include "vm/store_buffer.h"
#include "vm/thread_registry.h"
#include "vm/verified_memory.h"
#include "vm/verifier.h"
#include "vm/visitor.h"
@ -799,10 +800,18 @@ void Scavenger::Scavenge() {
void Scavenger::Scavenge(bool invoke_api_callbacks) {
Isolate* isolate = heap_->isolate();
// Ensure that all threads for this isolate are at a safepoint (either stopped
// or in native code). If two threads are racing at this point, the loser
// will continue with its scavenge after waiting for the winner to complete.
// TODO(koda): Consider moving SafepointThreads into allocation failure/retry
// logic to avoid needless collections.
isolate->thread_registry()->SafepointThreads();
// Scavenging is not reentrant. Make sure that is the case.
ASSERT(!scavenging_);
scavenging_ = true;
Isolate* isolate = heap_->isolate();
PageSpace* page_space = heap_->old_space();
NoSafepointScope no_safepoints;
@ -861,6 +870,8 @@ void Scavenger::Scavenge(bool invoke_api_callbacks) {
// Done scavenging. Reset the marker.
ASSERT(scavenging_);
scavenging_ = false;
isolate->thread_registry()->ResumeAllThreads();
}

View file

@ -498,12 +498,12 @@ TEST_CASE(HelperAllocAndGC) {
Thread::PrepareForGC();
Dart::thread_pool()->Run(new AllocAndGCTask(isolate, &done_monitor, &done));
{
// Manually wait.
// TODO(koda): Replace with execution of Dart and/or VM code when GC
// actually safepoints everything.
MonitorLocker ml(&done_monitor);
while (!done) {
ml.Wait();
while (true) {
isolate->thread_registry()->CheckSafepoint();
MonitorLocker ml(&done_monitor);
if (done) {
break;
}
}
}
}