Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(103)

Unified Diff: runtime/vm/compiler.cc

Issue 1433243003: Background compilation work: (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: d Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/flow_graph.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/compiler.cc
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 5530e06b5a477e83296899893239ace29bba7d8a..8bcde79aa8fdc34149db4dfc9968767e4529b058 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -777,6 +777,7 @@ static bool CompileParsedFunctionHelper(CompilationPipeline* pipeline,
if (optimized) {
if (result != NULL) {
+ // Background compilation, store compilation result in 'result'.
ASSERT(!Thread::Current()->IsMutatorThread());
// Do not install code, but return it instead.
// Since code dependencies (CHA, fields) are defined eagerly,
@@ -798,22 +799,35 @@ static bool CompileParsedFunctionHelper(CompilationPipeline* pipeline,
function.InstallOptimizedCode(code, is_osr);
}
- // TODO(srdjan): In background compilation, verify that CHA and field
- // guards have not been invalidated in the meantime.
// Register code with the classes it depends on because of CHA and
// fields it depends on because of store guards, unless we cannot
// deopt.
if (Compiler::allow_recompilation()) {
- for (intptr_t i = 0;
- i < thread->cha()->leaf_classes().length();
- ++i) {
- thread->cha()->leaf_classes()[i]->RegisterCHACode(code);
- }
- for (intptr_t i = 0;
- i < flow_graph->guarded_fields()->length();
- i++) {
- const Field* field = (*flow_graph->guarded_fields())[i];
- field->RegisterDependentCode(code);
+ if (result != NULL) {
+ // Background compilation: delay registering code until we are
+ // in the MutatorThread.
+ result->SetLeafClasses(thread->cha()->leaf_classes());
+ result->SetGuardedFields(*flow_graph->guarded_fields());
+ result->SetDeoptimizeDependentFields(
+ flow_graph->deoptimize_dependent_code());
+ } else {
+ for (intptr_t i = 0;
+ i < thread->cha()->leaf_classes().length();
+ ++i) {
+ thread->cha()->leaf_classes()[i]->RegisterCHACode(code);
+ }
+ for (intptr_t i = 0;
+ i < flow_graph->guarded_fields()->length();
+ i++) {
+ const Field* field = (*flow_graph->guarded_fields())[i];
+ field->RegisterDependentCode(code);
+ }
+ for (intptr_t i = 0;
+ i < flow_graph->deoptimize_dependent_code().length();
+ i++) {
+ const Field* field = flow_graph->deoptimize_dependent_code()[i];
+ field->DeoptimizeDependentCode();
+ }
}
}
} else { // not optimized.
@@ -1481,6 +1495,9 @@ class QueueElement {
explicit QueueElement(const Function& function)
: next_(NULL),
obj_(function.raw()),
+ leaf_classes_(Array::null()),
+ guarded_fields_(Array::null()),
+ deoptimize_dependent_fields_(Array::null()),
cha_invalidation_gen_(Isolate::kInvalidGen),
field_invalidation_gen_(Isolate::kInvalidGen),
prefix_invalidation_gen_(Isolate::kInvalidGen) {
@@ -1495,6 +1512,12 @@ class QueueElement {
RawFunction* Function() const { return Function::RawCast(obj_); }
RawCode* Code() const { return Code::RawCast(obj_); }
+ RawArray* leaf_classes() const { return leaf_classes_; }
+ RawArray* guarded_fields() const { return guarded_fields_; }
+ RawArray* deoptimize_dependent_fields() const {
+ return deoptimize_dependent_fields_;
+ }
+
uint32_t cha_invalidation_gen() const { return cha_invalidation_gen_; }
uint32_t field_invalidation_gen() const { return field_invalidation_gen_; }
uint32_t prefix_invalidation_gen() const { return prefix_invalidation_gen_; }
@@ -1502,12 +1525,27 @@ class QueueElement {
void set_next(QueueElement* elem) { next_ = elem; }
QueueElement* next() const { return next_; }
- RawObject** obj_ptr() { return &obj_; }
RawObject* obj() const { return obj_; }
+ RawObject** obj_ptr() { return &obj_; }
+
+ RawObject** leaf_classses_ptr() {
+ return reinterpret_cast<RawObject**>(&leaf_classes_);
+ }
+
+ RawObject** guarded_fields_ptr() {
+ return reinterpret_cast<RawObject**>(&guarded_fields_);
+ }
+
+ RawObject** deoptimize_dependent_fields_ptr() {
+ return reinterpret_cast<RawObject**>(&deoptimize_dependent_fields_);
+ }
void SetFromResult(const BackgroundCompilationResult& value) {
ASSERT(!value.result_code().IsNull());
obj_ = value.result_code().raw();
+ leaf_classes_ = value.leaf_classes().raw();
+ guarded_fields_ = value.guarded_fields().raw();
+ deoptimize_dependent_fields_ = value.deoptimize_dependent_fields().raw();
cha_invalidation_gen_ = value.cha_invalidation_gen();
field_invalidation_gen_ = value.field_invalidation_gen();
prefix_invalidation_gen_ = value.prefix_invalidation_gen();
@@ -1517,6 +1555,9 @@ class QueueElement {
QueueElement* next_;
RawObject* obj_; // Code or Function.
+ RawArray* leaf_classes_;
+ RawArray* guarded_fields_;
+ RawArray* deoptimize_dependent_fields_;
uint32_t cha_invalidation_gen_;
uint32_t field_invalidation_gen_;
uint32_t prefix_invalidation_gen_;
@@ -1543,6 +1584,9 @@ class BackgroundCompilationQueue {
QueueElement* p = first_;
while (p != NULL) {
visitor->VisitPointer(p->obj_ptr());
+ visitor->VisitPointer(p->leaf_classses_ptr());
+ visitor->VisitPointer(p->guarded_fields_ptr());
+ visitor->VisitPointer(p->deoptimize_dependent_fields_ptr());
p = p->next();
}
}
@@ -1604,6 +1648,9 @@ class BackgroundCompilationQueue {
BackgroundCompilationResult::BackgroundCompilationResult()
: result_code_(Code::Handle()),
+ leaf_classes_(Array::Handle()),
+ guarded_fields_(Array::Handle()),
+ deoptimize_dependent_fields_(Array::Handle()),
cha_invalidation_gen_(Isolate::kInvalidGen),
field_invalidation_gen_(Isolate::kInvalidGen),
prefix_invalidation_gen_(Isolate::kInvalidGen) {
@@ -1613,6 +1660,9 @@ BackgroundCompilationResult::BackgroundCompilationResult()
void BackgroundCompilationResult::Init() {
Isolate* i = Isolate::Current();
result_code_ = Code::null();
+ leaf_classes_ = Array::null();
+ guarded_fields_ = Array::null();
+ deoptimize_dependent_fields_ = Array::null();
cha_invalidation_gen_ = i->cha_invalidation_gen();
field_invalidation_gen_ = i->field_invalidation_gen();
prefix_invalidation_gen_ = i->prefix_invalidation_gen();
@@ -1622,12 +1672,46 @@ void BackgroundCompilationResult::Init() {
void BackgroundCompilationResult::SetFromQElement(QueueElement* value) {
ASSERT(value != NULL);
result_code_ = value->Code();
+ leaf_classes_ = value->leaf_classes();
+ guarded_fields_ = value->guarded_fields();
+ deoptimize_dependent_fields_ = value->deoptimize_dependent_fields();
cha_invalidation_gen_ = value->cha_invalidation_gen();
field_invalidation_gen_ = value->field_invalidation_gen();
prefix_invalidation_gen_ = value->prefix_invalidation_gen();
}
+void BackgroundCompilationResult::SetLeafClasses(
+ const GrowableArray<Class*>& leaf_classes) {
+ const Array& a = Array::Handle(Array::New(leaf_classes.length(), Heap::kOld));
+ for (intptr_t i = 0; i < leaf_classes.length(); i++) {
+ a.SetAt(i, *leaf_classes[i]);
+ }
+ leaf_classes_ = a.raw();
+}
+
+
+void BackgroundCompilationResult::SetGuardedFields(
+ const ZoneGrowableArray<const Field*>& guarded_fields) {
+ const Array& a =
+ Array::Handle(Array::New(guarded_fields.length(), Heap::kOld));
+ for (intptr_t i = 0; i < guarded_fields.length(); i++) {
+ a.SetAt(i, *guarded_fields[i]);
+ }
+ guarded_fields_ = a.raw();
+}
+
+
+void BackgroundCompilationResult::SetDeoptimizeDependentFields(
+ const GrowableArray<const Field*>& fields) {
+ const Array& a = Array::Handle(Array::New(fields.length(), Heap::kOld));
+ for (intptr_t i = 0; i < fields.length(); i++) {
+ a.SetAt(i, *fields[i]);
+ }
+ deoptimize_dependent_fields_ = a.raw();
+}
+
+
bool BackgroundCompilationResult::IsValid() const {
if (result_code().IsNull() || result_code().IsDisabled()) {
return false;
@@ -1756,7 +1840,7 @@ void BackgroundCompiler::CompileOptimized(const Function& function) {
void BackgroundCompiler::InstallGeneratedCode() {
ASSERT(Thread::Current()->IsMutatorThread());
MonitorLocker ml(queue_monitor_);
- Object& owner = Object::Handle();
+ Function& function = Function::Handle();
while (result_queue()->Peek() != NULL) {
BackgroundCompilationResult result;
QueueElement* elem = result_queue()->Remove();
@@ -1764,10 +1848,26 @@ void BackgroundCompiler::InstallGeneratedCode() {
result.SetFromQElement(elem);
delete elem;
- owner = result.result_code().owner();
- const Function& function = Function::Cast(owner);
+ const Code& code = result.result_code();
+ function ^= code.owner();
if (result.IsValid()) {
function.InstallOptimizedCode(result.result_code(), false /* not OSR */);
+ // Install leaf classes and fields dependencies.
+ Class& cls = Class::Handle();
+ for (intptr_t i = 0; i < result.leaf_classes().Length(); i++) {
+ cls ^= result.leaf_classes().At(i);
+ cls.RegisterCHACode(code);
+ }
+ Field& field = Field::Handle();
+ for (intptr_t i = 0; i < result.guarded_fields().Length(); i++) {
+ field ^= result.guarded_fields().At(i);
+ field.RegisterDependentCode(code);
+ }
+ for (intptr_t i = 0; i < result.deoptimize_dependent_fields().Length();
+ i++) {
+ field ^= result.deoptimize_dependent_fields().At(i);
+ field.DeoptimizeDependentCode();
+ }
} else if (FLAG_trace_compiler) {
THR_Print("Drop code generated in the background compiler:\n");
result.PrintValidity();
@@ -1822,6 +1922,18 @@ void BackgroundCompiler::Stop(BackgroundCompiler* task) {
void BackgroundCompiler::EnsureInit(Thread* thread) {
+ ASSERT(thread->IsMutatorThread());
+ // Finalize NoSuchMethodError, _Mint; occasionally needed in optimized
+ // compilation.
+ Class& cls = Class::Handle(thread->zone(),
+ Library::LookupCoreClass(Symbols::NoSuchMethodError()));
+ Error& error = Error::Handle(thread->zone(),
+ cls.EnsureIsFinalized(thread));
+ ASSERT(error.IsNull());
+ cls = Library::LookupCoreClass(Symbols::_Mint());
+ error = cls.EnsureIsFinalized(thread);
+ ASSERT(error.IsNull());
+
bool start_task = false;
Isolate* isolate = thread->isolate();
{
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/flow_graph.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698