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

Unified Diff: runtime/vm/flow_graph_compiler.cc

Issue 2734323003: Re-landing of "replace TrySync with Metadata". (Closed)
Patch Set: Address review comments Created 3 years, 9 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/flow_graph_compiler.h ('k') | runtime/vm/flow_graph_compiler_arm.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_compiler.cc
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index e1c8a0113e9743421e959d5441295684503e5f4a..665afa336d641d194ad1c16fae6ce58b00088237 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -196,6 +196,7 @@ FlowGraphCompiler::FlowGraphCompiler(
pc_descriptors_list_(NULL),
stackmap_table_builder_(NULL),
code_source_map_builder_(NULL),
+ catch_entry_state_maps_builder_(NULL),
block_info_(block_order_.length()),
deopt_infos_(),
static_calls_target_table_(),
@@ -267,6 +268,7 @@ bool FlowGraphCompiler::IsPotentialUnboxedField(const Field& field) {
void FlowGraphCompiler::InitCompiler() {
pc_descriptors_list_ = new (zone()) DescriptorList(64);
exception_handlers_list_ = new (zone()) ExceptionHandlerList();
+ catch_entry_state_maps_builder_ = new (zone()) CatchEntryStateMapBuilder();
block_info_.Clear();
// Conservative detection of leaf routines used to remove the stack check
// on function entry.
@@ -412,6 +414,91 @@ void FlowGraphCompiler::CompactBlocks() {
}
+void FlowGraphCompiler::EmitCatchEntryState(Environment* env,
+ intptr_t try_index) {
+#if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+ env = env ? env : pending_deoptimization_env_;
+ try_index = try_index != CatchClauseNode::kInvalidTryIndex
+ ? try_index
+ : CurrentTryIndex();
+ if (is_optimizing() && env != NULL &&
+ (try_index != CatchClauseNode::kInvalidTryIndex)) {
+ env = env->Outermost();
+ CatchBlockEntryInstr* catch_block =
+ flow_graph().graph_entry()->GetCatchEntry(try_index);
+ const GrowableArray<Definition*>* idefs =
+ catch_block->initial_definitions();
+ catch_entry_state_maps_builder_->NewMapping(assembler()->CodeSize());
+ // Parameters first.
+ intptr_t i = 0;
+ const intptr_t num_non_copied_params = flow_graph().num_non_copied_params();
+ for (; i < num_non_copied_params; ++i) {
+ // Don't sync captured parameters. They are not in the environment.
+ if (flow_graph().captured_parameters()->Contains(i)) continue;
+ if ((*idefs)[i]->IsConstant()) continue; // Common constants.
+ Location src = env->LocationAt(i);
+ intptr_t dest_index = i - num_non_copied_params;
+ if (!src.IsStackSlot()) {
+ ASSERT(src.IsConstant());
+ // Skip dead locations.
+ if (src.constant().raw() == Symbols::OptimizedOut().raw()) {
+ continue;
+ }
+ intptr_t id =
+ assembler()->object_pool_wrapper().FindObject(src.constant());
+ catch_entry_state_maps_builder_->AppendConstant(id, dest_index);
+ continue;
+ }
+ if (src.stack_index() != dest_index) {
+ catch_entry_state_maps_builder_->AppendMove(src.stack_index(),
+ dest_index);
+ }
+ }
+
+ // Process locals. Skip exception_var and stacktrace_var.
+ intptr_t local_base = kFirstLocalSlotFromFp + num_non_copied_params;
+ intptr_t ex_idx = local_base - catch_block->exception_var().index();
+ intptr_t st_idx = local_base - catch_block->stacktrace_var().index();
+ for (; i < flow_graph().variable_count(); ++i) {
+ // Don't sync captured parameters. They are not in the environment.
+ if (flow_graph().captured_parameters()->Contains(i)) continue;
+ if (i == ex_idx || i == st_idx) continue;
+ if ((*idefs)[i]->IsConstant()) continue; // Common constants.
+ Location src = env->LocationAt(i);
+ if (src.IsInvalid()) continue;
+ intptr_t dest_index = i - num_non_copied_params;
+ if (!src.IsStackSlot()) {
+ ASSERT(src.IsConstant());
+ // Skip dead locations.
+ if (src.constant().raw() == Symbols::OptimizedOut().raw()) {
+ continue;
+ }
+ intptr_t id =
+ assembler()->object_pool_wrapper().FindObject(src.constant());
+ catch_entry_state_maps_builder_->AppendConstant(id, dest_index);
+ continue;
+ }
+ if (src.stack_index() != dest_index) {
+ catch_entry_state_maps_builder_->AppendMove(src.stack_index(),
+ dest_index);
+ }
+ }
+ catch_entry_state_maps_builder_->EndMapping();
+ }
+#endif // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+}
+
+
+void FlowGraphCompiler::EmitCallsiteMetaData(TokenPosition token_pos,
+ intptr_t deopt_id,
+ RawPcDescriptors::Kind kind,
+ LocationSummary* locs) {
+ AddCurrentDescriptor(kind, deopt_id, token_pos);
+ RecordSafepoint(locs);
+ EmitCatchEntryState();
+}
+
+
void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
if (!is_optimizing()) {
if (instr->CanBecomeDeoptimizationTarget() && !instr->IsGoto()) {
@@ -422,10 +509,6 @@ void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
instr->token_pos());
}
AllocateRegistersLocally(instr);
- } else if (instr->MayThrow() &&
- (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) {
- // Optimized try-block: Sync locals to fixed stack locations.
- EmitTrySync(instr, CurrentTryIndex());
}
}
@@ -544,69 +627,6 @@ void FlowGraphCompiler::Bailout(const char* reason) {
}
-void FlowGraphCompiler::EmitTrySync(Instruction* instr, intptr_t try_index) {
- ASSERT(is_optimizing());
- Environment* env = instr->env()->Outermost();
- CatchBlockEntryInstr* catch_block =
- flow_graph().graph_entry()->GetCatchEntry(try_index);
- const GrowableArray<Definition*>* idefs = catch_block->initial_definitions();
-
- // Construct a ParallelMove instruction for parameters and locals. Skip the
- // special locals exception_var and stacktrace_var since they will be filled
- // when an exception is thrown. Constant locations are known to be the same
- // at all instructions that may throw, and do not need to be materialized.
-
- // Parameters first.
- intptr_t i = 0;
- const intptr_t num_non_copied_params = flow_graph().num_non_copied_params();
- ParallelMoveInstr* move_instr = new (zone()) ParallelMoveInstr();
- for (; i < num_non_copied_params; ++i) {
- // Don't sync captured parameters. They are not in the environment.
- if (flow_graph().captured_parameters()->Contains(i)) continue;
- if ((*idefs)[i]->IsConstant()) continue; // Common constants
- Location src = env->LocationAt(i);
-#if defined(TARGET_ARCH_DBC)
- intptr_t dest_index = kNumberOfCpuRegisters - 1 - i;
- Location dest = Location::RegisterLocation(dest_index);
- // Update safepoint bitmap to indicate that the target location
- // now contains a pointer. With DBC parameters are copied into
- // the locals area.
- instr->locs()->SetStackBit(dest_index);
-#else
- intptr_t dest_index = i - num_non_copied_params;
- Location dest = Location::StackSlot(dest_index);
-#endif
- move_instr->AddMove(dest, src);
- }
-
- // Process locals. Skip exception_var and stacktrace_var.
- intptr_t local_base = kFirstLocalSlotFromFp + num_non_copied_params;
- intptr_t ex_idx = local_base - catch_block->exception_var().index();
- intptr_t st_idx = local_base - catch_block->stacktrace_var().index();
- for (; i < flow_graph().variable_count(); ++i) {
- // Don't sync captured parameters. They are not in the environment.
- if (flow_graph().captured_parameters()->Contains(i)) continue;
- if (i == ex_idx || i == st_idx) continue;
- if ((*idefs)[i]->IsConstant()) continue;
- Location src = env->LocationAt(i);
- ASSERT(!src.IsFpuRegister());
- ASSERT(!src.IsDoubleStackSlot());
-#if defined(TARGET_ARCH_DBC)
- intptr_t dest_index = kNumberOfCpuRegisters - 1 - i;
- Location dest = Location::RegisterLocation(dest_index);
-#else
- intptr_t dest_index = i - num_non_copied_params;
- Location dest = Location::StackSlot(dest_index);
-#endif
- move_instr->AddMove(dest, src);
- // Update safepoint bitmap to indicate that the target location
- // now contains a pointer.
- instr->locs()->SetStackBit(dest_index);
- }
- parallel_move_resolver()->EmitNativeCode(move_instr);
-}
-
-
intptr_t FlowGraphCompiler::StackSize() const {
if (is_optimizing_) {
return flow_graph_.graph_entry()->spill_slot_count();
@@ -1015,6 +1035,15 @@ void FlowGraphCompiler::FinalizeVarDescriptors(const Code& code) {
code.set_var_descriptors(var_descs);
}
+void FlowGraphCompiler::FinalizeCatchEntryStateMap(const Code& code) {
+#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
+ TypedData& maps = TypedData::Handle(
+ catch_entry_state_maps_builder_->FinalizeCatchEntryStateMap());
+ code.set_catch_entry_state_maps(maps);
+#else
+ code.set_variables(Smi::Handle(Smi::New(flow_graph().variable_count())));
+#endif
+}
void FlowGraphCompiler::FinalizeStaticCallTargetsTable(const Code& code) {
ASSERT(code.static_calls_target_table() == Array::null());
@@ -1123,6 +1152,23 @@ bool FlowGraphCompiler::TryIntrinsify() {
// DBC is very different from other architectures in how it performs instance
// and static calls because it does not use stubs.
#if !defined(TARGET_ARCH_DBC)
+void FlowGraphCompiler::GenerateCallWithDeopt(TokenPosition token_pos,
+ intptr_t deopt_id,
+ const StubEntry& stub_entry,
+ RawPcDescriptors::Kind kind,
+ LocationSummary* locs) {
+ GenerateCall(token_pos, stub_entry, kind, locs);
+ const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
+ if (is_optimizing()) {
+ AddDeoptIndexAtCall(deopt_id_after);
+ } else {
+ // Add deoptimization continuation point after the call and before the
+ // arguments are removed.
+ AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
+ }
+}
+
+
void FlowGraphCompiler::GenerateInstanceCall(intptr_t deopt_id,
TokenPosition token_pos,
intptr_t argument_count,
« no previous file with comments | « runtime/vm/flow_graph_compiler.h ('k') | runtime/vm/flow_graph_compiler_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698