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

Unified Diff: runtime/vm/code_generator.cc

Issue 14935005: Implement a variation of scalar replacement for non-escaping allocations. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address comments Created 7 years, 7 months 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/code_generator.h ('k') | runtime/vm/compiler.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/code_generator.cc
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index fb9e84635d038f7adc2ab0c2a6b9642b4080dfc4..5ddbf867b71e256814356e4320006bfc362781f3 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1545,7 +1545,7 @@ DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
const intptr_t num_args =
function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
intptr_t unoptimized_stack_size =
- + deopt_info.TranslationLength() - num_args
+ + deopt_info.FrameSize() - num_args
- kLastParamSlotIndex; // Subtract caller FP and PC (possibly pc marker).
return unoptimized_stack_size * kWordSize;
}
@@ -1577,16 +1577,44 @@ static intptr_t DeoptimizeWithDeoptInfo(const Code& code,
Array::Handle(code.object_table()),
num_args,
static_cast<DeoptReasonId>(deopt_reason));
- for (intptr_t to_index = len - 1; to_index >= 0; to_index--) {
- deopt_instructions[to_index]->Execute(&deopt_context, to_index);
+ const intptr_t frame_size = deopt_info.FrameSize();
+
+ // All kMaterializeObject instructions are emitted before the instructions
+ // that describe stack frames. Skip them and defer materialization of
+ // objects until the frame is fully reconstructed and it is safe to perform
+ // GC.
+ // Arguments (class of the instance to allocate and field-value pairs) are
+ // described as part of the expression stack for the bottom-most deoptimized
+ // frame. They will be used during materialization and removed from the stack
+ // right before control switches to the unoptimized code.
+ const intptr_t num_materializations = len - frame_size;
+ Isolate::Current()->PrepareForDeferredMaterialization(num_materializations);
+ for (intptr_t from_index = 0, to_index = 1;
+ from_index < num_materializations;
+ from_index++) {
+ const intptr_t field_count =
+ DeoptInstr::GetFieldCount(deopt_instructions[from_index]);
+ intptr_t* args = deopt_context.GetToFrameAddressAt(to_index);
+ DeferredObject* obj = new DeferredObject(field_count, args);
+ Isolate::Current()->SetDeferredObjectAt(from_index, obj);
+ to_index += obj->ArgumentCount();
}
+
+ // Populate stack frames.
+ for (intptr_t to_index = frame_size - 1, from_index = len - 1;
+ to_index >= 0;
+ to_index--, from_index--) {
+ intptr_t* to_addr = deopt_context.GetToFrameAddressAt(to_index);
+ deopt_instructions[from_index]->Execute(&deopt_context, to_addr);
+ }
+
if (FLAG_trace_deoptimization_verbose) {
- for (intptr_t i = 0; i < len; i++) {
- OS::PrintErr("*%"Pd". [%p] %#014"Px" [%s]\n",
- i,
- &start[i],
- start[i],
- deopt_instructions[i]->ToCString());
+ for (intptr_t i = 0; i < frame_size; i++) {
+ OS::PrintErr("*%"Pd". [%"Px"] %#014"Px" [%s]\n",
+ i,
+ reinterpret_cast<uword>(&start[i]),
+ start[i],
+ deopt_instructions[i + (len - frame_size)]->ToCString());
}
}
return deopt_context.GetCallerFp();
@@ -1637,17 +1665,30 @@ END_LEAF_RUNTIME_ENTRY
// This is the last step in the deoptimization, GC can occur.
-DEFINE_RUNTIME_ENTRY(DeoptimizeMaterializeDoubles, 0) {
- DeferredObject* deferred_object = Isolate::Current()->DetachDeferredObjects();
-
- while (deferred_object != NULL) {
- DeferredObject* current = deferred_object;
- deferred_object = deferred_object->next();
-
- current->Materialize();
-
- delete current;
+// Returns number of bytes to remove from the expression stack of the
+// bottom-most deoptimized frame. Those arguments were artificially injected
+// under return address to keep them discoverable by GC that can occur during
+// materialization phase.
+DEFINE_RUNTIME_ENTRY(DeoptimizeMaterialize, 0) {
+ // First materialize all unboxed "primitive" values (doubles, mints, simd)
+ // then materialize objects. The order is important: objects might be
+ // referencing boxes allocated on the first step. At the same time
+ // objects can't be referencing other deferred objects because storing
+ // an object into a field is always conservatively treated as escaping by
+ // allocation sinking and load forwarding.
+ isolate->MaterializeDeferredBoxes();
+ isolate->MaterializeDeferredObjects();
+
+ // Compute total number of artificial arguments used during deoptimization.
+ intptr_t deopt_arguments = 0;
+ for (intptr_t i = 0; i < isolate->DeferredObjectsCount(); i++) {
+ deopt_arguments += isolate->GetDeferredObject(i)->ArgumentCount();
}
+ Isolate::Current()->DeleteDeferredObjects();
+
+ // Return value tells deoptimization stub to remove the given number of bytes
+ // from the stack.
+ arguments.SetReturn(Smi::Handle(Smi::New(deopt_arguments * kWordSize)));
// Since this is the only step where GC can occur during deoptimization,
// use it to report the source line where deoptimization occured.
« no previous file with comments | « runtime/vm/code_generator.h ('k') | runtime/vm/compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698