| Index: runtime/vm/flow_graph_inliner.cc
|
| ===================================================================
|
| --- runtime/vm/flow_graph_inliner.cc (revision 36573)
|
| +++ runtime/vm/flow_graph_inliner.cc (working copy)
|
| @@ -87,19 +87,6 @@
|
| }
|
|
|
|
|
| -// Helper to create a parameter stub from an actual argument.
|
| -static Definition* CreateParameterStub(intptr_t i,
|
| - Value* argument,
|
| - FlowGraph* graph) {
|
| - ConstantInstr* constant = argument->definition()->AsConstant();
|
| - if (constant != NULL) {
|
| - return new ConstantInstr(constant->value());
|
| - } else {
|
| - return new ParameterInstr(i, graph->graph_entry());
|
| - }
|
| -}
|
| -
|
| -
|
| // Helper to get the default value of a formal parameter.
|
| static ConstantInstr* GetDefaultValue(intptr_t i,
|
| const ParsedFunction& parsed_function) {
|
| @@ -446,6 +433,8 @@
|
|
|
| TargetEntryInstr* BuildDecisionGraph();
|
|
|
| + Isolate* isolate() const;
|
| +
|
| CallSiteInliner* const owner_;
|
| PolymorphicInstanceCallInstr* const call_;
|
| const intptr_t num_variants_;
|
| @@ -475,6 +464,8 @@
|
|
|
| FlowGraph* caller_graph() const { return caller_graph_; }
|
|
|
| + Isolate* isolate() const { return caller_graph_->isolate(); }
|
| +
|
| // Inlining heuristics based on Cooper et al. 2008.
|
| bool ShouldWeInline(const Function& callee,
|
| intptr_t instr_count,
|
| @@ -554,6 +545,18 @@
|
| static_cast<double>(initial_size_);
|
| }
|
|
|
| + // Helper to create a parameter stub from an actual argument.
|
| + Definition* CreateParameterStub(intptr_t i,
|
| + Value* argument,
|
| + FlowGraph* graph) {
|
| + ConstantInstr* constant = argument->definition()->AsConstant();
|
| + if (constant != NULL) {
|
| + return new(isolate()) ConstantInstr(constant->value());
|
| + } else {
|
| + return new(isolate()) ParameterInstr(i, graph->graph_entry());
|
| + }
|
| + }
|
| +
|
| bool TryInlining(const Function& function,
|
| const Array& argument_names,
|
| InlinedCallData* call_data) {
|
| @@ -619,10 +622,9 @@
|
| return false;
|
| }
|
|
|
| - Isolate* isolate = Isolate::Current();
|
| // Save and clear deopt id.
|
| - const intptr_t prev_deopt_id = isolate->deopt_id();
|
| - isolate->set_deopt_id(0);
|
| + const intptr_t prev_deopt_id = isolate()->deopt_id();
|
| + isolate()->set_deopt_id(0);
|
| // Install bailout jump.
|
| LongJumpScope jump;
|
| if (setjmp(*jump.Set()) == 0) {
|
| @@ -632,7 +634,7 @@
|
| {
|
| TimerScope timer(FLAG_compiler_stats,
|
| &CompilerStats::graphinliner_parse_timer,
|
| - isolate);
|
| + isolate());
|
| parsed_function = GetParsedFunction(function, &in_cache);
|
| }
|
|
|
| @@ -646,7 +648,7 @@
|
|
|
| // Build the callee graph.
|
| InlineExitCollector* exit_collector =
|
| - new InlineExitCollector(caller_graph_, call);
|
| + new(isolate()) InlineExitCollector(caller_graph_, call);
|
| FlowGraphBuilder builder(parsed_function,
|
| ic_data_array,
|
| exit_collector,
|
| @@ -657,7 +659,7 @@
|
| {
|
| TimerScope timer(FLAG_compiler_stats,
|
| &CompilerStats::graphinliner_build_timer,
|
| - isolate);
|
| + isolate());
|
| callee_graph = builder.BuildGraph();
|
| }
|
|
|
| @@ -666,7 +668,8 @@
|
| // without linking between the caller and callee graphs.
|
| // TODO(zerny): Put more information in the stubs, eg, type information.
|
| ZoneGrowableArray<Definition*>* param_stubs =
|
| - new ZoneGrowableArray<Definition*>(function.NumParameters());
|
| + new(isolate()) ZoneGrowableArray<Definition*>(
|
| + function.NumParameters());
|
|
|
| // Create a parameter stub for each fixed positional parameter.
|
| for (intptr_t i = 0; i < function.num_fixed_parameters(); ++i) {
|
| @@ -701,7 +704,7 @@
|
| {
|
| TimerScope timer(FLAG_compiler_stats,
|
| &CompilerStats::graphinliner_ssa_timer,
|
| - isolate);
|
| + isolate());
|
| // Compute SSA on the callee graph, catching bailouts.
|
| callee_graph->ComputeSSA(caller_graph_->max_virtual_register_number(),
|
| param_stubs);
|
| @@ -711,7 +714,7 @@
|
| {
|
| TimerScope timer(FLAG_compiler_stats,
|
| &CompilerStats::graphinliner_opt_timer,
|
| - isolate);
|
| + isolate());
|
| // TODO(zerny): Do more optimization passes on the callee graph.
|
| FlowGraphOptimizer optimizer(callee_graph);
|
| optimizer.ApplyICData();
|
| @@ -753,7 +756,7 @@
|
| (size > FLAG_inlining_constant_arguments_size_threshold)) {
|
| function.set_is_inlinable(false);
|
| }
|
| - isolate->set_deopt_id(prev_deopt_id);
|
| + isolate()->set_deopt_id(prev_deopt_id);
|
| TRACE_INLINING(OS::Print(" Bailout: heuristics with "
|
| "code size: %" Pd ", "
|
| "call sites: %" Pd ", "
|
| @@ -787,7 +790,7 @@
|
| // Build succeeded so we restore the bailout jump.
|
| inlined_ = true;
|
| inlined_size_ += size;
|
| - isolate->set_deopt_id(prev_deopt_id);
|
| + isolate()->set_deopt_id(prev_deopt_id);
|
|
|
| call_data->callee_graph = callee_graph;
|
| call_data->parameter_stubs = param_stubs;
|
| @@ -809,9 +812,9 @@
|
| return true;
|
| } else {
|
| Error& error = Error::Handle();
|
| - error = isolate->object_store()->sticky_error();
|
| - isolate->object_store()->clear_sticky_error();
|
| - isolate->set_deopt_id(prev_deopt_id);
|
| + error = isolate()->object_store()->sticky_error();
|
| + isolate()->object_store()->clear_sticky_error();
|
| + isolate()->set_deopt_id(prev_deopt_id);
|
| TRACE_INLINING(OS::Print(" Bailout: %s\n", error.ToErrorCString()));
|
| PRINT_INLINING_TREE("Bailout",
|
| &call_data->caller, &function, call);
|
| @@ -949,7 +952,7 @@
|
| }
|
| }
|
| *in_cache = false;
|
| - ParsedFunction* parsed_function = new ParsedFunction(function);
|
| + ParsedFunction* parsed_function = new(isolate()) ParsedFunction(function);
|
| Parser::ParseFunction(parsed_function);
|
| parsed_function->AllocateVariables();
|
| return parsed_function;
|
| @@ -1103,7 +1106,7 @@
|
| Object::ZoneHandle(
|
| parsed_function.default_parameter_values().At(
|
| i - fixed_param_count));
|
| - ConstantInstr* constant = new ConstantInstr(object);
|
| + ConstantInstr* constant = new(isolate()) ConstantInstr(object);
|
| arguments->Add(NULL);
|
| param_stubs->Add(constant);
|
| }
|
| @@ -1188,11 +1191,17 @@
|
| inlined_variants_(num_variants_),
|
| non_inlined_variants_(num_variants_),
|
| inlined_entries_(num_variants_),
|
| - exit_collector_(new InlineExitCollector(owner->caller_graph(), call)),
|
| + exit_collector_(new(isolate())
|
| + InlineExitCollector(owner->caller_graph(), call)),
|
| caller_function_(caller_function) {
|
| }
|
|
|
|
|
| +Isolate* PolymorphicInliner::isolate() const {
|
| + return owner_->caller_graph()->isolate();
|
| +}
|
| +
|
| +
|
| // Inlined bodies are shared if two different class ids have the same
|
| // inlined target. This sharing is represented by using three different
|
| // types of entries in the inlined_entries_ array:
|
| @@ -1220,7 +1229,8 @@
|
| // the graph anymore. A new target be created instead.
|
| inlined_entries_[i]->AsGraphEntry()->UnuseAllInputs();
|
|
|
| - JoinEntryInstr* new_join = BranchSimplifier::ToJoinEntry(old_target);
|
| + JoinEntryInstr* new_join =
|
| + BranchSimplifier::ToJoinEntry(isolate(), old_target);
|
| old_target->ReplaceAsPredecessorWith(new_join);
|
| for (intptr_t j = 0; j < old_target->dominated_blocks().length(); ++j) {
|
| BlockEntryInstr* block = old_target->dominated_blocks()[j];
|
| @@ -1230,9 +1240,9 @@
|
| TargetEntryInstr* new_target =
|
| new TargetEntryInstr(owner_->caller_graph()->allocate_block_id(),
|
| old_target->try_index());
|
| - new_target->InheritDeoptTarget(new_join);
|
| - GotoInstr* new_goto = new GotoInstr(new_join);
|
| - new_goto->InheritDeoptTarget(new_join);
|
| + new_target->InheritDeoptTarget(isolate(), new_join);
|
| + GotoInstr* new_goto = new(isolate()) GotoInstr(new_join);
|
| + new_goto->InheritDeoptTarget(isolate(), new_join);
|
| new_target->LinkTo(new_goto);
|
| new_target->set_last_instruction(new_goto);
|
| new_join->predecessors_.Add(new_target);
|
| @@ -1296,7 +1306,8 @@
|
| // hoisted above the inlined entry.
|
| ASSERT(arguments.length() > 0);
|
| Value* actual = arguments[0];
|
| - RedefinitionInstr* redefinition = new RedefinitionInstr(actual->Copy());
|
| + RedefinitionInstr* redefinition = new(isolate())
|
| + RedefinitionInstr(actual->Copy(isolate()));
|
| redefinition->set_ssa_temp_index(
|
| owner_->caller_graph()->alloc_ssa_temp_index());
|
| redefinition->InsertAfter(callee_graph->graph_entry()->normal_entry());
|
| @@ -1344,7 +1355,7 @@
|
| GrowableArray<Definition*> arguments(call_->ArgumentCount());
|
| Definition* receiver = call_->ArgumentAt(0);
|
| RedefinitionInstr* redefinition =
|
| - new RedefinitionInstr(new Value(receiver));
|
| + new(isolate()) RedefinitionInstr(new(isolate()) Value(receiver));
|
| redefinition->set_ssa_temp_index(
|
| owner_->caller_graph()->alloc_ssa_temp_index());
|
| if (optimizer.TryInlineRecognizedMethod(receiver_cid,
|
| @@ -1357,11 +1368,11 @@
|
| // Create a graph fragment.
|
| redefinition->InsertAfter(entry);
|
| InlineExitCollector* exit_collector =
|
| - new InlineExitCollector(owner_->caller_graph(), call_);
|
| + new(isolate()) InlineExitCollector(owner_->caller_graph(), call_);
|
|
|
| ReturnInstr* result =
|
| - new ReturnInstr(call_->instance_call()->token_pos(),
|
| - new Value(last));
|
| + new(isolate()) ReturnInstr(call_->instance_call()->token_pos(),
|
| + new(isolate()) Value(last));
|
| owner_->caller_graph()->AppendTo(
|
| last,
|
| result,
|
| @@ -1370,9 +1381,9 @@
|
| entry->set_last_instruction(result);
|
| exit_collector->AddExit(result);
|
| GraphEntryInstr* graph_entry =
|
| - new GraphEntryInstr(NULL, // No parsed function.
|
| - entry,
|
| - Isolate::kNoDeoptId); // No OSR id.
|
| + new(isolate()) GraphEntryInstr(NULL, // No parsed function.
|
| + entry,
|
| + Isolate::kNoDeoptId); // No OSR id.
|
| // Update polymorphic inliner state.
|
| inlined_entries_.Add(graph_entry);
|
| exit_collector_->Union(exit_collector);
|
| @@ -1391,9 +1402,10 @@
|
| TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() {
|
| // Start with a fresh target entry.
|
| TargetEntryInstr* entry =
|
| - new TargetEntryInstr(owner_->caller_graph()->allocate_block_id(),
|
| - call_->GetBlock()->try_index());
|
| - entry->InheritDeoptTarget(call_);
|
| + new(isolate()) TargetEntryInstr(
|
| + owner_->caller_graph()->allocate_block_id(),
|
| + call_->GetBlock()->try_index());
|
| + entry->InheritDeoptTarget(isolate(), call_);
|
|
|
| // This function uses a cursor (a pointer to the 'current' instruction) to
|
| // build the graph. The next instruction will be inserted after the
|
| @@ -1404,7 +1416,8 @@
|
| Definition* receiver = call_->ArgumentAt(0);
|
| // There are at least two variants including non-inlined ones, so we have
|
| // at least one branch on the class id.
|
| - LoadClassIdInstr* load_cid = new LoadClassIdInstr(new Value(receiver));
|
| + LoadClassIdInstr* load_cid =
|
| + new(isolate()) LoadClassIdInstr(new(isolate()) Value(receiver));
|
| load_cid->set_ssa_temp_index(owner_->caller_graph()->alloc_ssa_temp_index());
|
| cursor = AppendInstruction(cursor, load_cid);
|
| for (intptr_t i = 0; i < inlined_variants_.length(); ++i) {
|
| @@ -1416,7 +1429,7 @@
|
| // body. Check a redefinition of the receiver, to prevent the check
|
| // from being hoisted.
|
| RedefinitionInstr* redefinition =
|
| - new RedefinitionInstr(new Value(receiver));
|
| + new(isolate()) RedefinitionInstr(new(isolate()) Value(receiver));
|
| redefinition->set_ssa_temp_index(
|
| owner_->caller_graph()->alloc_ssa_temp_index());
|
| cursor = AppendInstruction(cursor, redefinition);
|
| @@ -1425,7 +1438,7 @@
|
| new CheckSmiInstr(new Value(redefinition),
|
| call_->deopt_id(),
|
| call_->token_pos());
|
| - check_smi->InheritDeoptTarget(call_);
|
| + check_smi->InheritDeoptTarget(isolate(), call_);
|
| cursor = AppendInstruction(cursor, check_smi);
|
| } else {
|
| const ICData& old_checks = call_->ic_data();
|
| @@ -1442,7 +1455,7 @@
|
| call_->deopt_id(),
|
| new_checks,
|
| call_->token_pos());
|
| - check_class->InheritDeoptTarget(call_);
|
| + check_class->InheritDeoptTarget(isolate(), call_);
|
| cursor = AppendInstruction(cursor, check_class);
|
| }
|
| // The next instruction is the first instruction of the inlined body.
|
| @@ -1475,7 +1488,7 @@
|
| JoinEntryInstr* join = callee_entry->AsJoinEntry();
|
| ASSERT(join->dominator() != NULL);
|
| GotoInstr* goto_join = new GotoInstr(join);
|
| - goto_join->InheritDeoptTarget(join);
|
| + goto_join->InheritDeoptTarget(isolate(), join);
|
| cursor->LinkTo(goto_join);
|
| current_block->set_last_instruction(goto_join);
|
| } else {
|
| @@ -1498,7 +1511,7 @@
|
| new Value(cid_constant),
|
| false); // No number check.
|
| BranchInstr* branch = new BranchInstr(compare);
|
| - branch->InheritDeoptTarget(call_);
|
| + branch->InheritDeoptTarget(isolate(), call_);
|
| AppendInstruction(AppendInstruction(cursor, cid_constant), branch);
|
| current_block->set_last_instruction(branch);
|
| cursor = NULL;
|
| @@ -1530,9 +1543,9 @@
|
| true_target =
|
| new TargetEntryInstr(owner_->caller_graph()->allocate_block_id(),
|
| call_->GetBlock()->try_index());
|
| - true_target->InheritDeoptTarget(join);
|
| + true_target->InheritDeoptTarget(isolate(), join);
|
| GotoInstr* goto_join = new GotoInstr(join);
|
| - goto_join->InheritDeoptTarget(join);
|
| + goto_join->InheritDeoptTarget(isolate(), join);
|
| true_target->LinkTo(goto_join);
|
| true_target->set_last_instruction(goto_join);
|
| }
|
| @@ -1544,7 +1557,7 @@
|
| TargetEntryInstr* false_target =
|
| new TargetEntryInstr(owner_->caller_graph()->allocate_block_id(),
|
| call_->GetBlock()->try_index());
|
| - false_target->InheritDeoptTarget(call_);
|
| + false_target->InheritDeoptTarget(isolate(), call_);
|
| *branch->false_successor_address() = false_target;
|
| current_block->AddDominatedBlock(false_target);
|
| cursor = current_block = false_target;
|
| @@ -1579,11 +1592,11 @@
|
| true); // With checks.
|
| fallback_call->set_ssa_temp_index(
|
| owner_->caller_graph()->alloc_ssa_temp_index());
|
| - fallback_call->InheritDeoptTarget(call_);
|
| + fallback_call->InheritDeoptTarget(isolate(), call_);
|
| ReturnInstr* fallback_return =
|
| new ReturnInstr(call_->instance_call()->token_pos(),
|
| new Value(fallback_call));
|
| - fallback_return->InheritDeoptTargetAfter(call_);
|
| + fallback_return->InheritDeoptTargetAfter(isolate(), call_);
|
| AppendInstruction(AppendInstruction(cursor, fallback_call),
|
| fallback_return);
|
| exit_collector_->AddExit(fallback_return);
|
|
|