From 7558644bd6daeead9251334792cd8e1bbb183641 Mon Sep 17 00:00:00 2001 From: Vyacheslav Egorov Date: Mon, 3 Sep 2018 16:01:24 +0000 Subject: [PATCH] [vm/compiler] Move compiler state (CHA, deopt id) from Thread to a special class Also move deopt id computation logic into a separate class and add a comment explaining while deopt ids are incremented by 2. Change-Id: Ife489be7d10c7198a8e7adf9e97e0c516d78ea55 Reviewed-on: https://dart-review.googlesource.com/72685 Commit-Queue: Vyacheslav Egorov Reviewed-by: Martin Kustermann --- runtime/vm/code_descriptors.cc | 4 +- .../vm/compiler/aot/aot_call_specializer.cc | 58 +++--- runtime/vm/compiler/aot/precompiler.cc | 8 +- .../compiler/assembler/assembler_dbc_test.cc | 3 +- .../vm/compiler/backend/block_scheduler.cc | 2 +- .../vm/compiler/backend/branch_optimizer.cc | 27 ++- .../compiler/backend/constant_propagator.cc | 10 +- runtime/vm/compiler/backend/flow_graph.cc | 33 +-- .../compiler/backend/flow_graph_compiler.cc | 10 +- .../backend/flow_graph_compiler_arm.cc | 18 +- .../backend/flow_graph_compiler_arm64.cc | 18 +- .../backend/flow_graph_compiler_dbc.cc | 4 +- .../backend/flow_graph_compiler_ia32.cc | 8 +- .../backend/flow_graph_compiler_x64.cc | 16 +- runtime/vm/compiler/backend/il.cc | 35 ++-- runtime/vm/compiler/backend/il.h | 42 ++-- runtime/vm/compiler/backend/il_arm.cc | 2 +- runtime/vm/compiler/backend/il_arm64.cc | 2 +- runtime/vm/compiler/backend/il_dbc.cc | 24 +-- runtime/vm/compiler/backend/il_ia32.cc | 2 +- runtime/vm/compiler/backend/il_printer.cc | 12 +- runtime/vm/compiler/backend/il_test.cc | 8 +- runtime/vm/compiler/backend/il_x64.cc | 2 +- runtime/vm/compiler/backend/inliner.cc | 190 +++++++++--------- runtime/vm/compiler/backend/range_analysis.cc | 6 +- .../vm/compiler/backend/type_propagator.cc | 11 +- runtime/vm/compiler/call_specializer.cc | 12 +- runtime/vm/compiler/cha.h | 18 +- runtime/vm/compiler/compiler_sources.gni | 1 + runtime/vm/compiler/compiler_state.h | 107 ++++++++++ .../frontend/base_flow_graph_builder.cc | 4 +- .../frontend/base_flow_graph_builder.h | 2 +- .../vm/compiler/frontend/bytecode_reader.cc | 8 +- .../compiler/frontend/flow_graph_builder.cc | 34 ++-- .../frontend/flow_graph_builder_test.cc | 1 + .../frontend/kernel_binary_flowgraph.cc | 7 +- runtime/vm/compiler/frontend/kernel_to_il.h | 2 +- runtime/vm/compiler/intrinsifier.cc | 57 +++--- runtime/vm/compiler/jit/compiler.cc | 21 +- runtime/vm/compiler/jit/compiler.h | 3 +- .../vm/compiler/jit/jit_call_specializer.cc | 2 +- runtime/vm/debugger.cc | 4 +- runtime/vm/deferred_objects.cc | 2 +- runtime/vm/deopt_instructions.cc | 2 +- runtime/vm/object.cc | 8 +- runtime/vm/parser.cc | 2 +- runtime/vm/regexp_assembler.cc | 3 +- runtime/vm/regexp_assembler_ir.h | 4 +- runtime/vm/runtime_entry.cc | 6 +- runtime/vm/thread.cc | 2 - runtime/vm/thread.h | 54 ++--- 51 files changed, 489 insertions(+), 432 deletions(-) create mode 100644 runtime/vm/compiler/compiler_state.h diff --git a/runtime/vm/code_descriptors.cc b/runtime/vm/code_descriptors.cc index 206c2498e41..da771141cd5 100644 --- a/runtime/vm/code_descriptors.cc +++ b/runtime/vm/code_descriptors.cc @@ -4,6 +4,7 @@ #include "vm/code_descriptors.h" +#include "vm/compiler/compiler_state.h" #include "vm/log.h" namespace dart { @@ -14,8 +15,7 @@ void DescriptorList::AddDescriptor(RawPcDescriptors::Kind kind, TokenPosition token_pos, intptr_t try_index) { ASSERT((kind == RawPcDescriptors::kRuntimeCall) || - (kind == RawPcDescriptors::kOther) || - (deopt_id != Thread::kNoDeoptId)); + (kind == RawPcDescriptors::kOther) || (deopt_id != DeoptId::kNone)); // When precompiling, we only use pc descriptors for exceptions. if (!FLAG_precompiled_mode || try_index != -1) { diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc index b9ba738a034..d62497b88ed 100644 --- a/runtime/vm/compiler/aot/aot_call_specializer.cc +++ b/runtime/vm/compiler/aot/aot_call_specializer.cc @@ -13,6 +13,7 @@ #include "vm/compiler/backend/inliner.h" #include "vm/compiler/backend/range_analysis.h" #include "vm/compiler/cha.h" +#include "vm/compiler/compiler_state.h" #include "vm/compiler/frontend/flow_graph_builder.h" #include "vm/compiler/jit/compiler.h" #include "vm/compiler/jit/jit_call_specializer.h" @@ -302,7 +303,7 @@ Value* AotCallSpecializer::PrepareStaticOpInput(Value* input, conversion = new (Z) SmiToDoubleInstr(input, call->token_pos()); } else if (FlowGraphCompiler::SupportsUnboxedInt64() && FlowGraphCompiler::CanConvertInt64ToDouble()) { - conversion = new (Z) Int64ToDoubleInstr(input, Thread::kNoDeoptId, + conversion = new (Z) Int64ToDoubleInstr(input, DeoptId::kNone, Instruction::kNotSpeculative); } else { UNREACHABLE(); @@ -375,14 +376,14 @@ bool AotCallSpecializer::TryOptimizeInstanceCallUsingStaticTypes( right_value = PrepareStaticOpInput(right_value, kMintCid, instr); replacement = new (Z) RelationalOpInstr( instr->token_pos(), op_kind, left_value, right_value, kMintCid, - Thread::kNoDeoptId, Instruction::kNotSpeculative); + DeoptId::kNone, Instruction::kNotSpeculative); } else { // TODO(dartbug.com/30480): Figure out how to handle null in // equality comparisons. // replacement = new (Z) EqualityCompareInstr( // instr->token_pos(), op_kind, left_value->CopyWithType(Z), - // right_value->CopyWithType(Z), kMintCid, Thread::kNoDeoptId); + // right_value->CopyWithType(Z), kMintCid, DeoptId::kNone); replacement = new (Z) CheckedSmiComparisonInstr( instr->token_kind(), left_value->CopyWithType(Z), right_value->CopyWithType(Z), instr); @@ -396,7 +397,7 @@ bool AotCallSpecializer::TryOptimizeInstanceCallUsingStaticTypes( instr->token_pos(), (op_kind == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT, left_value->CopyWithType(Z), right_value->CopyWithType(Z), - /* number_check = */ false, Thread::kNoDeoptId); + /* number_check = */ false, DeoptId::kNone); } else { replacement = new (Z) CheckedSmiComparisonInstr( instr->token_kind(), left_value->CopyWithType(Z), @@ -415,7 +416,7 @@ bool AotCallSpecializer::TryOptimizeInstanceCallUsingStaticTypes( right_value = PrepareStaticOpInput(right_value, kDoubleCid, instr); replacement = new (Z) RelationalOpInstr( instr->token_pos(), op_kind, left_value, right_value, kDoubleCid, - Thread::kNoDeoptId, Instruction::kNotSpeculative); + DeoptId::kNone, Instruction::kNotSpeculative); } } break; @@ -444,7 +445,7 @@ bool AotCallSpecializer::TryOptimizeInstanceCallUsingStaticTypes( // TODO(dartbug.com/30480): Enable 64-bit integer shifts. // replacement = new ShiftInt64OpInstr( // op_kind, left_value->CopyWithType(Z), - // right_value->CopyWithType(Z), Thread::kNoDeoptId); + // right_value->CopyWithType(Z), DeoptId::kNone); replacement = new (Z) CheckedSmiOpInstr(op_kind, left_value->CopyWithType(Z), right_value->CopyWithType(Z), instr); @@ -452,7 +453,7 @@ bool AotCallSpecializer::TryOptimizeInstanceCallUsingStaticTypes( left_value = PrepareStaticOpInput(left_value, kMintCid, instr); right_value = PrepareStaticOpInput(right_value, kMintCid, instr); replacement = new (Z) BinaryInt64OpInstr( - op_kind, left_value, right_value, Thread::kNoDeoptId, + op_kind, left_value, right_value, DeoptId::kNone, Instruction::kNotSpeculative); } } else { @@ -472,7 +473,7 @@ bool AotCallSpecializer::TryOptimizeInstanceCallUsingStaticTypes( left_value = PrepareStaticOpInput(left_value, kDoubleCid, instr); right_value = PrepareStaticOpInput(right_value, kDoubleCid, instr); replacement = new (Z) BinaryDoubleOpInstr( - op_kind, left_value, right_value, Thread::kNoDeoptId, + op_kind, left_value, right_value, DeoptId::kNone, instr->token_pos(), Instruction::kNotSpeculative); } } @@ -536,7 +537,7 @@ bool AotCallSpecializer::TryOptimizeStaticCallUsingStaticTypes( right_value = PrepareStaticOpInput(right_value, kMintCid, instr); replacement = new (Z) EqualityCompareInstr( instr->token_pos(), op_kind, left_value, right_value, kMintCid, - Thread::kNoDeoptId, Instruction::kNotSpeculative); + DeoptId::kNone, Instruction::kNotSpeculative); } break; } @@ -553,7 +554,7 @@ bool AotCallSpecializer::TryOptimizeStaticCallUsingStaticTypes( right_value = PrepareStaticOpInput(right_value, kMintCid, instr); replacement = new (Z) RelationalOpInstr( instr->token_pos(), op_kind, left_value, right_value, kMintCid, - Thread::kNoDeoptId, Instruction::kNotSpeculative); + DeoptId::kNone, Instruction::kNotSpeculative); } else if (FlowGraphCompiler::SupportsUnboxedDoubles() && right_type->IsNullableDouble() && IsSupportedIntOperandForStaticDoubleOp(left_type)) { @@ -561,7 +562,7 @@ bool AotCallSpecializer::TryOptimizeStaticCallUsingStaticTypes( right_value = PrepareStaticOpInput(right_value, kDoubleCid, instr); replacement = new (Z) RelationalOpInstr( instr->token_pos(), op_kind, left_value, right_value, kDoubleCid, - Thread::kNoDeoptId, Instruction::kNotSpeculative); + DeoptId::kNone, Instruction::kNotSpeculative); } break; } @@ -588,9 +589,9 @@ bool AotCallSpecializer::TryOptimizeStaticCallUsingStaticTypes( if (right_type->IsNullableInt() && (op_kind != Token::kDIV)) { left_value = PrepareReceiverOfDevirtualizedCall(left_value, kMintCid); right_value = PrepareStaticOpInput(right_value, kMintCid, instr); - replacement = new (Z) BinaryInt64OpInstr( - op_kind, left_value, right_value, Thread::kNoDeoptId, - Instruction::kNotSpeculative); + replacement = new (Z) + BinaryInt64OpInstr(op_kind, left_value, right_value, + DeoptId::kNone, Instruction::kNotSpeculative); } else if (FlowGraphCompiler::SupportsUnboxedDoubles() && right_type->IsNullableDouble() && IsSupportedIntOperandForStaticDoubleOp(left_type)) { @@ -601,7 +602,7 @@ bool AotCallSpecializer::TryOptimizeStaticCallUsingStaticTypes( left_value = PrepareStaticOpInput(left_value, kDoubleCid, instr); right_value = PrepareStaticOpInput(right_value, kDoubleCid, instr); replacement = new (Z) BinaryDoubleOpInstr( - op_kind, left_value, right_value, Thread::kNoDeoptId, + op_kind, left_value, right_value, DeoptId::kNone, instr->token_pos(), Instruction::kNotSpeculative); } } @@ -612,7 +613,7 @@ bool AotCallSpecializer::TryOptimizeStaticCallUsingStaticTypes( Value* left_value = instr->PushArgumentAt(receiver_index)->value(); left_value = PrepareReceiverOfDevirtualizedCall(left_value, kMintCid); replacement = new (Z) - UnaryInt64OpInstr(Token::kNEGATE, left_value, Thread::kNoDeoptId, + UnaryInt64OpInstr(Token::kNEGATE, left_value, DeoptId::kNone, Instruction::kNotSpeculative); break; } @@ -625,8 +626,8 @@ bool AotCallSpecializer::TryOptimizeStaticCallUsingStaticTypes( if (right_type->IsNullableInt()) { left_value = PrepareReceiverOfDevirtualizedCall(left_value, kMintCid); right_value = PrepareStaticOpInput(right_value, kMintCid, instr); - replacement = new (Z) ShiftInt64OpInstr( - op_kind, left_value, right_value, Thread::kNoDeoptId); + replacement = new (Z) ShiftInt64OpInstr(op_kind, left_value, + right_value, DeoptId::kNone); } break; } @@ -650,7 +651,7 @@ bool AotCallSpecializer::TryOptimizeStaticCallUsingStaticTypes( right_value = PrepareStaticOpInput(right_value, kDoubleCid, instr); replacement = new (Z) EqualityCompareInstr( instr->token_pos(), op_kind, left_value, right_value, kDoubleCid, - Thread::kNoDeoptId, Instruction::kNotSpeculative); + DeoptId::kNone, Instruction::kNotSpeculative); } break; } @@ -667,7 +668,7 @@ bool AotCallSpecializer::TryOptimizeStaticCallUsingStaticTypes( right_value = PrepareStaticOpInput(right_value, kDoubleCid, instr); replacement = new (Z) RelationalOpInstr( instr->token_pos(), op_kind, left_value, right_value, kDoubleCid, - Thread::kNoDeoptId, Instruction::kNotSpeculative); + DeoptId::kNone, Instruction::kNotSpeculative); } break; } @@ -683,7 +684,7 @@ bool AotCallSpecializer::TryOptimizeStaticCallUsingStaticTypes( PrepareReceiverOfDevirtualizedCall(left_value, kDoubleCid); right_value = PrepareStaticOpInput(right_value, kDoubleCid, instr); replacement = new (Z) BinaryDoubleOpInstr( - op_kind, left_value, right_value, Thread::kNoDeoptId, + op_kind, left_value, right_value, DeoptId::kNone, instr->token_pos(), Instruction::kNotSpeculative); } break; @@ -910,7 +911,8 @@ void AotCallSpecializer::VisitInstanceCall(InstanceCallInstr* instr) { } if (!receiver_class.IsNull()) { GrowableArray class_ids(6); - if (thread()->cha()->ConcreteSubclasses(receiver_class, &class_ids)) { + if (thread()->compiler_state().cha().ConcreteSubclasses(receiver_class, + &class_ids)) { // First check if all subclasses end up calling the same method. // If this is the case we will replace instance call with a direct // static call. @@ -960,7 +962,7 @@ void AotCallSpecializer::VisitInstanceCall(InstanceCallInstr* instr) { // Create an ICData and map all previously seen classes (< i) to // the computed single_target. ic_data = ICData::New(function, instr->function_name(), - args_desc_array, Thread::kNoDeoptId, + args_desc_array, DeoptId::kNone, /* args_tested = */ 1, ICData::kOptimized); for (intptr_t j = 0; j < i; j++) { ic_data.AddReceiverCheck(class_ids[j], single_target); @@ -981,7 +983,7 @@ void AotCallSpecializer::VisitInstanceCall(InstanceCallInstr* instr) { // Create fake IC data with the resolved target. const ICData& ic_data = ICData::Handle( ICData::New(flow_graph()->function(), instr->function_name(), - args_desc_array, Thread::kNoDeoptId, + args_desc_array, DeoptId::kNone, /* args_tested = */ 1, ICData::kOptimized)); cls = single_target.Owner(); ic_data.AddReceiverCheck(cls.id(), single_target); @@ -1082,7 +1084,8 @@ bool AotCallSpecializer::TryExpandCallThroughGetter(const Class& receiver_class, call->token_pos(), getter_name, Token::kGET, get_arguments, /*type_args_len=*/0, /*argument_names=*/Object::empty_array(), - /*checked_argument_count=*/1, thread()->GetNextDeoptId()); + /*checked_argument_count=*/1, + thread()->compiler_state().GetNextDeoptId()); // Arguments to the .call() are the same as arguments to the // original call (including type arguments), but receiver @@ -1102,7 +1105,8 @@ bool AotCallSpecializer::TryExpandCallThroughGetter(const Class& receiver_class, InstanceCallInstr* invoke_call = new (Z) InstanceCallInstr( call->token_pos(), Symbols::Call(), Token::kILLEGAL, call_arguments, call->type_args_len(), call->argument_names(), - /*checked_argument_count=*/1, thread()->GetNextDeoptId()); + /*checked_argument_count=*/1, + thread()->compiler_state().GetNextDeoptId()); // Insert all new instructions, except .call() invocation into the // graph. @@ -1185,7 +1189,7 @@ bool AotCallSpecializer::TryReplaceInstanceOfWithRangeCheck( StrictCompareInstr* check_cid = new (Z) StrictCompareInstr(call->token_pos(), Token::kEQ_STRICT, new (Z) Value(left_cid), new (Z) Value(lower_cid), - /* number_check = */ false, Thread::kNoDeoptId); + /* number_check = */ false, DeoptId::kNone); ReplaceCall(call, check_cid); return true; } diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc index 12d2c6ab957..aa2572926d8 100644 --- a/runtime/vm/compiler/aot/precompiler.cc +++ b/runtime/vm/compiler/aot/precompiler.cc @@ -22,6 +22,7 @@ #include "vm/compiler/backend/type_propagator.h" #include "vm/compiler/cha.h" #include "vm/compiler/compiler_pass.h" +#include "vm/compiler/compiler_state.h" #include "vm/compiler/frontend/flow_graph_builder.h" #include "vm/compiler/jit/compiler.h" #include "vm/dart_entry.h" @@ -883,7 +884,7 @@ void Precompiler::CollectCallbackFields() { args_desc = ArgumentsDescriptor::New(0, // No type argument vector. function.num_fixed_parameters()); cids.Clear(); - if (T->cha()->ConcreteSubclasses(cls, &cids)) { + if (CHA::ConcreteSubclasses(cls, &cids)) { for (intptr_t j = 0; j < cids.length(); ++j) { subcls ^= I->class_table()->At(cids[j]); if (subcls.is_allocated()) { @@ -2832,16 +2833,13 @@ bool PrecompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) { true, FLAG_max_speculative_inlining_attempts); while (!done) { - DeoptIdScope deopt_id_scope(thread(), 0); LongJumpScope jump; const intptr_t val = setjmp(*jump.Set()); if (val == 0) { FlowGraph* flow_graph = nullptr; ZoneGrowableArray* ic_data_array = nullptr; - // Class hierarchy analysis is registered with the thread in the - // constructor and unregisters itself upon destruction. - CHA cha(thread()); + CompilerState compiler_state(thread()); // TimerScope needs an isolate to be properly terminated in case of a // LongJump. diff --git a/runtime/vm/compiler/assembler/assembler_dbc_test.cc b/runtime/vm/compiler/assembler/assembler_dbc_test.cc index 4e350fc5ef0..26cc5a4a3a3 100644 --- a/runtime/vm/compiler/assembler/assembler_dbc_test.cc +++ b/runtime/vm/compiler/assembler/assembler_dbc_test.cc @@ -6,6 +6,7 @@ #if defined(TARGET_ARCH_DBC) #include "vm/compiler/assembler/assembler.h" +#include "vm/compiler/compiler_state.h" #include "vm/stack_frame.h" #include "vm/unit_test.h" @@ -83,7 +84,7 @@ static void MakeDummyInstanceCall(Assembler* assembler, const Object& result) { Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs)); const ICData& ic_data = ICData::Handle(ICData::New( dummy_instance_function, String::Handle(dummy_instance_function.name()), - dummy_arguments_descriptor, Thread::kNoDeoptId, 2, ICData::kInstance)); + dummy_arguments_descriptor, DeoptId::kNone, 2, ICData::kInstance)); // Wire up the Function in the ICData. GrowableArray cids(2); diff --git a/runtime/vm/compiler/backend/block_scheduler.cc b/runtime/vm/compiler/backend/block_scheduler.cc index acc03785f2c..7b26cd6893f 100644 --- a/runtime/vm/compiler/backend/block_scheduler.cc +++ b/runtime/vm/compiler/backend/block_scheduler.cc @@ -62,7 +62,7 @@ void BlockScheduler::AssignEdgeWeights() const { if (Compiler::IsBackgroundCompilation() && ic_data_array.IsNull()) { // Deferred loading cleared ic_data_array. Compiler::AbortBackgroundCompilation( - Thread::kNoDeoptId, "BlockScheduler: ICData array cleared"); + DeoptId::kNone, "BlockScheduler: ICData array cleared"); } if (ic_data_array.IsNull()) { DEBUG_ASSERT(Isolate::Current()->HasAttemptedReload()); diff --git a/runtime/vm/compiler/backend/branch_optimizer.cc b/runtime/vm/compiler/backend/branch_optimizer.cc index 78615fc73ea..7eeda64c211 100644 --- a/runtime/vm/compiler/backend/branch_optimizer.cc +++ b/runtime/vm/compiler/backend/branch_optimizer.cc @@ -65,8 +65,8 @@ JoinEntryInstr* BranchSimplifier::ToJoinEntry(Zone* zone, // Convert a target block into a join block. Branches will be duplicated // so the former true and false targets become joins of the control flows // from all the duplicated branches. - JoinEntryInstr* join = new (zone) JoinEntryInstr( - target->block_id(), target->try_index(), Thread::kNoDeoptId); + JoinEntryInstr* join = new (zone) + JoinEntryInstr(target->block_id(), target->try_index(), DeoptId::kNone); join->InheritDeoptTarget(zone, target); join->LinkTo(target->next()); join->set_last_instruction(target->last_instruction()); @@ -82,7 +82,7 @@ BranchInstr* BranchSimplifier::CloneBranch(Zone* zone, ComparisonInstr* new_comparison = comparison->CopyWithNewOperands(new_left, new_right); BranchInstr* new_branch = - new (zone) BranchInstr(new_comparison, Thread::kNoDeoptId); + new (zone) BranchInstr(new_comparison, DeoptId::kNone); return new_branch; } @@ -182,24 +182,21 @@ void BranchSimplifier::Simplify(FlowGraph* flow_graph) { // Connect the branch to the true and false joins, via empty target // blocks. - TargetEntryInstr* true_target = - new (zone) TargetEntryInstr(flow_graph->max_block_id() + 1, - block->try_index(), Thread::kNoDeoptId); + TargetEntryInstr* true_target = new (zone) TargetEntryInstr( + flow_graph->max_block_id() + 1, block->try_index(), DeoptId::kNone); true_target->InheritDeoptTarget(zone, join_true); - TargetEntryInstr* false_target = - new (zone) TargetEntryInstr(flow_graph->max_block_id() + 2, - block->try_index(), Thread::kNoDeoptId); + TargetEntryInstr* false_target = new (zone) TargetEntryInstr( + flow_graph->max_block_id() + 2, block->try_index(), DeoptId::kNone); false_target->InheritDeoptTarget(zone, join_false); flow_graph->set_max_block_id(flow_graph->max_block_id() + 2); *new_branch->true_successor_address() = true_target; *new_branch->false_successor_address() = false_target; - GotoInstr* goto_true = - new (zone) GotoInstr(join_true, Thread::kNoDeoptId); + GotoInstr* goto_true = new (zone) GotoInstr(join_true, DeoptId::kNone); goto_true->InheritDeoptTarget(zone, join_true); true_target->LinkTo(goto_true); true_target->set_last_instruction(goto_true); GotoInstr* goto_false = - new (zone) GotoInstr(join_false, Thread::kNoDeoptId); + new (zone) GotoInstr(join_false, DeoptId::kNone); goto_false->InheritDeoptTarget(zone, join_false); false_target->LinkTo(goto_false); false_target->set_last_instruction(goto_false); @@ -302,9 +299,9 @@ void IfConverter::Simplify(FlowGraph* flow_graph) { ComparisonInstr* new_comparison = comparison->CopyWithNewOperands( comparison->left()->Copy(zone), comparison->right()->Copy(zone)); - IfThenElseInstr* if_then_else = new (zone) - IfThenElseInstr(new_comparison, if_true->Copy(zone), - if_false->Copy(zone), Thread::kNoDeoptId); + IfThenElseInstr* if_then_else = + new (zone) IfThenElseInstr(new_comparison, if_true->Copy(zone), + if_false->Copy(zone), DeoptId::kNone); flow_graph->InsertBefore(branch, if_then_else, NULL, FlowGraph::kValue); diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc index 1a24e311655..4d88f97e634 100644 --- a/runtime/vm/compiler/backend/constant_propagator.cc +++ b/runtime/vm/compiler/backend/constant_propagator.cc @@ -1302,7 +1302,7 @@ void ConstantPropagator::EliminateRedundantBranches() { JoinEntryInstr* join = if_true->AsJoinEntry(); if (join->phis() == NULL) { GotoInstr* jump = - new (Z) GotoInstr(if_true->AsJoinEntry(), Thread::kNoDeoptId); + new (Z) GotoInstr(if_true->AsJoinEntry(), DeoptId::kNone); jump->InheritDeoptTarget(Z, branch); Instruction* previous = branch->previous(); @@ -1444,8 +1444,8 @@ void ConstantPropagator::Transform() { ASSERT(reachable_->Contains(if_false->preorder_number())); ASSERT(if_false->parallel_move() == NULL); ASSERT(if_false->loop_info() == NULL); - join = new (Z) JoinEntryInstr( - if_false->block_id(), if_false->try_index(), Thread::kNoDeoptId); + join = new (Z) JoinEntryInstr(if_false->block_id(), + if_false->try_index(), DeoptId::kNone); join->InheritDeoptTarget(Z, if_false); if_false->UnuseAllInputs(); next = if_false->next(); @@ -1453,7 +1453,7 @@ void ConstantPropagator::Transform() { ASSERT(if_true->parallel_move() == NULL); ASSERT(if_true->loop_info() == NULL); join = new (Z) JoinEntryInstr(if_true->block_id(), if_true->try_index(), - Thread::kNoDeoptId); + DeoptId::kNone); join->InheritDeoptTarget(Z, if_true); if_true->UnuseAllInputs(); next = if_true->next(); @@ -1464,7 +1464,7 @@ void ConstantPropagator::Transform() { // Drop the comparison, which does not have side effects as long // as it is a strict compare (the only one we can determine is // constant with the current analysis). - GotoInstr* jump = new (Z) GotoInstr(join, Thread::kNoDeoptId); + GotoInstr* jump = new (Z) GotoInstr(join, DeoptId::kNone); jump->InheritDeoptTarget(Z, branch); Instruction* previous = branch->previous(); diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc index 60101840b6b..e92b11051c3 100644 --- a/runtime/vm/compiler/backend/flow_graph.cc +++ b/runtime/vm/compiler/backend/flow_graph.cc @@ -12,6 +12,7 @@ #include "vm/compiler/backend/il_printer.h" #include "vm/compiler/backend/range_analysis.h" #include "vm/compiler/cha.h" +#include "vm/compiler/compiler_state.h" #include "vm/compiler/frontend/flow_graph_builder.h" #include "vm/growable_array.h" #include "vm/object_store.h" @@ -507,8 +508,8 @@ FlowGraph::ToCheck FlowGraph::CheckForInstanceCall( // has a null value are excluded above (to avoid throwing an exception // on something valid, like null.hashCode). intptr_t subclass_count = 0; - if (!thread()->cha()->HasOverride(receiver_class, method_name, - &subclass_count)) { + CHA& cha = thread()->compiler_state().cha(); + if (!cha.HasOverride(receiver_class, method_name, &subclass_count)) { if (FLAG_trace_cha) { THR_Print( " **(CHA) Instance call needs no class check since there " @@ -516,7 +517,7 @@ FlowGraph::ToCheck FlowGraph::CheckForInstanceCall( method_name.ToCString(), receiver_class.ToCString()); } if (FLAG_use_cha_deopt) { - thread()->cha()->AddToGuardedClasses(receiver_class, subclass_count); + cha.AddToGuardedClasses(receiver_class, subclass_count); } return receiver_maybe_null ? ToCheck::kCheckNull : ToCheck::kNoCheck; } @@ -1115,7 +1116,7 @@ void FlowGraph::Rename(GrowableArray* live_phis, if (parsed_function().has_arg_desc_var()) { Definition* defn = new SpecialParameterInstr(SpecialParameterInstr::kArgDescriptor, - Thread::kNoDeoptId, graph_entry_); + DeoptId::kNone, graph_entry_); AllocateSSAIndexes(defn); AddToInitialDefinitions(defn); env[ArgumentDescriptorEnvIndex()] = defn; @@ -1193,10 +1194,10 @@ void FlowGraph::RenameRecursive(BlockEntryInstr* block_entry, Definition* param = nullptr; if (raw_exception_var_envindex == i) { param = new SpecialParameterInstr(SpecialParameterInstr::kException, - Thread::kNoDeoptId, catch_entry); + DeoptId::kNone, catch_entry); } else if (raw_stacktrace_var_envindex == i) { param = new SpecialParameterInstr(SpecialParameterInstr::kStackTrace, - Thread::kNoDeoptId, catch_entry); + DeoptId::kNone, catch_entry); } else { param = new (zone()) ParameterInstr(i, block_entry); } @@ -1650,7 +1651,7 @@ void FlowGraph::InsertConversion(Representation from, if (IsUnboxedInteger(from) && IsUnboxedInteger(to)) { const intptr_t deopt_id = (to == kUnboxedInt32) && (deopt_target != NULL) ? deopt_target->DeoptimizationTarget() - : Thread::kNoDeoptId; + : DeoptId::kNone; converted = new (Z) UnboxedIntConverterInstr(from, to, use->CopyWithType(), deopt_id); } else if ((from == kUnboxedInt32) && (to == kUnboxedDouble)) { @@ -1659,13 +1660,13 @@ void FlowGraph::InsertConversion(Representation from, CanConvertInt64ToDouble()) { const intptr_t deopt_id = (deopt_target != NULL) ? deopt_target->DeoptimizationTarget() - : Thread::kNoDeoptId; + : DeoptId::kNone; ASSERT(CanUnboxDouble()); converted = new Int64ToDoubleInstr(use->CopyWithType(), deopt_id); } else if ((from == kTagged) && Boxing::Supports(to)) { const intptr_t deopt_id = (deopt_target != NULL) ? deopt_target->DeoptimizationTarget() - : Thread::kNoDeoptId; + : DeoptId::kNone; converted = UnboxInstr::Create(to, use->CopyWithType(), deopt_id, use->instruction()->speculative_mode()); } else if ((to == kTagged) && Boxing::Supports(from)) { @@ -1677,7 +1678,7 @@ void FlowGraph::InsertConversion(Representation from, // trigger a deoptimization if executed. See #12417 for a discussion. const intptr_t deopt_id = (deopt_target != NULL) ? deopt_target->DeoptimizationTarget() - : Thread::kNoDeoptId; + : DeoptId::kNone; ASSERT(Boxing::Supports(from)); ASSERT(Boxing::Supports(to)); Definition* boxed = BoxInstr::Create(from, use->CopyWithType()); @@ -2277,7 +2278,7 @@ void FlowGraph::OptimizeLeftShiftBitAndSmiOp( // Replace Mint op with Smi op. BinarySmiOpInstr* smi_op = new (Z) BinarySmiOpInstr( Token::kBIT_AND, new (Z) Value(left_instr), new (Z) Value(right_instr), - Thread::kNoDeoptId); // BIT_AND cannot deoptimize. + DeoptId::kNone); // BIT_AND cannot deoptimize. bit_and_instr->ReplaceWith(smi_op, current_iterator); } } @@ -2369,7 +2370,7 @@ void FlowGraph::AppendExtractNthOutputForMerged(Definition* instr, static TargetEntryInstr* NewTarget(FlowGraph* graph, Instruction* inherit) { TargetEntryInstr* target = new (graph->zone()) TargetEntryInstr(graph->allocate_block_id(), - inherit->GetBlock()->try_index(), Thread::kNoDeoptId); + inherit->GetBlock()->try_index(), DeoptId::kNone); target->InheritDeoptTarget(graph->zone(), inherit); return target; } @@ -2377,7 +2378,7 @@ static TargetEntryInstr* NewTarget(FlowGraph* graph, Instruction* inherit) { static JoinEntryInstr* NewJoin(FlowGraph* graph, Instruction* inherit) { JoinEntryInstr* join = new (graph->zone()) JoinEntryInstr(graph->allocate_block_id(), - inherit->GetBlock()->try_index(), Thread::kNoDeoptId); + inherit->GetBlock()->try_index(), DeoptId::kNone); join->InheritDeoptTarget(graph->zone(), inherit); return join; } @@ -2385,7 +2386,7 @@ static JoinEntryInstr* NewJoin(FlowGraph* graph, Instruction* inherit) { static GotoInstr* NewGoto(FlowGraph* graph, JoinEntryInstr* target, Instruction* inherit) { - GotoInstr* got = new (graph->zone()) GotoInstr(target, Thread::kNoDeoptId); + GotoInstr* got = new (graph->zone()) GotoInstr(target, DeoptId::kNone); got->InheritDeoptTarget(graph->zone(), inherit); return got; } @@ -2393,7 +2394,7 @@ static GotoInstr* NewGoto(FlowGraph* graph, static BranchInstr* NewBranch(FlowGraph* graph, ComparisonInstr* cmp, Instruction* inherit) { - BranchInstr* bra = new (graph->zone()) BranchInstr(cmp, Thread::kNoDeoptId); + BranchInstr* bra = new (graph->zone()) BranchInstr(cmp, DeoptId::kNone); bra->InheritDeoptTarget(graph->zone(), inherit); return bra; } @@ -2475,7 +2476,7 @@ JoinEntryInstr* FlowGraph::NewDiamond(Instruction* instruction, StrictCompareInstr* circuit = new (zone()) StrictCompareInstr( inherit->token_pos(), Token::kEQ_STRICT, new (zone()) Value(phi), new (zone()) Value(GetConstant(Bool::True())), false, - Thread::kNoDeoptId); // don't inherit + DeoptId::kNone); // don't inherit // Return new blocks through the second diamond. return NewDiamond(mid_point, inherit, circuit, b_true, b_false); diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc index 36f7ff935c2..ad396ce8e01 100644 --- a/runtime/vm/compiler/backend/flow_graph_compiler.cc +++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc @@ -149,7 +149,7 @@ FlowGraphCompiler::FlowGraphCompiler( // No need to collect extra ICData objects created during compilation. deopt_id_to_ic_data_ = nullptr; } else { - const intptr_t len = thread()->deopt_id(); + const intptr_t len = thread()->compiler_state().deopt_id(); deopt_id_to_ic_data_->EnsureLength(len, nullptr); } ASSERT(assembler != NULL); @@ -425,10 +425,10 @@ void FlowGraphCompiler::EmitCallsiteMetadata(TokenPosition token_pos, AddCurrentDescriptor(kind, deopt_id, token_pos); RecordSafepoint(locs); EmitCatchEntryState(); - if (deopt_id != Thread::kNoDeoptId) { + if (deopt_id != DeoptId::kNone) { // Marks either the continuation point in unoptimized code or the // deoptimization point in optimized code, after call. - const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id); + const intptr_t deopt_id_after = DeoptId::ToDeoptAfter(deopt_id); if (is_optimizing()) { AddDeoptIndexAtCall(deopt_id_after); } else { @@ -1147,7 +1147,7 @@ void FlowGraphCompiler::GenerateCallWithDeopt(TokenPosition token_pos, RawPcDescriptors::Kind kind, LocationSummary* locs) { GenerateCall(token_pos, stub_entry, kind, locs); - const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id); + const intptr_t deopt_id_after = DeoptId::ToDeoptAfter(deopt_id); if (is_optimizing()) { AddDeoptIndexAtCall(deopt_id_after); } else { @@ -2209,7 +2209,7 @@ void ThrowErrorSlowPathCode::EmitNativeCode(FlowGraphCompiler* compiler) { __ CallRuntime(runtime_entry_, num_args_); } // Can't query deopt_id() without checking if instruction can deoptimize... - intptr_t deopt_id = Thread::kNoDeoptId; + intptr_t deopt_id = DeoptId::kNone; if (instruction()->CanDeoptimize() || instruction()->CanBecomeDeoptimizationTarget()) { deopt_id = instruction()->deopt_id(); diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc index c02c1e3e9d7..cd5b0293499 100644 --- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc +++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc @@ -118,7 +118,7 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, // For any outer environment the deopt id is that of the call instruction // which is recorded in the outer environment. builder->AddReturnAddress(current->function(), - Thread::ToDeoptAfter(current->deopt_id()), + DeoptId::ToDeoptAfter(current->deopt_id()), slot_ix++); // The values of outgoing arguments can be changed from the inlined call so @@ -921,7 +921,7 @@ void FlowGraphCompiler::GenerateCall(TokenPosition token_pos, RawPcDescriptors::Kind kind, LocationSummary* locs) { __ BranchLink(stub_entry); - EmitCallsiteMetadata(token_pos, Thread::kNoDeoptId, kind, locs); + EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs); AddStubCallTarget(Code::ZoneHandle(stub_entry.code())); } @@ -930,7 +930,7 @@ void FlowGraphCompiler::GeneratePatchableCall(TokenPosition token_pos, RawPcDescriptors::Kind kind, LocationSummary* locs) { __ BranchLinkPatchable(stub_entry); - EmitCallsiteMetadata(token_pos, Thread::kNoDeoptId, kind, locs); + EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs); } void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id, @@ -1045,7 +1045,7 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall( __ blx(LR); RecordSafepoint(locs, slow_path_argument_count); - const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id); + const intptr_t deopt_id_after = DeoptId::ToDeoptAfter(deopt_id); if (FLAG_precompiled_mode) { // Megamorphic calls may occur in slow path stubs. // If valid use try_index argument. @@ -1053,14 +1053,12 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall( try_index = CurrentTryIndex(); } AddDescriptor(RawPcDescriptors::kOther, assembler()->CodeSize(), - Thread::kNoDeoptId, token_pos, try_index); + DeoptId::kNone, token_pos, try_index); } else if (is_optimizing()) { - AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, - token_pos); + AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos); AddDeoptIndexAtCall(deopt_id_after); } else { - AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, - token_pos); + AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos); // Add deoptimization continuation point after the call and before the // arguments are removed. AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos); @@ -1086,7 +1084,7 @@ void FlowGraphCompiler::EmitSwitchableInstanceCall(const ICData& ic_data, __ LoadUniqueObject(R9, ic_data); __ blx(LR); - EmitCallsiteMetadata(token_pos, Thread::kNoDeoptId, RawPcDescriptors::kOther, + EmitCallsiteMetadata(token_pos, DeoptId::kNone, RawPcDescriptors::kOther, locs); __ Drop(ic_data.CountWithTypeArgs()); } diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc index 3c77a2f85cb..99af7c4a0ba 100644 --- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc +++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc @@ -115,7 +115,7 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, // For any outer environment the deopt id is that of the call instruction // which is recorded in the outer environment. builder->AddReturnAddress(current->function(), - Thread::ToDeoptAfter(current->deopt_id()), + DeoptId::ToDeoptAfter(current->deopt_id()), slot_ix++); // The values of outgoing arguments can be changed from the inlined call so @@ -900,7 +900,7 @@ void FlowGraphCompiler::GenerateCall(TokenPosition token_pos, RawPcDescriptors::Kind kind, LocationSummary* locs) { __ BranchLink(stub_entry); - EmitCallsiteMetadata(token_pos, Thread::kNoDeoptId, kind, locs); + EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs); AddStubCallTarget(Code::ZoneHandle(stub_entry.code())); } @@ -909,7 +909,7 @@ void FlowGraphCompiler::GeneratePatchableCall(TokenPosition token_pos, RawPcDescriptors::Kind kind, LocationSummary* locs) { __ BranchLinkPatchable(stub_entry); - EmitCallsiteMetadata(token_pos, Thread::kNoDeoptId, kind, locs); + EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs); } void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id, @@ -1021,7 +1021,7 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall( __ blr(LR); RecordSafepoint(locs, slow_path_argument_count); - const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id); + const intptr_t deopt_id_after = DeoptId::ToDeoptAfter(deopt_id); if (FLAG_precompiled_mode) { // Megamorphic calls may occur in slow path stubs. // If valid use try_index argument. @@ -1029,14 +1029,12 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall( try_index = CurrentTryIndex(); } AddDescriptor(RawPcDescriptors::kOther, assembler()->CodeSize(), - Thread::kNoDeoptId, token_pos, try_index); + DeoptId::kNone, token_pos, try_index); } else if (is_optimizing()) { - AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, - token_pos); + AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos); AddDeoptIndexAtCall(deopt_id_after); } else { - AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, - token_pos); + AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos); // Add deoptimization continuation point after the call and before the // arguments are removed. AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos); @@ -1061,7 +1059,7 @@ void FlowGraphCompiler::EmitSwitchableInstanceCall(const ICData& ic_data, __ LoadUniqueObject(R5, ic_data); __ blr(TMP); - EmitCallsiteMetadata(token_pos, Thread::kNoDeoptId, RawPcDescriptors::kOther, + EmitCallsiteMetadata(token_pos, DeoptId::kNone, RawPcDescriptors::kOther, locs); __ Drop(ic_data.CountWithTypeArgs()); } diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc b/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc index 9a9e90f708d..8dcebb4b5a8 100644 --- a/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc +++ b/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc @@ -129,7 +129,7 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, // For any outer environment the deopt id is that of the call instruction // which is recorded in the outer environment. builder->AddReturnAddress(current->function(), - Thread::ToDeoptAfter(current->deopt_id()), + DeoptId::ToDeoptAfter(current->deopt_id()), slot_ix++); builder->AddPcMarker(previous->function(), slot_ix++); @@ -179,7 +179,7 @@ void FlowGraphCompiler::RecordAfterCallHelper(TokenPosition token_pos, RecordSafepoint(locs); // Marks either the continuation point in unoptimized code or the // deoptimization point in optimized code, after call. - const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id); + const intptr_t deopt_id_after = DeoptId::ToDeoptAfter(deopt_id); if (is_optimizing()) { // Return/ReturnTOS instruction drops incoming arguments so // we have to drop outgoing arguments from the innermost environment. diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc index 69dae4ca0f1..41c287ca9c8 100644 --- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc +++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc @@ -116,7 +116,7 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, // For any outer environment the deopt id is that of the call instruction // which is recorded in the outer environment. builder->AddReturnAddress(current->function(), - Thread::ToDeoptAfter(current->deopt_id()), + DeoptId::ToDeoptAfter(current->deopt_id()), slot_ix++); // The values of outgoing arguments can be changed from the inlined call so @@ -851,7 +851,7 @@ void FlowGraphCompiler::GenerateCall(TokenPosition token_pos, RawPcDescriptors::Kind kind, LocationSummary* locs) { __ Call(stub_entry); - EmitCallsiteMetadata(token_pos, Thread::kNoDeoptId, kind, locs); + EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs); AddStubCallTarget(Code::ZoneHandle(stub_entry.code())); } @@ -967,9 +967,9 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall( __ call(Address(THR, Thread::megamorphic_call_checked_entry_offset())); __ call(EBX); - AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, token_pos); + AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos); RecordSafepoint(locs, slow_path_argument_count); - const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id); + const intptr_t deopt_id_after = DeoptId::ToDeoptAfter(deopt_id); // Precompilation not implemented on ia32 platform. ASSERT(!FLAG_precompiled_mode); if (is_optimizing()) { diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc index 09d4d95b94e..4542805f6ce 100644 --- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc +++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc @@ -115,7 +115,7 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, // For any outer environment the deopt id is that of the call instruction // which is recorded in the outer environment. builder->AddReturnAddress(current->function(), - Thread::ToDeoptAfter(current->deopt_id()), + DeoptId::ToDeoptAfter(current->deopt_id()), slot_ix++); // The values of outgoing arguments can be changed from the inlined call so @@ -912,7 +912,7 @@ void FlowGraphCompiler::GenerateCall(TokenPosition token_pos, RawPcDescriptors::Kind kind, LocationSummary* locs) { __ Call(stub_entry); - EmitCallsiteMetadata(token_pos, Thread::kNoDeoptId, kind, locs); + EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs); AddStubCallTarget(Code::ZoneHandle(stub_entry.code())); } @@ -921,7 +921,7 @@ void FlowGraphCompiler::GeneratePatchableCall(TokenPosition token_pos, RawPcDescriptors::Kind kind, LocationSummary* locs) { __ CallPatchable(stub_entry); - EmitCallsiteMetadata(token_pos, Thread::kNoDeoptId, kind, locs); + EmitCallsiteMetadata(token_pos, DeoptId::kNone, kind, locs); } void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id, @@ -1037,7 +1037,7 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall( __ call(Address(THR, Thread::megamorphic_call_checked_entry_offset())); RecordSafepoint(locs, slow_path_argument_count); - const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id); + const intptr_t deopt_id_after = DeoptId::ToDeoptAfter(deopt_id); if (FLAG_precompiled_mode) { // Megamorphic calls may occur in slow path stubs. // If valid use try_index argument. @@ -1045,14 +1045,12 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall( try_index = CurrentTryIndex(); } AddDescriptor(RawPcDescriptors::kOther, assembler()->CodeSize(), - Thread::kNoDeoptId, token_pos, try_index); + DeoptId::kNone, token_pos, try_index); } else if (is_optimizing()) { - AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, - token_pos); + AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos); AddDeoptIndexAtCall(deopt_id_after); } else { - AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, - token_pos); + AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos); // Add deoptimization continuation point after the call and before the // arguments are removed. AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos); diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc index 4d5b307606f..145fc3df912 100644 --- a/runtime/vm/compiler/backend/il.cc +++ b/runtime/vm/compiler/backend/il.cc @@ -477,7 +477,7 @@ const ICData* Instruction::GetICData( const ZoneGrowableArray& ic_data_array) const { // The deopt_id can be outside the range of the IC data array for // computations added in the optimizing compiler. - ASSERT(deopt_id_ != Thread::kNoDeoptId); + ASSERT(deopt_id_ != DeoptId::kNone); if (deopt_id_ < ic_data_array.length()) { const ICData* result = ic_data_array[deopt_id_]; #if defined(TAG_IC_DATA) @@ -1046,7 +1046,7 @@ GraphEntryInstr::GraphEntryInstr(const ParsedFunction& parsed_function, intptr_t osr_id) : BlockEntryInstr(0, CatchClauseNode::kInvalidTryIndex, - Thread::Current()->GetNextDeoptId()), + CompilerState::Current().GetNextDeoptId()), parsed_function_(parsed_function), normal_entry_(normal_entry), catch_entries_(), @@ -1322,7 +1322,7 @@ void Instruction::InheritDeoptTargetAfter(FlowGraph* flow_graph, Definition* call, Definition* result) { ASSERT(call->env() != NULL); - deopt_id_ = Thread::ToDeoptAfter(call->deopt_id_); + deopt_id_ = DeoptId::ToDeoptAfter(call->deopt_id_); call->env()->DeepCopyAfterTo( flow_graph->zone(), this, call->ArgumentCount(), flow_graph->constant_dead(), @@ -1537,8 +1537,8 @@ bool BlockEntryInstr::FindOsrEntryAndRelink(GraphEntryInstr* graph_entry, // we can simply jump to the beginning of the block. ASSERT(instr->previous() == this); - GotoInstr* goto_join = - new GotoInstr(AsJoinEntry(), Thread::Current()->GetNextDeoptId()); + GotoInstr* goto_join = new GotoInstr( + AsJoinEntry(), CompilerState::Current().GetNextDeoptId()); goto_join->CopyDeoptIdFrom(*parent); graph_entry->normal_entry()->LinkTo(goto_join); return true; @@ -1754,7 +1754,7 @@ BlockEntryInstr* GotoInstr::SuccessorAt(intptr_t index) const { } void Instruction::Goto(JoinEntryInstr* entry) { - LinkTo(new GotoInstr(entry, Thread::Current()->GetNextDeoptId())); + LinkTo(new GotoInstr(entry, CompilerState::Current().GetNextDeoptId())); } bool UnboxedIntConverterInstr::ComputeCanDeoptimize() const { @@ -2268,7 +2268,7 @@ Definition* CheckedSmiOpInstr::Canonicalize(FlowGraph* flow_graph) { case Token::kBIT_XOR: replacement = new BinarySmiOpInstr( op_kind(), new Value(left()->definition()), - new Value(right()->definition()), Thread::kNoDeoptId); + new Value(right()->definition()), DeoptId::kNone); default: break; } @@ -2308,11 +2308,11 @@ Definition* CheckedSmiComparisonInstr::Canonicalize(FlowGraph* flow_graph) { if (Token::IsRelationalOperator(kind())) { replacement = new RelationalOpInstr( token_pos(), kind(), left()->CopyWithType(), right()->CopyWithType(), - op_cid, Thread::kNoDeoptId, speculative_mode); + op_cid, DeoptId::kNone, speculative_mode); } else if (Token::IsEqualityOperator(kind())) { replacement = new EqualityCompareInstr( token_pos(), kind(), left()->CopyWithType(), right()->CopyWithType(), - op_cid, Thread::kNoDeoptId, speculative_mode); + op_cid, DeoptId::kNone, speculative_mode); } if (replacement != NULL) { if (FLAG_trace_strong_mode_types && (op_cid == kMintCid)) { @@ -2452,7 +2452,7 @@ Definition* BinaryIntegerOpInstr::Canonicalize(FlowGraph* flow_graph) { // the code generator deal with throw on slowpath. break; } - ASSERT(GetDeoptId() != Thread::kNoDeoptId); + ASSERT(GetDeoptId() != DeoptId::kNone); DeoptimizeInstr* deopt = new DeoptimizeInstr(ICData::kDeoptBinarySmiOp, GetDeoptId()); flow_graph->InsertBefore(this, deopt, env(), FlowGraph::kEffect); @@ -2476,7 +2476,7 @@ Definition* BinaryIntegerOpInstr::Canonicalize(FlowGraph* flow_graph) { // the code generator deal with throw on slowpath. break; } - ASSERT(GetDeoptId() != Thread::kNoDeoptId); + ASSERT(GetDeoptId() != DeoptId::kNone); DeoptimizeInstr* deopt = new DeoptimizeInstr(ICData::kDeoptBinarySmiOp, GetDeoptId()); flow_graph->InsertBefore(this, deopt, env(), FlowGraph::kEffect); @@ -2939,8 +2939,7 @@ Definition* UnboxIntegerInstr::Canonicalize(FlowGraph* flow_graph) { UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr( from_representation, representation(), box_defn->value()->CopyWithType(), - (representation() == kUnboxedInt32) ? GetDeoptId() - : Thread::kNoDeoptId); + (representation() == kUnboxedInt32) ? GetDeoptId() : DeoptId::kNone); // TODO(vegorov): marking resulting converter as truncating when // unboxing can't deoptimize is a workaround for the missing // deoptimization environment when we insert converter after @@ -3030,7 +3029,7 @@ Definition* UnboxedIntConverterInstr::Canonicalize(FlowGraph* flow_graph) { UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr( box_defn->from(), representation(), box_defn->value()->CopyWithType(), - (to() == kUnboxedInt32) ? GetDeoptId() : Thread::kNoDeoptId); + (to() == kUnboxedInt32) ? GetDeoptId() : DeoptId::kNone); if ((representation() == kUnboxedInt32) && is_truncating()) { converter->mark_truncating(); } @@ -3294,7 +3293,7 @@ TestCidsInstr::TestCidsInstr(TokenPosition token_pos, set_operation_cid(kObjectCid); #ifdef DEBUG ASSERT(cid_results[0] == kSmiCid); - if (deopt_id == Thread::kNoDeoptId) { + if (deopt_id == DeoptId::kNone) { // The entry for Smi can be special, but all other entries have // to match in the no-deopt case. for (intptr_t i = 4; i < cid_results.length(); i += 2) { @@ -3320,7 +3319,7 @@ Definition* TestCidsInstr::Canonicalize(FlowGraph* flow_graph) { } if (!CanDeoptimize()) { - ASSERT(deopt_id() == Thread::kNoDeoptId); + ASSERT(deopt_id() == DeoptId::kNone); return (data[data.length() - 1] == true_result) ? flow_graph->GetConstant(Bool::False()) : flow_graph->GetConstant(Bool::True()); @@ -4561,7 +4560,7 @@ Environment* Environment::From(Zone* zone, const ParsedFunction& parsed_function) { Environment* env = new (zone) Environment(definitions.length(), fixed_parameter_count, - Thread::kNoDeoptId, parsed_function, NULL); + DeoptId::kNone, parsed_function, NULL); for (intptr_t i = 0; i < definitions.length(); ++i) { env->values_.Add(new (zone) Value(definitions[i])); } @@ -4665,7 +4664,7 @@ ComparisonInstr* RelationalOpInstr::CopyWithNewOperands(Value* new_left, ComparisonInstr* StrictCompareInstr::CopyWithNewOperands(Value* new_left, Value* new_right) { return new StrictCompareInstr(token_pos(), kind(), new_left, new_right, - needs_number_check(), Thread::kNoDeoptId); + needs_number_check(), DeoptId::kNone); } ComparisonInstr* TestSmiInstr::CopyWithNewOperands(Value* new_left, diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h index 4cc04ea7665..46cfc602925 100644 --- a/runtime/vm/compiler/backend/il.h +++ b/runtime/vm/compiler/backend/il.h @@ -8,6 +8,7 @@ #include "vm/allocation.h" #include "vm/ast.h" #include "vm/compiler/backend/locations.h" +#include "vm/compiler/compiler_state.h" #include "vm/compiler/method_recognizer.h" #include "vm/flags.h" #include "vm/growable_array.h" @@ -759,21 +760,6 @@ class CallTargets : public Cids { void MergeIntoRanges(); }; -class DeoptIdScope : public StackResource { - public: - DeoptIdScope(Thread* thread, intptr_t deopt_id) - : StackResource(thread), prev_deopt_id_(thread->deopt_id()) { - thread->set_deopt_id(deopt_id); - } - - ~DeoptIdScope() { thread()->set_deopt_id(prev_deopt_id_); } - - private: - const intptr_t prev_deopt_id_; - - DISALLOW_COPY_AND_ASSIGN(DeoptIdScope); -}; - class Instruction : public ZoneAllocated { public: #define DECLARE_TAG(type, attrs) k##type, @@ -790,7 +776,7 @@ class Instruction : public ZoneAllocated { kNotSpeculative }; - explicit Instruction(intptr_t deopt_id = Thread::kNoDeoptId) + explicit Instruction(intptr_t deopt_id = DeoptId::kNone) : deopt_id_(deopt_id), lifetime_position_(kNoPlaceId), previous_(NULL), @@ -974,7 +960,7 @@ class Instruction : public ZoneAllocated { // to. virtual intptr_t DeoptimizationTarget() const { UNREACHABLE(); - return Thread::kNoDeoptId; + return DeoptId::kNone; } // Returns a replacement for the instruction or NULL if the instruction can @@ -1151,7 +1137,7 @@ template ::Base { public: - explicit TemplateInstruction(intptr_t deopt_id = Thread::kNoDeoptId) + explicit TemplateInstruction(intptr_t deopt_id = DeoptId::kNone) : CSETrait::Base(deopt_id), inputs_() {} virtual intptr_t InputCount() const { return N; } @@ -1855,7 +1841,7 @@ class AliasIdentity : public ValueObject { // Abstract super-class of all instructions that define a value (Bind, Phi). class Definition : public Instruction { public: - explicit Definition(intptr_t deopt_id = Thread::kNoDeoptId); + explicit Definition(intptr_t deopt_id = DeoptId::kNone); // Overridden by definitions that have call counts. virtual intptr_t CallCount() const { @@ -2037,7 +2023,7 @@ template class CSETrait = NoCSE> class TemplateDefinition : public CSETrait::Base { public: - explicit TemplateDefinition(intptr_t deopt_id = Thread::kNoDeoptId) + explicit TemplateDefinition(intptr_t deopt_id = DeoptId::kNone) : CSETrait::Base(deopt_id), inputs_() {} virtual intptr_t InputCount() const { return N; } @@ -2651,7 +2637,7 @@ class ComparisonInstr : public Definition { protected: ComparisonInstr(TokenPosition token_pos, Token::Kind kind, - intptr_t deopt_id = Thread::kNoDeoptId) + intptr_t deopt_id = DeoptId::kNone) : Definition(deopt_id), token_pos_(token_pos), kind_(kind), @@ -2683,7 +2669,7 @@ class TemplateComparison public: TemplateComparison(TokenPosition token_pos, Token::Kind kind, - intptr_t deopt_id = Thread::kNoDeoptId) + intptr_t deopt_id = DeoptId::kNone) : CSETrait::Base(token_pos, kind, deopt_id), @@ -3592,7 +3578,7 @@ class TestCidsInstr : public TemplateComparison<1, NoThrow, Pure> { virtual Definition* Canonicalize(FlowGraph* flow_graph); virtual bool ComputeCanDeoptimize() const { - return GetDeoptId() != Thread::kNoDeoptId; + return GetDeoptId() != DeoptId::kNone; } virtual Representation RequiredInputRepresentation(intptr_t idx) const { @@ -4105,7 +4091,7 @@ class NativeCallInstr : public TemplateDartCall<0> { bool link_lazily, TokenPosition position, PushArgumentsArray* args) - : TemplateDartCall(Thread::kNoDeoptId, + : TemplateDartCall(DeoptId::kNone, 0, Array::null_array(), args, @@ -4495,7 +4481,7 @@ class LoadIndexedInstr : public TemplateDefinition<2, NoThrow> { bool aligned() const { return alignment_ == kAlignedAccess; } virtual bool ComputeCanDeoptimize() const { - return GetDeoptId() != Thread::kNoDeoptId; + return GetDeoptId() != DeoptId::kNone; } virtual Representation representation() const; @@ -4776,7 +4762,7 @@ class InstanceOfInstr : public TemplateDefinition<3, Throws> { // either reside in new space or be in the store buffer. class AllocationInstr : public Definition { public: - explicit AllocationInstr(intptr_t deopt_id = Thread::kNoDeoptId) + explicit AllocationInstr(intptr_t deopt_id = DeoptId::kNone) : Definition(deopt_id) {} // TODO(sjindel): Update these conditions when the incremental write barrier @@ -4792,7 +4778,7 @@ class AllocationInstr : public Definition { template class TemplateAllocation : public AllocationInstr { public: - explicit TemplateAllocation(intptr_t deopt_id = Thread::kNoDeoptId) + explicit TemplateAllocation(intptr_t deopt_id = DeoptId::kNone) : AllocationInstr(deopt_id), inputs_() {} virtual intptr_t InputCount() const { return N; } @@ -5542,7 +5528,7 @@ class BoxInstr : public TemplateDefinition<1, NoThrow, Pure> { virtual CompileType ComputeType() const; virtual bool ComputeCanDeoptimize() const { return false; } - virtual intptr_t DeoptimizationTarget() const { return Thread::kNoDeoptId; } + virtual intptr_t DeoptimizationTarget() const { return DeoptId::kNone; } virtual Representation RequiredInputRepresentation(intptr_t idx) const { ASSERT(idx == 0); diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc index 733efafac5e..2d80341e954 100644 --- a/runtime/vm/compiler/backend/il_arm.cc +++ b/runtime/vm/compiler/backend/il_arm.cc @@ -2957,7 +2957,7 @@ void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { catch_handler_types_, needs_stacktrace()); // On lazy deoptimization we patch the optimized code here to enter the // deoptimization stub. - const intptr_t deopt_id = Thread::ToDeoptAfter(GetDeoptId()); + const intptr_t deopt_id = DeoptId::ToDeoptAfter(GetDeoptId()); if (compiler->is_optimizing()) { compiler->AddDeoptIndexAtCall(deopt_id); } else { diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc index 9862d6e8bb5..de564dfd862 100644 --- a/runtime/vm/compiler/backend/il_arm64.cc +++ b/runtime/vm/compiler/backend/il_arm64.cc @@ -2652,7 +2652,7 @@ void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { catch_handler_types_, needs_stacktrace()); // On lazy deoptimization we patch the optimized code here to enter the // deoptimization stub. - const intptr_t deopt_id = Thread::ToDeoptAfter(GetDeoptId()); + const intptr_t deopt_id = DeoptId::ToDeoptAfter(GetDeoptId()); if (compiler->is_optimizing()) { compiler->AddDeoptIndexAtCall(deopt_id); } else { diff --git a/runtime/vm/compiler/backend/il_dbc.cc b/runtime/vm/compiler/backend/il_dbc.cc index e9de79fe56a..61f92fc2bd9 100644 --- a/runtime/vm/compiler/backend/il_dbc.cc +++ b/runtime/vm/compiler/backend/il_dbc.cc @@ -991,7 +991,7 @@ EMIT_NATIVE_CODE(NativeCall, __ object_pool_wrapper().FindImmediate(static_cast(argc_tag)); __ NativeCall(trampoline_kidx, target_kidx, argc_tag_kidx); compiler->RecordSafepoint(locs()); - compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, + compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos()); } @@ -1040,15 +1040,15 @@ EMIT_NATIVE_CODE(AllocateObject, } __ PushConstant(cls()); __ AllocateT(); - compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, - Thread::kNoDeoptId, token_pos()); + compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, + token_pos()); compiler->RecordSafepoint(locs()); __ PopLocal(locs()->out(0).reg()); } else { __ PushConstant(cls()); __ AllocateT(); - compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, - Thread::kNoDeoptId, token_pos()); + compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, + token_pos()); compiler->RecordSafepoint(locs()); } } else if (compiler->is_optimizing()) { @@ -1069,14 +1069,14 @@ EMIT_NATIVE_CODE(AllocateObject, } const intptr_t kidx = __ AddConstant(cls()); __ Allocate(kidx); - compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, + compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos()); compiler->RecordSafepoint(locs()); __ PopLocal(locs()->out(0).reg()); } else { const intptr_t kidx = __ AddConstant(cls()); __ Allocate(kidx); - compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, + compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos()); compiler->RecordSafepoint(locs()); } @@ -1141,7 +1141,7 @@ EMIT_NATIVE_CODE(AllocateContext, ASSERT(!compiler->is_optimizing()); __ AllocateContext(num_context_variables()); compiler->RecordSafepoint(locs()); - compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, + compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos()); } @@ -1154,7 +1154,7 @@ EMIT_NATIVE_CODE(AllocateUninitializedContext, num_context_variables()); __ AllocateContext(num_context_variables()); compiler->RecordSafepoint(locs()); - compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, + compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos()); __ PopLocal(locs()->out(0).reg()); } @@ -1168,7 +1168,7 @@ EMIT_NATIVE_CODE(CloneContext, } __ CloneContext(); compiler->RecordSafepoint(locs()); - compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, + compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos()); if (compiler->is_optimizing()) { __ PopLocal(locs()->out(0).reg()); @@ -1183,7 +1183,7 @@ EMIT_NATIVE_CODE(CatchBlockEntry, 0) { catch_handler_types_, needs_stacktrace()); // On lazy deoptimization we patch the optimized code here to enter the // deoptimization stub. - const intptr_t deopt_id = Thread::ToDeoptAfter(GetDeoptId()); + const intptr_t deopt_id = DeoptId::ToDeoptAfter(GetDeoptId()); if (compiler->is_optimizing()) { compiler->AddDeoptIndexAtCall(deopt_id); } else { @@ -1630,7 +1630,7 @@ EMIT_NATIVE_CODE(Box, 1, Location::RequiresRegister(), LocationSummary::kCall) { } const intptr_t kidx = __ AddConstant(compiler->double_class()); __ Allocate(kidx); - compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, + compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos()); compiler->RecordSafepoint(locs()); __ PopLocal(out); diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc index 43b4c4332f9..18f3279d331 100644 --- a/runtime/vm/compiler/backend/il_ia32.cc +++ b/runtime/vm/compiler/backend/il_ia32.cc @@ -2534,7 +2534,7 @@ void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { catch_handler_types_, needs_stacktrace()); // On lazy deoptimization we patch the optimized code here to enter the // deoptimization stub. - const intptr_t deopt_id = Thread::ToDeoptAfter(GetDeoptId()); + const intptr_t deopt_id = DeoptId::ToDeoptAfter(GetDeoptId()); if (compiler->is_optimizing()) { compiler->AddDeoptIndexAtCall(deopt_id); } else { diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc index e16521e8402..ed6af4d2d7b 100644 --- a/runtime/vm/compiler/backend/il_printer.cc +++ b/runtime/vm/compiler/backend/il_printer.cc @@ -340,7 +340,7 @@ const char* Instruction::ToCString() const { } void Instruction::PrintTo(BufferFormatter* f) const { - if (GetDeoptId() != Thread::kNoDeoptId) { + if (GetDeoptId() != DeoptId::kNone) { f->Print("%s:%" Pd "(", DebugName(), GetDeoptId()); } else { f->Print("%s(", DebugName()); @@ -359,7 +359,7 @@ void Instruction::PrintOperandsTo(BufferFormatter* f) const { void Definition::PrintTo(BufferFormatter* f) const { PrintUse(f, *this); if (HasSSATemp() || HasTemp()) f->Print(" <- "); - if (GetDeoptId() != Thread::kNoDeoptId) { + if (GetDeoptId() != DeoptId::kNone) { f->Print("%s:%" Pd "(", DebugName(), GetDeoptId()); } else { f->Print("%s(", DebugName()); @@ -562,10 +562,10 @@ void TestCidsInstr::PrintOperandsTo(BufferFormatter* f) const { } f->Print("] "); if (CanDeoptimize()) { - ASSERT(deopt_id() != Thread::kNoDeoptId); + ASSERT(deopt_id() != DeoptId::kNone); f->Print("else deoptimize "); } else { - ASSERT(deopt_id() == Thread::kNoDeoptId); + ASSERT(deopt_id() == DeoptId::kNone); f->Print("else %s ", cid_results()[length - 1] != 0 ? "false" : "true"); } } @@ -1075,7 +1075,7 @@ void GotoInstr::PrintTo(BufferFormatter* f) const { parallel_move()->PrintTo(f); f->Print(" "); } - if (GetDeoptId() != Thread::kNoDeoptId) { + if (GetDeoptId() != DeoptId::kNone) { f->Print("goto:%" Pd " B%" Pd "", GetDeoptId(), successor()->block_id()); } else { f->Print("goto: B%" Pd "", successor()->block_id()); @@ -1083,7 +1083,7 @@ void GotoInstr::PrintTo(BufferFormatter* f) const { } void IndirectGotoInstr::PrintTo(BufferFormatter* f) const { - if (GetDeoptId() != Thread::kNoDeoptId) { + if (GetDeoptId() != DeoptId::kNone) { f->Print("igoto:%" Pd "(", GetDeoptId()); } else { f->Print("igoto:("); diff --git a/runtime/vm/compiler/backend/il_test.cc b/runtime/vm/compiler/backend/il_test.cc index 8fb8da0a0c6..bf20fb64d24 100644 --- a/runtime/vm/compiler/backend/il_test.cc +++ b/runtime/vm/compiler/backend/il_test.cc @@ -9,19 +9,19 @@ namespace dart { TEST_CASE(InstructionTests) { TargetEntryInstr* target_instr = new TargetEntryInstr( - 1, CatchClauseNode::kInvalidTryIndex, Thread::kNoDeoptId); + 1, CatchClauseNode::kInvalidTryIndex, DeoptId::kNone); EXPECT(target_instr->IsBlockEntry()); EXPECT(!target_instr->IsDefinition()); SpecialParameterInstr* context = new SpecialParameterInstr( - SpecialParameterInstr::kContext, Thread::kNoDeoptId, target_instr); + SpecialParameterInstr::kContext, DeoptId::kNone, target_instr); EXPECT(context->IsDefinition()); EXPECT(!context->IsBlockEntry()); EXPECT(context->GetBlock() == target_instr); } TEST_CASE(OptimizationTests) { - JoinEntryInstr* join = new JoinEntryInstr( - 1, CatchClauseNode::kInvalidTryIndex, Thread::kNoDeoptId); + JoinEntryInstr* join = + new JoinEntryInstr(1, CatchClauseNode::kInvalidTryIndex, DeoptId::kNone); Definition* def1 = new PhiInstr(join, 0); Definition* def2 = new PhiInstr(join, 0); diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc index 6aab93648bb..313be83fc8a 100644 --- a/runtime/vm/compiler/backend/il_x64.cc +++ b/runtime/vm/compiler/backend/il_x64.cc @@ -2657,7 +2657,7 @@ void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { catch_handler_types_, needs_stacktrace()); // On lazy deoptimization we patch the optimized code here to enter the // deoptimization stub. - const intptr_t deopt_id = Thread::ToDeoptAfter(GetDeoptId()); + const intptr_t deopt_id = DeoptId::ToDeoptAfter(GetDeoptId()); if (compiler->is_optimizing()) { compiler->AddDeoptIndexAtCall(deopt_id); } else { diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc index c6259ac36d7..ccacbd2e390 100644 --- a/runtime/vm/compiler/backend/inliner.cc +++ b/runtime/vm/compiler/backend/inliner.cc @@ -925,7 +925,7 @@ class CallSiteInliner : public ValueObject { // Loading occured while parsing. We need to abort here because // state changed while compiling. Compiler::AbortBackgroundCompilation( - Thread::kNoDeoptId, "Loading occured while parsing in inliner"); + DeoptId::kNone, "Loading occured while parsing in inliner"); } } @@ -936,7 +936,7 @@ class CallSiteInliner : public ValueObject { function.RestoreICDataMap(ic_data_array, clone_ic_data); if (Compiler::IsBackgroundCompilation() && (function.ic_data_array() == Array::null())) { - Compiler::AbortBackgroundCompilation(Thread::kNoDeoptId, + Compiler::AbortBackgroundCompilation(DeoptId::kNone, "ICData cleared while inlining"); } @@ -1667,9 +1667,9 @@ bool PolymorphicInliner::CheckInlinedDuplicate(const Function& target) { } // Create a new target with the join as unconditional successor. TargetEntryInstr* new_target = new TargetEntryInstr( - AllocateBlockId(), old_target->try_index(), Thread::kNoDeoptId); + AllocateBlockId(), old_target->try_index(), DeoptId::kNone); new_target->InheritDeoptTarget(zone(), new_join); - GotoInstr* new_goto = new (Z) GotoInstr(new_join, Thread::kNoDeoptId); + GotoInstr* new_goto = new (Z) GotoInstr(new_join, DeoptId::kNone); new_goto->InheritDeoptTarget(zone(), new_join); new_target->LinkTo(new_goto); new_target->set_last_instruction(new_goto); @@ -1768,7 +1768,7 @@ bool PolymorphicInliner::TryInlineRecognizedMethod(intptr_t receiver_cid, new (Z) InlineExitCollector(owner_->caller_graph(), call_); ReturnInstr* result = new (Z) ReturnInstr(call_->instance_call()->token_pos(), - new (Z) Value(last->AsDefinition()), Thread::kNoDeoptId); + new (Z) Value(last->AsDefinition()), DeoptId::kNone); owner_->caller_graph()->AppendTo( last, result, call_->env(), // Return can become deoptimization target. @@ -1798,7 +1798,7 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() { // Start with a fresh target entry. TargetEntryInstr* entry = new (Z) TargetEntryInstr( - AllocateBlockId(), try_idx, Thread::Current()->GetNextDeoptId()); + AllocateBlockId(), try_idx, CompilerState::Current().GetNextDeoptId()); entry->InheritDeoptTarget(zone(), call_); // This function uses a cursor (a pointer to the 'current' instruction) to @@ -1863,7 +1863,7 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() { // the join. JoinEntryInstr* join = callee_entry->AsJoinEntry(); ASSERT(join->dominator() != NULL); - GotoInstr* goto_join = new GotoInstr(join, Thread::kNoDeoptId); + GotoInstr* goto_join = new GotoInstr(join, DeoptId::kNone); goto_join->InheritDeoptTarget(zone(), join); cursor->LinkTo(goto_join); current_block->set_last_instruction(goto_join); @@ -1896,13 +1896,13 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() { new Value(load_cid), new Value(cid_constant_end), kSmiCid, call_->deopt_id()); BranchInstr* branch_top = upper_limit_branch = - new BranchInstr(compare_top, Thread::kNoDeoptId); + new BranchInstr(compare_top, DeoptId::kNone); branch_top->InheritDeoptTarget(zone(), call_); cursor = AppendInstruction(cursor, branch_top); current_block->set_last_instruction(branch_top); - TargetEntryInstr* below_target = new TargetEntryInstr( - AllocateBlockId(), try_idx, Thread::kNoDeoptId); + TargetEntryInstr* below_target = + new TargetEntryInstr(AllocateBlockId(), try_idx, DeoptId::kNone); below_target->InheritDeoptTarget(zone(), call_); current_block->AddDominatedBlock(below_target); cursor = current_block = below_target; @@ -1912,13 +1912,13 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() { call_->instance_call()->token_pos(), Token::kGTE, new Value(load_cid), new Value(cid_constant), kSmiCid, call_->deopt_id()); - branch = new BranchInstr(compare_bottom, Thread::kNoDeoptId); + branch = new BranchInstr(compare_bottom, DeoptId::kNone); } else { StrictCompareInstr* compare = new StrictCompareInstr( call_->instance_call()->token_pos(), Token::kEQ_STRICT, new Value(load_cid), new Value(cid_constant), - /* number_check = */ false, Thread::kNoDeoptId); - branch = new BranchInstr(compare, Thread::kNoDeoptId); + /* number_check = */ false, DeoptId::kNone); + branch = new BranchInstr(compare, DeoptId::kNone); } branch->InheritDeoptTarget(zone(), call_); @@ -1949,10 +1949,10 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() { JoinEntryInstr* join = callee_entry->AsJoinEntry(); ASSERT(join != NULL); ASSERT(join->dominator() != NULL); - true_target = new TargetEntryInstr(AllocateBlockId(), try_idx, - Thread::kNoDeoptId); + true_target = + new TargetEntryInstr(AllocateBlockId(), try_idx, DeoptId::kNone); true_target->InheritDeoptTarget(zone(), join); - GotoInstr* goto_join = new GotoInstr(join, Thread::kNoDeoptId); + GotoInstr* goto_join = new GotoInstr(join, DeoptId::kNone); goto_join->InheritDeoptTarget(zone(), join); true_target->LinkTo(goto_join); true_target->set_last_instruction(goto_join); @@ -1964,7 +1964,7 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() { // fall-through code below for non-inlined variants. TargetEntryInstr* false_target = - new TargetEntryInstr(AllocateBlockId(), try_idx, Thread::kNoDeoptId); + new TargetEntryInstr(AllocateBlockId(), try_idx, DeoptId::kNone); false_target->InheritDeoptTarget(zone(), call_); *branch->false_successor_address() = false_target; cid_test_entry_block->AddDominatedBlock(false_target); @@ -1975,14 +1975,14 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() { // If we tested against a range of Cids there are two different tests // that can go to the no-cid-match target. JoinEntryInstr* join = - new JoinEntryInstr(AllocateBlockId(), try_idx, Thread::kNoDeoptId); - TargetEntryInstr* false_target2 = new TargetEntryInstr( - AllocateBlockId(), try_idx, Thread::kNoDeoptId); + new JoinEntryInstr(AllocateBlockId(), try_idx, DeoptId::kNone); + TargetEntryInstr* false_target2 = + new TargetEntryInstr(AllocateBlockId(), try_idx, DeoptId::kNone); *upper_limit_branch->false_successor_address() = false_target2; cid_test_entry_block->AddDominatedBlock(false_target2); cid_test_entry_block->AddDominatedBlock(join); - GotoInstr* goto_1 = new GotoInstr(join, Thread::kNoDeoptId); - GotoInstr* goto_2 = new GotoInstr(join, Thread::kNoDeoptId); + GotoInstr* goto_1 = new GotoInstr(join, DeoptId::kNone); + GotoInstr* goto_2 = new GotoInstr(join, DeoptId::kNone); false_target->LinkTo(goto_1); false_target2->LinkTo(goto_2); false_target->set_last_instruction(goto_1); @@ -2017,7 +2017,7 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() { fallback_call->set_total_call_count(call_->CallCount()); ReturnInstr* fallback_return = new ReturnInstr(call_->instance_call()->token_pos(), - new Value(fallback_call), Thread::kNoDeoptId); + new Value(fallback_call), DeoptId::kNone); fallback_return->InheritDeoptTargetAfter(owner_->caller_graph(), call_, fallback_call); AppendInstruction(AppendInstruction(cursor, fallback_call), @@ -2358,20 +2358,20 @@ static bool InlineGetIndexed(FlowGraph* flow_graph, Definition* array = receiver; Definition* index = call->ArgumentAt(1); - *entry = new (Z) - TargetEntryInstr(flow_graph->allocate_block_id(), - call->GetBlock()->try_index(), Thread::kNoDeoptId); + *entry = + new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), + call->GetBlock()->try_index(), DeoptId::kNone); (*entry)->InheritDeoptTarget(Z, call); Instruction* cursor = *entry; array_cid = PrepareInlineIndexedOp(flow_graph, call, array_cid, &array, index, &cursor, can_speculate); - intptr_t deopt_id = Thread::kNoDeoptId; + intptr_t deopt_id = DeoptId::kNone; if ((array_cid == kTypedDataInt32ArrayCid) || (array_cid == kTypedDataUint32ArrayCid)) { // Deoptimization may be needed if result does not always fit in a Smi. - deopt_id = (kSmiBits >= 32) ? Thread::kNoDeoptId : call->deopt_id(); + deopt_id = (kSmiBits >= 32) ? DeoptId::kNone : call->deopt_id(); } // Array load and return. @@ -2380,14 +2380,14 @@ static bool InlineGetIndexed(FlowGraph* flow_graph, LoadIndexedInstr(new (Z) Value(array), new (Z) Value(index), index_scale, array_cid, kAlignedAccess, deopt_id, call->token_pos()); *last = load; - cursor = flow_graph->AppendTo( - cursor, load, deopt_id != Thread::kNoDeoptId ? call->env() : NULL, - FlowGraph::kValue); + cursor = flow_graph->AppendTo(cursor, load, + deopt_id != DeoptId::kNone ? call->env() : NULL, + FlowGraph::kValue); if (array_cid == kTypedDataFloat32ArrayCid) { *last = new (Z) FloatToDoubleInstr(new (Z) Value(load), deopt_id); flow_graph->AppendTo(cursor, *last, - deopt_id != Thread::kNoDeoptId ? call->env() : NULL, + deopt_id != DeoptId::kNone ? call->env() : NULL, FlowGraph::kValue); } return true; @@ -2409,9 +2409,9 @@ static bool InlineSetIndexed(FlowGraph* flow_graph, Definition* index = call->ArgumentAt(1); Definition* stored_value = call->ArgumentAt(2); - *entry = new (Z) - TargetEntryInstr(flow_graph->allocate_block_id(), - call->GetBlock()->try_index(), Thread::kNoDeoptId); + *entry = + new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), + call->GetBlock()->try_index(), DeoptId::kNone); (*entry)->InheritDeoptTarget(Z, call); Instruction* cursor = *entry; if (flow_graph->isolate()->argument_type_checks() && @@ -2552,9 +2552,9 @@ static bool InlineDoubleOp(FlowGraph* flow_graph, Definition* left = receiver; Definition* right = call->ArgumentAt(1); - *entry = new (Z) - TargetEntryInstr(flow_graph->allocate_block_id(), - call->GetBlock()->try_index(), Thread::kNoDeoptId); + *entry = + new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), + call->GetBlock()->try_index(), DeoptId::kNone); (*entry)->InheritDeoptTarget(Z, call); // Arguments are checked. No need for class check. BinaryDoubleOpInstr* double_bin_op = new (Z) @@ -2576,9 +2576,9 @@ static bool InlineDoubleTestOp(FlowGraph* flow_graph, return false; } - *entry = new (Z) - TargetEntryInstr(flow_graph->allocate_block_id(), - call->GetBlock()->try_index(), Thread::kNoDeoptId); + *entry = + new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), + call->GetBlock()->try_index(), DeoptId::kNone); (*entry)->InheritDeoptTarget(Z, call); // Arguments are checked. No need for class check. @@ -2598,9 +2598,9 @@ static bool InlineSmiBitAndFromSmi(FlowGraph* flow_graph, Definition* left = receiver; Definition* right = call->ArgumentAt(1); - *entry = new (Z) - TargetEntryInstr(flow_graph->allocate_block_id(), - call->GetBlock()->try_index(), Thread::kNoDeoptId); + *entry = + new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), + call->GetBlock()->try_index(), DeoptId::kNone); (*entry)->InheritDeoptTarget(Z, call); // Right arguments is known to be smi: other._bitAndFromSmi(this); BinarySmiOpInstr* smi_op = @@ -2622,9 +2622,9 @@ static bool InlineGrowableArraySetter(FlowGraph* flow_graph, Definition* array = receiver; Definition* value = call->ArgumentAt(1); - *entry = new (Z) - TargetEntryInstr(flow_graph->allocate_block_id(), - call->GetBlock()->try_index(), Thread::kNoDeoptId); + *entry = + new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), + call->GetBlock()->try_index(), DeoptId::kNone); (*entry)->InheritDeoptTarget(Z, call); // This is an internal method, no need to check argument types. @@ -2755,8 +2755,8 @@ static LoadIndexedInstr* NewLoad(FlowGraph* flow_graph, intptr_t view_cid) { return new (Z) LoadIndexedInstr(new (Z) Value(array), new (Z) Value(index), 1, // Index scale - view_cid, kUnalignedAccess, - Thread::kNoDeoptId, call->token_pos()); + view_cid, kUnalignedAccess, DeoptId::kNone, + call->token_pos()); } static bool InlineByteArrayBaseLoad(FlowGraph* flow_graph, @@ -2781,9 +2781,9 @@ static bool InlineByteArrayBaseLoad(FlowGraph* flow_graph, Definition* array = receiver; Definition* index = call->ArgumentAt(1); - *entry = new (Z) - TargetEntryInstr(flow_graph->allocate_block_id(), - call->GetBlock()->try_index(), Thread::kNoDeoptId); + *entry = + new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), + call->GetBlock()->try_index(), DeoptId::kNone); (*entry)->InheritDeoptTarget(Z, call); Instruction* cursor = *entry; @@ -2815,13 +2815,13 @@ static bool InlineByteArrayBaseLoad(FlowGraph* flow_graph, ASSERT(block_external->next() == array); flow_graph->InsertAfter( block_external->next(), load1, - call->deopt_id() != Thread::kNoDeoptId ? call->env() : nullptr, + call->deopt_id() != DeoptId::kNone ? call->env() : nullptr, FlowGraph::kValue); LoadIndexedInstr* load2 = NewLoad(flow_graph, call, receiver, index, view_cid); flow_graph->InsertAfter( block_internal, load2, - call->deopt_id() != Thread::kNoDeoptId ? call->env() : nullptr, + call->deopt_id() != DeoptId::kNone ? call->env() : nullptr, FlowGraph::kValue); // Construct phi of external and internal load. *last = flow_graph->AddPhi(cursor->AsJoinEntry(), load1, load2); @@ -2831,14 +2831,14 @@ static bool InlineByteArrayBaseLoad(FlowGraph* flow_graph, LoadIndexedInstr* load = NewLoad(flow_graph, call, array, index, view_cid); flow_graph->AppendTo( cursor, load, - call->deopt_id() != Thread::kNoDeoptId ? call->env() : nullptr, + call->deopt_id() != DeoptId::kNone ? call->env() : nullptr, FlowGraph::kValue); cursor = *last = load; } if (view_cid == kTypedDataFloat32ArrayCid) { *last = new (Z) FloatToDoubleInstr(new (Z) Value((*last)->AsDefinition()), - Thread::kNoDeoptId); + DeoptId::kNone); flow_graph->AppendTo(cursor, *last, nullptr, FlowGraph::kValue); } return true; @@ -2879,9 +2879,9 @@ static bool InlineByteArrayBaseStore(FlowGraph* flow_graph, Definition* array = receiver; Definition* index = call->ArgumentAt(1); - *entry = new (Z) - TargetEntryInstr(flow_graph->allocate_block_id(), - call->GetBlock()->try_index(), Thread::kNoDeoptId); + *entry = + new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), + call->GetBlock()->try_index(), DeoptId::kNone); (*entry)->InheritDeoptTarget(Z, call); Instruction* cursor = *entry; @@ -3029,12 +3029,12 @@ static bool InlineByteArrayBaseStore(FlowGraph* flow_graph, flow_graph->InsertAfter( block_external->next(), NewStore(flow_graph, call, array, index, stored_value, view_cid), - call->deopt_id() != Thread::kNoDeoptId ? call->env() : nullptr, + call->deopt_id() != DeoptId::kNone ? call->env() : nullptr, FlowGraph::kEffect); flow_graph->InsertAfter( block_internal, NewStore(flow_graph, call, receiver, index, stored_value, view_cid), - call->deopt_id() != Thread::kNoDeoptId ? call->env() : nullptr, + call->deopt_id() != DeoptId::kNone ? call->env() : nullptr, FlowGraph::kEffect); *last = cursor; } else { @@ -3044,7 +3044,7 @@ static bool InlineByteArrayBaseStore(FlowGraph* flow_graph, NewStore(flow_graph, call, array, index, stored_value, view_cid); flow_graph->AppendTo( cursor, store, - call->deopt_id() != Thread::kNoDeoptId ? call->env() : nullptr, + call->deopt_id() != DeoptId::kNone ? call->env() : nullptr, FlowGraph::kEffect); *last = store; } @@ -3083,7 +3083,7 @@ static Definition* PrepareInlineStringIndexOp(FlowGraph* flow_graph, LoadIndexedInstr* load_indexed = new (Z) LoadIndexedInstr( new (Z) Value(str), new (Z) Value(index), Instance::ElementSizeFor(cid), - cid, kAlignedAccess, Thread::kNoDeoptId, call->token_pos()); + cid, kAlignedAccess, DeoptId::kNone, call->token_pos()); cursor = flow_graph->AppendTo(cursor, load_indexed, NULL, FlowGraph::kValue); ASSERT(cursor == load_indexed); @@ -3102,9 +3102,9 @@ static bool InlineStringBaseCharAt(FlowGraph* flow_graph, Definition* str = receiver; Definition* index = call->ArgumentAt(1); - *entry = new (Z) - TargetEntryInstr(flow_graph->allocate_block_id(), - call->GetBlock()->try_index(), Thread::kNoDeoptId); + *entry = + new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), + call->GetBlock()->try_index(), DeoptId::kNone); (*entry)->InheritDeoptTarget(Z, call); *last = PrepareInlineStringIndexOp(flow_graph, call, cid, str, index, *entry); @@ -3134,9 +3134,9 @@ static bool InlineStringCodeUnitAt(FlowGraph* flow_graph, Definition* str = receiver; Definition* index = call->ArgumentAt(1); - *entry = new (Z) - TargetEntryInstr(flow_graph->allocate_block_id(), - call->GetBlock()->try_index(), Thread::kNoDeoptId); + *entry = + new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), + call->GetBlock()->try_index(), DeoptId::kNone); (*entry)->InheritDeoptTarget(Z, call); *last = PrepareInlineStringIndexOp(flow_graph, call, cid, str, index, *entry); @@ -3318,9 +3318,9 @@ static bool InlineSimdOp(FlowGraph* flow_graph, if (!ShouldInlineSimd()) { return false; } - *entry = new (Z) - TargetEntryInstr(flow_graph->allocate_block_id(), - call->GetBlock()->try_index(), Thread::kNoDeoptId); + *entry = + new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), + call->GetBlock()->try_index(), DeoptId::kNone); (*entry)->InheritDeoptTarget(Z, call); Instruction* cursor = *entry; switch (kind) { @@ -3373,10 +3373,9 @@ static bool InlineSimdOp(FlowGraph* flow_graph, *last = SimdOpInstr::CreateFromCall(Z, kind, receiver, call); break; } - flow_graph->AppendTo( - cursor, *last, - call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, - FlowGraph::kValue); + flow_graph->AppendTo(cursor, *last, + call->deopt_id() != DeoptId::kNone ? call->env() : NULL, + FlowGraph::kValue); return true; } @@ -3388,9 +3387,9 @@ static bool InlineMathCFunction(FlowGraph* flow_graph, if (!CanUnboxDouble()) { return false; } - *entry = new (Z) - TargetEntryInstr(flow_graph->allocate_block_id(), - call->GetBlock()->try_index(), Thread::kNoDeoptId); + *entry = + new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), + call->GetBlock()->try_index(), DeoptId::kNone); (*entry)->InheritDeoptTarget(Z, call); Instruction* cursor = *entry; @@ -3412,10 +3411,9 @@ static bool InlineMathCFunction(FlowGraph* flow_graph, break; } } - flow_graph->AppendTo( - cursor, *last, - call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, - FlowGraph::kValue); + flow_graph->AppendTo(cursor, *last, + call->deopt_id() != DeoptId::kNone ? call->env() : NULL, + FlowGraph::kValue); return true; } @@ -3425,7 +3423,7 @@ static Instruction* InlineMul(FlowGraph* flow_graph, Definition* y) { BinaryInt64OpInstr* mul = new (Z) BinaryInt64OpInstr(Token::kMUL, new (Z) Value(x), new (Z) Value(y), - Thread::kNoDeoptId, Instruction::kNotSpeculative); + DeoptId::kNone, Instruction::kNotSpeculative); return flow_graph->AppendTo(cursor, mul, nullptr, FlowGraph::kValue); } @@ -3454,7 +3452,7 @@ static bool InlineMathIntPow(FlowGraph* flow_graph, // Lazily construct entry only in this case. *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), - call->GetBlock()->try_index(), Thread::kNoDeoptId); + call->GetBlock()->try_index(), DeoptId::kNone); (*entry)->InheritDeoptTarget(Z, call); Definition* x_def = x->definition(); Definition* square = @@ -3868,7 +3866,7 @@ bool FlowGraphInliner::TryInlineRecognizedMethod( case MethodRecognizer::kObjectConstructor: { *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), - call->GetBlock()->try_index(), Thread::kNoDeoptId); + call->GetBlock()->try_index(), DeoptId::kNone); (*entry)->InheritDeoptTarget(Z, call); ASSERT(!call->HasUses()); *last = NULL; // Empty body. @@ -3886,13 +3884,13 @@ bool FlowGraphInliner::TryInlineRecognizedMethod( const auto num_elements = new (Z) Value(call->ArgumentAt(1)); *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), - call->GetBlock()->try_index(), Thread::kNoDeoptId); + call->GetBlock()->try_index(), DeoptId::kNone); (*entry)->InheritDeoptTarget(Z, call); *last = new (Z) CreateArrayInstr(call->token_pos(), type, num_elements, call->deopt_id()); flow_graph->AppendTo( *entry, *last, - call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, + call->deopt_id() != DeoptId::kNone ? call->env() : NULL, FlowGraph::kValue); return true; } @@ -3903,15 +3901,15 @@ bool FlowGraphInliner::TryInlineRecognizedMethod( if (IsSmiValue(num_elements, &length)) { if (length >= 0 && length <= Array::kMaxElements) { Value* type = new (Z) Value(call->ArgumentAt(0)); - *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), - call->GetBlock()->try_index(), - Thread::kNoDeoptId); + *entry = new (Z) + TargetEntryInstr(flow_graph->allocate_block_id(), + call->GetBlock()->try_index(), DeoptId::kNone); (*entry)->InheritDeoptTarget(Z, call); *last = new (Z) CreateArrayInstr(call->token_pos(), type, num_elements, call->deopt_id()); flow_graph->AppendTo( *entry, *last, - call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, + call->deopt_id() != DeoptId::kNone ? call->env() : NULL, FlowGraph::kValue); return true; } @@ -3940,12 +3938,12 @@ bool FlowGraphInliner::TryInlineRecognizedMethod( if (!type.IsNull()) { *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), - call->GetBlock()->try_index(), Thread::kNoDeoptId); + call->GetBlock()->try_index(), DeoptId::kNone); (*entry)->InheritDeoptTarget(Z, call); *last = new (Z) ConstantInstr(type); flow_graph->AppendTo( *entry, *last, - call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, + call->deopt_id() != DeoptId::kNone ? call->env() : NULL, FlowGraph::kValue); return true; } @@ -3957,7 +3955,7 @@ bool FlowGraphInliner::TryInlineRecognizedMethod( // range. *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), - call->GetBlock()->try_index(), Thread::kNoDeoptId); + call->GetBlock()->try_index(), DeoptId::kNone); (*entry)->InheritDeoptTarget(Z, call); Definition* str = call->ArgumentAt(0); Definition* index = call->ArgumentAt(1); @@ -3970,7 +3968,7 @@ bool FlowGraphInliner::TryInlineRecognizedMethod( call->deopt_id(), call->token_pos()); flow_graph->AppendTo( *entry, *last, - call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, + call->deopt_id() != DeoptId::kNone ? call->env() : NULL, FlowGraph::kEffect); return true; } diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc index 95e5a72e61b..23195323402 100644 --- a/runtime/vm/compiler/backend/range_analysis.cc +++ b/runtime/vm/compiler/backend/range_analysis.cc @@ -983,7 +983,7 @@ class BoundsCheckGeneralizer { for (intptr_t i = 0; i < non_positive_symbols.length(); i++) { CheckArrayBoundInstr* precondition = new CheckArrayBoundInstr( new Value(max_smi), new Value(non_positive_symbols[i]), - Thread::kNoDeoptId); + DeoptId::kNone); precondition->mark_generalized(); precondition = scheduler_.Emit(precondition, check); if (precondition == NULL) { @@ -997,7 +997,7 @@ class BoundsCheckGeneralizer { CheckArrayBoundInstr* new_check = new CheckArrayBoundInstr( new Value(UnwrapConstraint(check->length()->definition())), - new Value(upper_bound), Thread::kNoDeoptId); + new Value(upper_bound), DeoptId::kNone); new_check->mark_generalized(); if (new_check->IsRedundant(array_length)) { if (FLAG_trace_range_analysis) { @@ -1035,7 +1035,7 @@ class BoundsCheckGeneralizer { Definition* left, Definition* right) { return new BinarySmiOpInstr(op_kind, new Value(left), new Value(right), - Thread::kNoDeoptId); + DeoptId::kNone); } BinarySmiOpInstr* MakeBinaryOp(Token::Kind op_kind, diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc index 841ca91ff4f..b5aaa9537ec 100644 --- a/runtime/vm/compiler/backend/type_propagator.cc +++ b/runtime/vm/compiler/backend/type_propagator.cc @@ -8,7 +8,7 @@ #include "vm/bit_vector.h" #include "vm/compiler/backend/il_printer.h" -#include "vm/compiler/cha.h" +#include "vm/compiler/compiler_state.h" #include "vm/object_store.h" #include "vm/regexp_assembler.h" #include "vm/resolver.h" @@ -695,7 +695,7 @@ intptr_t CompileType::ToNullableCid() { } else if (type_->HasResolvedTypeClass()) { const Class& type_class = Class::Handle(type_->type_class()); Thread* thread = Thread::Current(); - CHA* cha = thread->cha(); + CHA& cha = thread->compiler_state().cha(); // Don't infer a cid from an abstract type since there can be multiple // compatible classes with different cids. if (!type_class.is_abstract() && !CHA::IsImplemented(type_class) && @@ -710,7 +710,7 @@ intptr_t CompileType::ToNullableCid() { type_class.ToCString()); } if (FLAG_use_cha_deopt) { - cha->AddToGuardedClasses(type_class, /*subclass_count=*/0); + cha.AddToGuardedClasses(type_class, /*subclass_count=*/0); } cid_ = type_class.id(); } else { @@ -968,8 +968,9 @@ CompileType ParameterInstr::ComputeType() const { type_class.ToCString()); } if (FLAG_use_cha_deopt) { - thread->cha()->AddToGuardedClasses(type_class, - /*subclass_count=*/0); + thread->compiler_state().cha().AddToGuardedClasses( + type_class, + /*subclass_count=*/0); } cid = type_class.id(); } diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc index a7da1b2e64b..b119b074757 100644 --- a/runtime/vm/compiler/call_specializer.cc +++ b/runtime/vm/compiler/call_specializer.cc @@ -8,6 +8,7 @@ #include "vm/compiler/backend/flow_graph_compiler.h" #include "vm/compiler/backend/inliner.h" #include "vm/compiler/cha.h" +#include "vm/compiler/compiler_state.h" #include "vm/cpu.h" namespace dart { @@ -557,7 +558,7 @@ bool CallSpecializer::TryReplaceWithEqualityOp(InstanceCallInstr* call, StrictCompareInstr* comp = new (Z) StrictCompareInstr(call->token_pos(), Token::kEQ_STRICT, new (Z) Value(left), new (Z) Value(right), - /* number_check = */ false, Thread::kNoDeoptId); + /* number_check = */ false, DeoptId::kNone); ReplaceCall(call, comp); return true; } @@ -1310,7 +1311,8 @@ bool CallSpecializer::TypeCheckAsClassEquality(const AbstractType& type) { type_class.ToCString()); } if (FLAG_use_cha_deopt) { - thread()->cha()->AddToGuardedClasses(type_class, /*subclass_count=*/0); + thread()->compiler_state().cha().AddToGuardedClasses( + type_class, /*subclass_count=*/0); } } else { return false; @@ -1357,7 +1359,7 @@ bool CallSpecializer::TryOptimizeInstanceOfUsingStaticTypes( type.IsNullType() ? Token::kEQ_STRICT : Token::kNE_STRICT, left_value->CopyWithType(Z), new (Z) Value(flow_graph()->constant_null()), - /* number_check = */ false, Thread::kNoDeoptId); + /* number_check = */ false, DeoptId::kNone); if (FLAG_trace_strong_mode_types) { THR_Print("[Strong mode] replacing %s with %s (%s < %s)\n", call->ToCString(), replacement->ToCString(), @@ -1403,7 +1405,7 @@ void CallSpecializer::ReplaceWithInstanceOf(InstanceCallInstr* call) { StrictCompareInstr* check_cid = new (Z) StrictCompareInstr( call->token_pos(), Token::kEQ_STRICT, new (Z) Value(left_cid), - new (Z) Value(cid), /* number_check = */ false, Thread::kNoDeoptId); + new (Z) Value(cid), /* number_check = */ false, DeoptId::kNone); ReplaceCall(call, check_cid); return; } @@ -1430,7 +1432,7 @@ void CallSpecializer::ReplaceWithInstanceOf(InstanceCallInstr* call) { } TestCidsInstr* test_cids = new (Z) TestCidsInstr( call->token_pos(), Token::kIS, new (Z) Value(left), *results, - can_deopt ? call->deopt_id() : Thread::kNoDeoptId); + can_deopt ? call->deopt_id() : DeoptId::kNone); // Remove type. ReplaceCall(call, test_cids); return; diff --git a/runtime/vm/compiler/cha.h b/runtime/vm/compiler/cha.h index ea49315e0dd..3dce752fb87 100644 --- a/runtime/vm/compiler/cha.h +++ b/runtime/vm/compiler/cha.h @@ -17,20 +17,10 @@ template class ZoneGrowableArray; class String; -class CHA : public StackResource { +class CHA : public ValueObject { public: explicit CHA(Thread* thread) - : StackResource(thread), - thread_(thread), - guarded_classes_(thread->zone(), 1), - previous_(thread->cha()) { - thread->set_cha(this); - } - - ~CHA() { - ASSERT(thread_->cha() == this); - thread_->set_cha(previous_); - } + : thread_(thread), guarded_classes_(thread->zone(), 1) {} // Returns true if the class has subclasses. static bool HasSubclasses(const Class& cls); @@ -39,7 +29,8 @@ class CHA : public StackResource { // Collect the concrete subclasses of 'cls' into 'class_ids'. Return true if // the result is valid (may be invalid because we don't track the subclasses // of classes allocated in the VM isolate or class Object). - bool ConcreteSubclasses(const Class& cls, GrowableArray* class_ids); + static bool ConcreteSubclasses(const Class& cls, + GrowableArray* class_ids); // Return true if the class is implemented by some other class. static bool IsImplemented(const Class& cls); @@ -81,7 +72,6 @@ class CHA : public StackResource { }; GrowableArray guarded_classes_; - CHA* previous_; }; } // namespace dart diff --git a/runtime/vm/compiler/compiler_sources.gni b/runtime/vm/compiler/compiler_sources.gni index 62b132c9d30..a3f399d2fa4 100644 --- a/runtime/vm/compiler/compiler_sources.gni +++ b/runtime/vm/compiler/compiler_sources.gni @@ -75,6 +75,7 @@ compiler_sources = [ "cha.h", "compiler_pass.cc", "compiler_pass.h", + "compiler_state.h", "frontend/base_flow_graph_builder.cc", "frontend/base_flow_graph_builder.h", "frontend/bytecode_reader.cc", diff --git a/runtime/vm/compiler/compiler_state.h b/runtime/vm/compiler/compiler_state.h new file mode 100644 index 00000000000..320a174a34e --- /dev/null +++ b/runtime/vm/compiler/compiler_state.h @@ -0,0 +1,107 @@ +// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +#ifndef RUNTIME_VM_COMPILER_COMPILER_STATE_H_ +#define RUNTIME_VM_COMPILER_COMPILER_STATE_H_ + +#include "vm/compiler/cha.h" +#include "vm/thread.h" + +namespace dart { + +// Deoptimization Id logic. +// +// Deoptimization ids are used to refer to deoptimization points, at which +// control can enter unoptimized code from the optimized version of the code. +// +// Note: any instruction that does a call has two deoptimization points, +// one before the call and one after the call - so that we could deoptimize +// to either before or after the call depending on whether the same call +// already occured in the optimized code (and potentially produced +// observable side-effects) or not. +// +// To simplify implementation we always allocate two deopt ids (one for before +// point and one for the after point). +class DeoptId : public AllStatic { + public: + static constexpr intptr_t kNone = -1; + + static inline intptr_t Next(intptr_t deopt_id) { return deopt_id + kStep; } + + static inline intptr_t ToDeoptAfter(intptr_t deopt_id) { + ASSERT(IsDeoptBefore(deopt_id)); + return deopt_id + kAfterOffset; + } + + static inline bool IsDeoptBefore(intptr_t deopt_id) { + return (deopt_id % kStep) == kBeforeOffset; + } + + static inline bool IsDeoptAfter(intptr_t deopt_id) { + return (deopt_id % kStep) == kAfterOffset; + } + + private: + static constexpr intptr_t kStep = 2; + static constexpr intptr_t kBeforeOffset = 0; + static constexpr intptr_t kAfterOffset = 1; +}; + +// Global compiler state attached to the thread. +class CompilerState : public StackResource { + public: + explicit CompilerState(Thread* thread) : StackResource(thread), cha_(thread) { + previous_ = thread->SetCompilerState(this); + } + + ~CompilerState() { + ASSERT(&thread()->compiler_state() == this); + thread()->SetCompilerState(previous_); + } + + CHA& cha() { return cha_; } + + intptr_t deopt_id() const { return deopt_id_; } + void set_deopt_id(int value) { + ASSERT(value >= 0); + deopt_id_ = value; + } + + intptr_t GetNextDeoptId() { + ASSERT(deopt_id_ != DeoptId::kNone); + const intptr_t id = deopt_id_; + deopt_id_ = DeoptId::Next(deopt_id_); + return id; + } + + static CompilerState& Current() { + return Thread::Current()->compiler_state(); + } + + private: + CHA cha_; + intptr_t deopt_id_ = 0; + + CompilerState* previous_; +}; + +class DeoptIdScope : public StackResource { + public: + DeoptIdScope(Thread* thread, intptr_t deopt_id) + : StackResource(thread), + prev_deopt_id_(thread->compiler_state().deopt_id()) { + thread->compiler_state().set_deopt_id(deopt_id); + } + + ~DeoptIdScope() { thread()->compiler_state().set_deopt_id(prev_deopt_id_); } + + private: + const intptr_t prev_deopt_id_; + + DISALLOW_COPY_AND_ASSIGN(DeoptIdScope); +}; + +} // namespace dart + +#endif // RUNTIME_VM_COMPILER_COMPILER_STATE_H_ diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc index 6b4accb03a3..55e3531f542 100644 --- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc +++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc @@ -315,7 +315,7 @@ Fragment BaseFlowGraphBuilder::LoadIndexed(intptr_t index_scale) { Value* array = Pop(); LoadIndexedInstr* instr = new (Z) LoadIndexedInstr(array, index, index_scale, kArrayCid, kAlignedAccess, - Thread::kNoDeoptId, TokenPosition::kNoSource); + DeoptId::kNone, TokenPosition::kNoSource); Push(instr); return Fragment(instr); } @@ -445,7 +445,7 @@ Fragment BaseFlowGraphBuilder::StoreIndexed(intptr_t class_id) { StoreIndexedInstr* store = new (Z) StoreIndexedInstr( Pop(), // Array. index, value, emit_store_barrier, Instance::ElementSizeFor(class_id), - class_id, kAlignedAccess, Thread::kNoDeoptId, TokenPosition::kNoSource); + class_id, kAlignedAccess, DeoptId::kNone, TokenPosition::kNoSource); Push(store); return Fragment(store); } diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h index c1418a746b4..190635cb88f 100644 --- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h +++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h @@ -220,7 +220,7 @@ class BaseFlowGraphBuilder { Fragment TailCall(const Code& code); intptr_t GetNextDeoptId() { - intptr_t deopt_id = thread_->GetNextDeoptId(); + intptr_t deopt_id = thread_->compiler_state().GetNextDeoptId(); if (context_level_array_ != NULL) { intptr_t level = context_depth_; context_level_array_->Add(deopt_id); diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc index aa739c1549d..3f244f7f4f7 100644 --- a/runtime/vm/compiler/frontend/bytecode_reader.cc +++ b/runtime/vm/compiler/frontend/bytecode_reader.cc @@ -210,7 +210,7 @@ intptr_t BytecodeMetadataHelper::ReadPoolEntries(const Function& function, } obj = ICData::New(function, name, array, // Arguments descriptor. - Thread::kNoDeoptId, checked_argument_count, + DeoptId::kNone, checked_argument_count, ICData::RebindRule::kInstance); #if defined(TAG_IC_DATA) ICData::Cast(obj).set_tag(ICData::Tag::kInstanceCall); @@ -254,7 +254,7 @@ intptr_t BytecodeMetadataHelper::ReadPoolEntries(const Function& function, array ^= pool.ObjectAt(arg_desc_index); obj = ICData::New(function, name, array, // Arguments descriptor. - Thread::kNoDeoptId, num_args_checked, + DeoptId::kNone, num_args_checked, ICData::RebindRule::kStatic); ICData::Cast(obj).AddTarget(Function::Cast(elem)); #if defined(TAG_IC_DATA) @@ -567,10 +567,10 @@ void BytecodeMetadataHelper::ReadExceptionsTable(const Code& bytecode) { handler_types.SetAt(i, handler_type); } pc_descriptors_list->AddDescriptor(RawPcDescriptors::kOther, start_pc, - Thread::kNoDeoptId, + DeoptId::kNone, TokenPosition::kNoSource, try_index); pc_descriptors_list->AddDescriptor(RawPcDescriptors::kOther, end_pc, - Thread::kNoDeoptId, + DeoptId::kNone, TokenPosition::kNoSource, -1); exception_handlers_list->AddHandler( diff --git a/runtime/vm/compiler/frontend/flow_graph_builder.cc b/runtime/vm/compiler/frontend/flow_graph_builder.cc index 4d93fdf2d24..bba0acead1f 100644 --- a/runtime/vm/compiler/frontend/flow_graph_builder.cc +++ b/runtime/vm/compiler/frontend/flow_graph_builder.cc @@ -164,7 +164,7 @@ void NestedStatement::AdjustContextLevel(intptr_t context_level) { } intptr_t FlowGraphBuilder::GetNextDeoptId() const { - intptr_t deopt_id = thread()->GetNextDeoptId(); + intptr_t deopt_id = thread()->compiler_state().GetNextDeoptId(); if (context_level_array_ != NULL) { intptr_t level = context_level(); context_level_array_->Add(deopt_id); @@ -427,8 +427,8 @@ Definition* InlineExitCollector::JoinReturns(BlockEntryInstr** exit_block, // Create a join of the returns. intptr_t join_id = caller_graph_->max_block_id() + 1; caller_graph_->set_max_block_id(join_id); - JoinEntryInstr* join = new (Z) - JoinEntryInstr(join_id, try_index, Thread::Current()->GetNextDeoptId()); + JoinEntryInstr* join = new (Z) JoinEntryInstr( + join_id, try_index, CompilerState::Current().GetNextDeoptId()); // The dominator set of the join is the intersection of the dominator // sets of all the predecessors. If we keep the dominator sets ordered @@ -447,7 +447,7 @@ Definition* InlineExitCollector::JoinReturns(BlockEntryInstr** exit_block, for (intptr_t i = 0; i < num_exits; ++i) { // Add the control-flow edge. GotoInstr* goto_instr = - new (Z) GotoInstr(join, Thread::Current()->GetNextDeoptId()); + new (Z) GotoInstr(join, CompilerState::Current().GetNextDeoptId()); goto_instr->InheritDeoptTarget(zone(), ReturnAt(i)); LastInstructionAt(i)->LinkTo(goto_instr); ExitBlockAt(i)->set_last_instruction(LastInstructionAt(i)->next()); @@ -533,18 +533,18 @@ void InlineExitCollector::ReplaceCall(TargetEntryInstr* callee_entry) { // by the constant propagation. TargetEntryInstr* false_block = new (Z) TargetEntryInstr( caller_graph_->allocate_block_id(), call_block->try_index(), - Thread::Current()->GetNextDeoptId()); + CompilerState::Current().GetNextDeoptId()); false_block->InheritDeoptTargetAfter(caller_graph_, call_, NULL); false_block->LinkTo(call_->next()); call_block->ReplaceAsPredecessorWith(false_block); ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True()); - BranchInstr* branch = new (Z) - BranchInstr(new (Z) StrictCompareInstr( - TokenPosition::kNoSource, Token::kEQ_STRICT, - new (Z) Value(true_const), new (Z) Value(true_const), - false, Thread::Current()->GetNextDeoptId()), - Thread::Current()->GetNextDeoptId()); // No number check. + BranchInstr* branch = new (Z) BranchInstr( + new (Z) StrictCompareInstr(TokenPosition::kNoSource, Token::kEQ_STRICT, + new (Z) Value(true_const), + new (Z) Value(true_const), false, + CompilerState::Current().GetNextDeoptId()), + CompilerState::Current().GetNextDeoptId()); // No number check. branch->InheritDeoptTarget(zone(), call_); *branch->true_successor_address() = callee_entry; *branch->false_successor_address() = false_block; @@ -2192,7 +2192,7 @@ void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { { LocalVariable* tmp_var = EnterTempLocalScope(array_val); const intptr_t class_id = kArrayCid; - const intptr_t deopt_id = Thread::kNoDeoptId; + const intptr_t deopt_id = DeoptId::kNone; for (int i = 0; i < node->length(); ++i) { Value* array = Bind(new (Z) LoadLocalInstr(*tmp_var, node->token_pos())); Value* index = Bind(new (Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(i)), @@ -3490,12 +3490,14 @@ void EffectGraphVisitor::VisitStoreInstanceFieldNode( if (isolate()->use_field_guards()) { store_value = Bind(BuildStoreExprTemp(store_value, token_pos)); - GuardFieldClassInstr* guard_field_class = new (Z) GuardFieldClassInstr( - store_value, node->field(), thread()->GetNextDeoptId()); + GuardFieldClassInstr* guard_field_class = new (Z) + GuardFieldClassInstr(store_value, node->field(), + thread()->compiler_state().GetNextDeoptId()); AddInstruction(guard_field_class); store_value = Bind(BuildLoadExprTemp(token_pos)); - GuardFieldLengthInstr* guard_field_length = new (Z) GuardFieldLengthInstr( - store_value, node->field(), thread()->GetNextDeoptId()); + GuardFieldLengthInstr* guard_field_length = new (Z) + GuardFieldLengthInstr(store_value, node->field(), + thread()->compiler_state().GetNextDeoptId()); AddInstruction(guard_field_length); store_value = Bind(BuildLoadExprTemp(token_pos)); } diff --git a/runtime/vm/compiler/frontend/flow_graph_builder_test.cc b/runtime/vm/compiler/frontend/flow_graph_builder_test.cc index eb8ac056a1f..4b591c959cc 100644 --- a/runtime/vm/compiler/frontend/flow_graph_builder_test.cc +++ b/runtime/vm/compiler/frontend/flow_graph_builder_test.cc @@ -63,6 +63,7 @@ class SourcePositionTest : public ValueObject { new ParsedFunction(thread_, Function::ZoneHandle(function.raw())); Parser::ParseFunction(parsed_function); parsed_function->AllocateVariables(); + CompilerState state(thread_); FlowGraphBuilder builder(*parsed_function, *ic_data_array, /* not building var desc */ NULL, /* not inlining */ NULL, Compiler::kNoOSRDeoptId); diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc index 238760ef6c2..ca6e29d87d9 100644 --- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc +++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc @@ -800,7 +800,7 @@ FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfNoSuchMethodForwarder( loop += condition; Instruction* entry = - new (Z) GotoInstr(join, Thread::Current()->GetNextDeoptId()); + new (Z) GotoInstr(join, CompilerState::Current().GetNextDeoptId()); body += Fragment(entry, loop_exit); } @@ -5041,8 +5041,9 @@ Fragment StreamingFlowGraphBuilder::BuildDoStatement() { condition.IfTrueGoto(flow_graph_builder_, join); loop_depth_dec(); - return Fragment(new (Z) GotoInstr(join, Thread::Current()->GetNextDeoptId()), - condition.CreateFalseSuccessor(flow_graph_builder_)); + return Fragment( + new (Z) GotoInstr(join, CompilerState::Current().GetNextDeoptId()), + condition.CreateFalseSuccessor(flow_graph_builder_)); } Fragment StreamingFlowGraphBuilder::BuildForStatement() { diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h index af23d3ba030..9f6b524fc60 100644 --- a/runtime/vm/compiler/frontend/kernel_to_il.h +++ b/runtime/vm/compiler/frontend/kernel_to_il.h @@ -172,7 +172,7 @@ class FlowGraphBuilder : public BaseFlowGraphBuilder { LocalVariable* LookupVariable(intptr_t kernel_offset); - bool IsCompiledForOsr() { return osr_id_ != Thread::kNoDeoptId; } + bool IsCompiledForOsr() { return osr_id_ != DeoptId::kNone; } TranslationHelper translation_helper_; Thread* thread_; diff --git a/runtime/vm/compiler/intrinsifier.cc b/runtime/vm/compiler/intrinsifier.cc index 9afbe0b49d1..0d8fb526c1e 100644 --- a/runtime/vm/compiler/intrinsifier.cc +++ b/runtime/vm/compiler/intrinsifier.cc @@ -227,7 +227,7 @@ bool Intrinsifier::GraphIntrinsify(const ParsedFunction& parsed_function, intptr_t block_id = builder.AllocateBlockId(); TargetEntryInstr* normal_entry = new TargetEntryInstr(block_id, CatchClauseNode::kInvalidTryIndex, - Thread::Current()->GetNextDeoptId()); + CompilerState::Current().GetNextDeoptId()); GraphEntryInstr* graph_entry = new GraphEntryInstr( parsed_function, normal_entry, Compiler::kNoOSRDeoptId); FlowGraph* graph = @@ -372,7 +372,7 @@ class BlockBuilder : public ValueObject { current_(entry), fall_through_env_(new Environment(0, 0, - Thread::kNoDeoptId, + DeoptId::kNone, flow_graph->parsed_function(), NULL)) {} @@ -400,8 +400,8 @@ class BlockBuilder : public ValueObject { } void AddIntrinsicReturn(Value* value) { - ReturnInstr* instr = - new ReturnInstr(TokenPos(), value, Thread::Current()->GetNextDeoptId()); + ReturnInstr* instr = new ReturnInstr( + TokenPos(), value, CompilerState::Current().GetNextDeoptId()); AddInstruction(instr); entry_->set_last_instruction(instr); } @@ -420,7 +420,7 @@ class BlockBuilder : public ValueObject { Definition* AddUnboxInstr(Representation rep, Value* value, bool is_checked) { Definition* unboxed_value = - AddDefinition(UnboxInstr::Create(rep, value, Thread::kNoDeoptId)); + AddDefinition(UnboxInstr::Create(rep, value, DeoptId::kNone)); if (is_checked) { // The type of |value| has already been checked and it is safe to // adjust reaching type. This is done manually because there is no type @@ -446,7 +446,7 @@ class BlockBuilder : public ValueObject { Definition* InvokeMathCFunctionHelper(MethodRecognizer::Kind recognized_kind, ZoneGrowableArray* args) { InvokeMathCFunctionInstr* invoke_math_c_function = - new InvokeMathCFunctionInstr(args, Thread::kNoDeoptId, recognized_kind, + new InvokeMathCFunctionInstr(args, DeoptId::kNone, recognized_kind, TokenPos()); AddDefinition(invoke_math_c_function); return invoke_math_c_function; @@ -466,7 +466,7 @@ static void PrepareIndexedOp(BlockBuilder* builder, new Value(array), length_offset, Type::ZoneHandle(Type::SmiType()), TokenPosition::kNoSource)); builder->AddInstruction(new CheckArrayBoundInstr( - new Value(length), new Value(index), Thread::kNoDeoptId)); + new Value(length), new Value(index), DeoptId::kNone)); } static bool IntrinsifyArrayGetIndexed(FlowGraph* flow_graph, @@ -495,7 +495,7 @@ static bool IntrinsifyArrayGetIndexed(FlowGraph* flow_graph, Definition* result = builder.AddDefinition(new LoadIndexedInstr( new Value(array), new Value(index), Instance::ElementSizeFor(array_cid), // index scale - array_cid, kAlignedAccess, Thread::kNoDeoptId, builder.TokenPos())); + array_cid, kAlignedAccess, DeoptId::kNone, builder.TokenPos())); // Box and/or convert result if necessary. switch (array_cid) { case kTypedDataInt32ArrayCid: @@ -510,7 +510,7 @@ static bool IntrinsifyArrayGetIndexed(FlowGraph* flow_graph, break; case kTypedDataFloat32ArrayCid: result = builder.AddDefinition( - new FloatToDoubleInstr(new Value(result), Thread::kNoDeoptId)); + new FloatToDoubleInstr(new Value(result), DeoptId::kNone)); // Fall through. case kTypedDataFloat64ArrayCid: result = builder.AddDefinition( @@ -580,8 +580,8 @@ static bool IntrinsifyArraySetIndexed(FlowGraph* flow_graph, case kExternalTypedDataUint8ClampedArrayCid: case kTypedDataInt16ArrayCid: case kTypedDataUint16ArrayCid: - builder.AddInstruction(new CheckSmiInstr( - new Value(value), Thread::kNoDeoptId, builder.TokenPos())); + builder.AddInstruction(new CheckSmiInstr(new Value(value), DeoptId::kNone, + builder.TokenPos())); break; case kTypedDataInt32ArrayCid: case kExternalTypedDataInt32ArrayCid: @@ -625,14 +625,13 @@ static bool IntrinsifyArraySetIndexed(FlowGraph* flow_graph, } Zone* zone = flow_graph->zone(); Cids* value_check = Cids::CreateMonomorphic(zone, value_check_cid); - builder.AddInstruction( - new CheckClassInstr(new Value(value), Thread::kNoDeoptId, - *value_check, builder.TokenPos())); + builder.AddInstruction(new CheckClassInstr( + new Value(value), DeoptId::kNone, *value_check, builder.TokenPos())); value = builder.AddUnboxInstr(rep, new Value(value), /* is_checked = */ true); if (array_cid == kTypedDataFloat32ArrayCid) { value = builder.AddDefinition( - new DoubleToFloatInstr(new Value(value), Thread::kNoDeoptId)); + new DoubleToFloatInstr(new Value(value), DeoptId::kNone)); } break; } @@ -650,7 +649,7 @@ static bool IntrinsifyArraySetIndexed(FlowGraph* flow_graph, builder.AddInstruction(new StoreIndexedInstr( new Value(array), new Value(index), new Value(value), kNoStoreBarrier, Instance::ElementSizeFor(array_cid), // index scale - array_cid, kAlignedAccess, Thread::kNoDeoptId, builder.TokenPos())); + array_cid, kAlignedAccess, DeoptId::kNone, builder.TokenPos())); // Return null. Definition* null_def = builder.AddNullDefinition(); builder.AddIntrinsicReturn(new Value(null_def)); @@ -777,7 +776,7 @@ static bool BuildCodeUnitAt(FlowGraph* flow_graph, intptr_t cid) { Definition* result = builder.AddDefinition(new LoadIndexedInstr( new Value(str), new Value(index), Instance::ElementSizeFor(cid), cid, - kAlignedAccess, Thread::kNoDeoptId, builder.TokenPos())); + kAlignedAccess, DeoptId::kNone, builder.TokenPos())); builder.AddIntrinsicReturn(new Value(result)); return true; } @@ -815,8 +814,8 @@ static bool BuildSimdOp(FlowGraph* flow_graph, intptr_t cid, Token::Kind kind) { Cids* value_check = Cids::CreateMonomorphic(zone, cid); // Check argument. Receiver (left) is known to be a Float32x4. - builder.AddInstruction(new CheckClassInstr( - new Value(right), Thread::kNoDeoptId, *value_check, builder.TokenPos())); + builder.AddInstruction(new CheckClassInstr(new Value(right), DeoptId::kNone, + *value_check, builder.TokenPos())); Definition* left_simd = builder.AddUnboxInstr(rep, new Value(left), /* is_checked = */ true); @@ -825,7 +824,7 @@ static bool BuildSimdOp(FlowGraph* flow_graph, intptr_t cid, Token::Kind kind) { Definition* unboxed_result = builder.AddDefinition(SimdOpInstr::Create( SimdOpInstr::KindForOperator(cid, kind), new Value(left_simd), - new Value(right_simd), Thread::kNoDeoptId)); + new Value(right_simd), DeoptId::kNone)); Definition* result = builder.AddDefinition(BoxInstr::Create(rep, new Value(unboxed_result))); builder.AddIntrinsicReturn(new Value(result)); @@ -860,8 +859,8 @@ static bool BuildFloat32x4Shuffle(FlowGraph* flow_graph, builder.AddUnboxInstr(kUnboxedFloat32x4, new Value(receiver), /* is_checked = */ true); - Definition* unboxed_result = builder.AddDefinition(SimdOpInstr::Create( - kind, new Value(unboxed_receiver), Thread::kNoDeoptId)); + Definition* unboxed_result = builder.AddDefinition( + SimdOpInstr::Create(kind, new Value(unboxed_receiver), DeoptId::kNone)); Definition* result = builder.AddDefinition( BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result))); @@ -956,7 +955,7 @@ bool Intrinsifier::Build_GrowableArrayGetIndexed(FlowGraph* flow_graph) { Definition* result = builder.AddDefinition(new LoadIndexedInstr( new Value(backing_store), new Value(index), Instance::ElementSizeFor(kArrayCid), // index scale - kArrayCid, kAlignedAccess, Thread::kNoDeoptId, builder.TokenPos())); + kArrayCid, kAlignedAccess, DeoptId::kNone, builder.TokenPos())); builder.AddIntrinsicReturn(new Value(result)); return true; } @@ -998,7 +997,7 @@ bool Intrinsifier::Build_GrowableArraySetIndexedUnchecked( new Value(backing_store), new Value(index), new Value(value), kEmitStoreBarrier, Instance::ElementSizeFor(kArrayCid), // index scale - kArrayCid, kAlignedAccess, Thread::kNoDeoptId, builder.TokenPos())); + kArrayCid, kAlignedAccess, DeoptId::kNone, builder.TokenPos())); // Return null. Definition* null_def = builder.AddNullDefinition(); builder.AddIntrinsicReturn(new Value(null_def)); @@ -1015,8 +1014,8 @@ bool Intrinsifier::Build_GrowableArraySetData(FlowGraph* flow_graph) { Zone* zone = flow_graph->zone(); Cids* value_check = Cids::CreateMonomorphic(zone, kArrayCid); - builder.AddInstruction(new CheckClassInstr( - new Value(data), Thread::kNoDeoptId, *value_check, builder.TokenPos())); + builder.AddInstruction(new CheckClassInstr(new Value(data), DeoptId::kNone, + *value_check, builder.TokenPos())); builder.AddInstruction(new StoreInstanceFieldInstr( GrowableObjectArray::data_offset(), new Value(growable_array), @@ -1035,8 +1034,8 @@ bool Intrinsifier::Build_GrowableArraySetLength(FlowGraph* flow_graph) { Definition* length = builder.AddParameter(1); Definition* growable_array = builder.AddParameter(2); - builder.AddInstruction(new CheckSmiInstr( - new Value(length), Thread::kNoDeoptId, builder.TokenPos())); + builder.AddInstruction( + new CheckSmiInstr(new Value(length), DeoptId::kNone, builder.TokenPos())); builder.AddInstruction(new StoreInstanceFieldInstr( GrowableObjectArray::length_offset(), new Value(growable_array), new Value(length), kNoStoreBarrier, builder.TokenPos())); @@ -1058,7 +1057,7 @@ bool Intrinsifier::Build_DoubleFlipSignBit(FlowGraph* flow_graph) { builder.AddUnboxInstr(kUnboxedDouble, new Value(receiver), /* is_checked = */ true); Definition* unboxed_result = builder.AddDefinition(new UnaryDoubleOpInstr( - Token::kNEGATE, new Value(unboxed_value), Thread::kNoDeoptId)); + Token::kNEGATE, new Value(unboxed_value), DeoptId::kNone)); Definition* result = builder.AddDefinition( BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result))); builder.AddIntrinsicReturn(new Value(result)); diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc index 5d499c5927d..6e1959191b4 100644 --- a/runtime/vm/compiler/jit/compiler.cc +++ b/runtime/vm/compiler/jit/compiler.cc @@ -23,6 +23,7 @@ #include "vm/compiler/backend/type_propagator.h" #include "vm/compiler/cha.h" #include "vm/compiler/compiler_pass.h" +#include "vm/compiler/compiler_state.h" #include "vm/compiler/frontend/flow_graph_builder.h" #include "vm/compiler/frontend/kernel_to_il.h" #include "vm/compiler/jit/jit_call_specializer.h" @@ -676,7 +677,10 @@ RawCode* CompileParsedFunctionHelper::FinalizeCompilation( THR_Print("--> FAIL: Loading invalidation."); } } - if (!thread()->cha()->IsConsistentWithCurrentHierarchy()) { + if (!thread() + ->compiler_state() + .cha() + .IsConsistentWithCurrentHierarchy()) { code_is_valid = false; if (trace_compiler) { THR_Print("--> FAIL: Class hierarchy has new subclasses."); @@ -706,7 +710,7 @@ RawCode* CompileParsedFunctionHelper::FinalizeCompilation( // The generated code was compiled under certain assumptions about // class hierarchy and field types. Register these dependencies // to ensure that the code will be deoptimized if they are violated. - thread()->cha()->RegisterDependencies(code); + thread()->compiler_state().cha().RegisterDependencies(code); const ZoneGrowableArray& guarded_fields = *flow_graph->parsed_function().guarded_fields(); @@ -741,7 +745,7 @@ void CompileParsedFunctionHelper::CheckIfBackgroundCompilerIsBeingStopped() { if (!isolate()->background_compiler()->is_running()) { // The background compiler is being stopped. Compiler::AbortBackgroundCompilation( - Thread::kNoDeoptId, "Background compilation is being stopped"); + DeoptId::kNone, "Background compilation is being stopped"); } } @@ -776,15 +780,12 @@ RawCode* CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) { Code* volatile result = &Code::ZoneHandle(zone); while (!done) { *result = Code::null(); - DeoptIdScope deopt_id_scope(thread(), 0); LongJumpScope jump; if (setjmp(*jump.Set()) == 0) { FlowGraph* flow_graph = nullptr; ZoneGrowableArray* ic_data_array = nullptr; - // Class hierarchy analysis is registered with the thread in the - // constructor and unregisters itself upon destruction. - CHA cha(thread()); + CompilerState compiler_state(thread()); // TimerScope needs an isolate to be properly terminated in case of a // LongJump. @@ -812,7 +813,7 @@ RawCode* CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) { if (Compiler::IsBackgroundCompilation() && (function.ic_data_array() == Array::null())) { Compiler::AbortBackgroundCompilation( - Thread::kNoDeoptId, "RestoreICDataMap: ICData array cleared."); + DeoptId::kNone, "RestoreICDataMap: ICData array cleared."); } } @@ -1014,7 +1015,7 @@ static RawObject* CompileFunctionHelper(CompilationPipeline* pipeline, // Loading occured while parsing. We need to abort here because state // changed while compiling. Compiler::AbortBackgroundCompilation( - Thread::kNoDeoptId, + DeoptId::kNone, "Invalidated state during parsing because of script loading"); } } @@ -1351,7 +1352,7 @@ void Compiler::ComputeLocalVarDescriptors(const Code& code) { ASSERT(!function.IsIrregexpFunction()); // In background compilation, parser can produce 'errors": bailouts // if state changed while compiling in background. - DeoptIdScope deopt_id_scope(Thread::Current(), 0); + CompilerState state(Thread::Current()); LongJumpScope jump; if (setjmp(*jump.Set()) == 0) { ZoneGrowableArray* ic_data_array = diff --git a/runtime/vm/compiler/jit/compiler.h b/runtime/vm/compiler/jit/compiler.h index 38946f130b9..68ef8d1015a 100644 --- a/runtime/vm/compiler/jit/compiler.h +++ b/runtime/vm/compiler/jit/compiler.h @@ -6,6 +6,7 @@ #define RUNTIME_VM_COMPILER_JIT_COMPILER_H_ #include "vm/allocation.h" +#include "vm/compiler/compiler_state.h" #include "vm/growable_array.h" #include "vm/runtime_entry.h" #include "vm/thread_pool.h" @@ -79,7 +80,7 @@ class IrregexpCompilationPipeline : public CompilationPipeline { class Compiler : public AllStatic { public: - static const intptr_t kNoOSRDeoptId = Thread::kNoDeoptId; + static const intptr_t kNoOSRDeoptId = DeoptId::kNone; static bool IsBackgroundCompilation(); // The result for a function may change if debugging gets turned on/off. diff --git a/runtime/vm/compiler/jit/jit_call_specializer.cc b/runtime/vm/compiler/jit/jit_call_specializer.cc index f6def2370c3..aa95f7c8cfd 100644 --- a/runtime/vm/compiler/jit/jit_call_specializer.cc +++ b/runtime/vm/compiler/jit/jit_call_specializer.cc @@ -211,7 +211,7 @@ void JitCallSpecializer::VisitStoreInstanceField( if (Compiler::IsBackgroundCompilation()) { isolate()->AddDeoptimizingBoxedField(field); Compiler::AbortBackgroundCompilation( - Thread::kNoDeoptId, "Unboxing instance field while compiling"); + DeoptId::kNone, "Unboxing instance field while compiling"); UNREACHABLE(); } if (FLAG_trace_optimization || FLAG_trace_field_guards) { diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc index f1cdf0946b7..306cf6faf23 100644 --- a/runtime/vm/debugger.cc +++ b/runtime/vm/debugger.cc @@ -250,7 +250,7 @@ ActivationFrame::ActivationFrame(uword pc, token_pos_initialized_(false), token_pos_(TokenPosition::kNoSource), try_index_(-1), - deopt_id_(Thread::kNoDeoptId), + deopt_id_(DeoptId::kNone), line_number_(-1), column_number_(-1), context_level_(-1), @@ -700,7 +700,7 @@ intptr_t ActivationFrame::ContextLevel() { GetVarDescriptors(); intptr_t deopt_id = DeoptId(); - if (deopt_id == Thread::kNoDeoptId) { + if (deopt_id == DeoptId::kNone) { PrintDescriptorsError("Missing deopt id"); } intptr_t var_desc_len = var_descriptors_.Length(); diff --git a/runtime/vm/deferred_objects.cc b/runtime/vm/deferred_objects.cc index 153f2aebf7b..952956980cc 100644 --- a/runtime/vm/deferred_objects.cc +++ b/runtime/vm/deferred_objects.cc @@ -108,7 +108,7 @@ void DeferredRetAddr::Materialize(DeoptContext* deopt_context) { // Check that deopt_id exists. // TODO(vegorov): verify after deoptimization targets as well. #ifdef DEBUG - ASSERT(Thread::IsDeoptAfter(deopt_id_) || + ASSERT(DeoptId::IsDeoptAfter(deopt_id_) || (code.GetPcForDeoptId(deopt_id_, RawPcDescriptors::kDeopt) != 0)); #endif diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc index 06641ab4084..ec6fa743e84 100644 --- a/runtime/vm/deopt_instructions.cc +++ b/runtime/vm/deopt_instructions.cc @@ -862,7 +862,7 @@ uword DeoptInstr::GetRetAddress(DeoptInstr* instr, static_cast(instr); // The following assert may trigger when displaying a backtrace // from the simulator. - ASSERT(Thread::IsDeoptAfter(ret_address_instr->deopt_id())); + ASSERT(DeoptId::IsDeoptAfter(ret_address_instr->deopt_id())); ASSERT(!object_table.IsNull()); Thread* thread = Thread::Current(); Zone* zone = thread->zone(); diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index 082462e9426..af5795792f0 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -3613,7 +3613,7 @@ RawError* Class::EnsureIsFinalized(Thread* thread) const { return Error::null(); } if (Compiler::IsBackgroundCompilation()) { - Compiler::AbortBackgroundCompilation(Thread::kNoDeoptId, + Compiler::AbortBackgroundCompilation(DeoptId::kNone, "Class finalization while compiling"); } ASSERT(thread->IsMutatorThread()); @@ -13735,7 +13735,7 @@ void PcDescriptors::Verify(const Function& function) const { Iterator iter(*this, RawPcDescriptors::kDeopt | RawPcDescriptors::kIcCall); while (iter.MoveNext()) { // 'deopt_id' is set for kDeopt and kIcCall and must be unique for one kind. - if (Thread::IsDeoptAfter(iter.DeoptId())) { + if (DeoptId::IsDeoptAfter(iter.DeoptId())) { // TODO(vegorov): some instructions contain multiple calls and have // multiple "after" targets recorded. Right now it is benign but might // lead to issues in the future. Fix that and enable verification. @@ -15274,7 +15274,7 @@ RawICData* ICData::New() { NoSafepointScope no_safepoint; result ^= raw; } - result.set_deopt_id(Thread::kNoDeoptId); + result.set_deopt_id(DeoptId::kNone); result.set_state_bits(0); #if defined(TAG_IC_DATA) result.set_tag(ICData::Tag::kUnknown); @@ -15954,7 +15954,7 @@ intptr_t Code::GetDeoptIdForOsr(uword pc) const { return iter.DeoptId(); } } - return Thread::kNoDeoptId; + return DeoptId::kNone; } const char* Code::ToCString() const { diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc index 5cfa65a3122..d55273e1bfb 100644 --- a/runtime/vm/parser.cc +++ b/runtime/vm/parser.cc @@ -228,7 +228,7 @@ void ParsedFunction::AddToGuardedFields(const Field* field) const { if (Compiler::IsBackgroundCompilation()) { if (!other->IsConsistentWith(*field)) { Compiler::AbortBackgroundCompilation( - Thread::kNoDeoptId, + DeoptId::kNone, "Field's guarded state changed during compilation"); } } diff --git a/runtime/vm/regexp_assembler.cc b/runtime/vm/regexp_assembler.cc index ecd191409d0..fb7dc746fc8 100644 --- a/runtime/vm/regexp_assembler.cc +++ b/runtime/vm/regexp_assembler.cc @@ -61,7 +61,8 @@ BlockLabel::BlockLabel() #if !defined(DART_PRECOMPILED_RUNTIME) if (!FLAG_interpret_irregexp) { // Only needed by the compiled IR backend. - block_ = new JoinEntryInstr(-1, -1, Thread::Current()->GetNextDeoptId()); + block_ = + new JoinEntryInstr(-1, -1, CompilerState::Current().GetNextDeoptId()); } #endif } diff --git a/runtime/vm/regexp_assembler_ir.h b/runtime/vm/regexp_assembler_ir.h index 0b0dcca7e62..3652b72fc02 100644 --- a/runtime/vm/regexp_assembler_ir.h +++ b/runtime/vm/regexp_assembler_ir.h @@ -133,7 +133,9 @@ class IRRegExpMacroAssembler : public RegExpMacroAssembler { void FinalizeRegistersArray(); private: - intptr_t GetNextDeoptId() const { return thread_->GetNextDeoptId(); } + intptr_t GetNextDeoptId() const { + return thread_->compiler_state().GetNextDeoptId(); + } // Generate the contents of preset blocks. The entry block is the entry point // of the generated code. diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc index 0d809cf52a0..c5b9eba6155 100644 --- a/runtime/vm/runtime_entry.cc +++ b/runtime/vm/runtime_entry.cc @@ -1428,7 +1428,7 @@ DEFINE_RUNTIME_ENTRY(SingleTargetMiss, 1) { kTypeArgsLen, old_target.num_fixed_parameters())); const ICData& ic_data = ICData::Handle(zone, ICData::New(caller_function, name, descriptor, - Thread::kNoDeoptId, 1, /* args_tested */ + DeoptId::kNone, 1, /* args_tested */ ICData::kInstance)); // Maybe add the new target. @@ -1504,7 +1504,7 @@ DEFINE_RUNTIME_ENTRY(UnlinkedCall, 2) { const Array& descriptor = Array::Handle(zone, unlinked.args_descriptor()); const ICData& ic_data = ICData::Handle(zone, ICData::New(caller_function, name, descriptor, - Thread::kNoDeoptId, 1, /* args_tested */ + DeoptId::kNone, 1, /* args_tested */ ICData::kInstance)); Class& cls = Class::Handle(zone, receiver.clazz()); @@ -1584,7 +1584,7 @@ DEFINE_RUNTIME_ENTRY(MonomorphicMiss, 1) { kTypeArgsLen, old_target.num_fixed_parameters())); const ICData& ic_data = ICData::Handle(zone, ICData::New(caller_function, name, descriptor, - Thread::kNoDeoptId, 1, /* args_tested */ + DeoptId::kNone, 1, /* args_tested */ ICData::kInstance)); // Add the first target. diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc index 8e3761f97c6..a188d2b1c8e 100644 --- a/runtime/vm/thread.cc +++ b/runtime/vm/thread.cc @@ -92,10 +92,8 @@ Thread::Thread(Isolate* isolate) deferred_interrupts_mask_(0), deferred_interrupts_(0), stack_overflow_count_(0), - cha_(NULL), hierarchy_info_(NULL), type_usage_info_(NULL), - deopt_id_(0), pending_functions_(GrowableObjectArray::null()), active_exception_(Object::null()), active_stacktrace_(Object::null()), diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h index 608c165e0a3..65402deb06c 100644 --- a/runtime/vm/thread.h +++ b/runtime/vm/thread.h @@ -22,7 +22,7 @@ namespace dart { class AbstractType; class ApiLocalScope; class Array; -class CHA; +class CompilerState; class Class; class Code; class CompilerStats; @@ -369,15 +369,9 @@ class Thread : public BaseThread { // Has |this| exited Dart code? bool HasExitedDartCode() const; - // The (topmost) CHA for the compilation in this thread. - CHA* cha() const { - ASSERT(isolate_ != NULL); - return cha_; - } - - void set_cha(CHA* value) { - ASSERT(isolate_ != NULL); - cha_ = value; + CompilerState& compiler_state() { + ASSERT(compiler_state_ != nullptr); + return *compiler_state_; } HierarchyInfo* hierarchy_info() const { @@ -560,35 +554,6 @@ class Thread : public BaseThread { static bool ObjectAtOffset(intptr_t offset, Object* object); static intptr_t OffsetFromThread(const RuntimeEntry* runtime_entry); - static const intptr_t kNoDeoptId = -1; - static const intptr_t kDeoptIdStep = 2; - static const intptr_t kDeoptIdBeforeOffset = 0; - static const intptr_t kDeoptIdAfterOffset = 1; - intptr_t deopt_id() const { return deopt_id_; } - void set_deopt_id(int value) { - ASSERT(value >= 0); - deopt_id_ = value; - } - intptr_t GetNextDeoptId() { - ASSERT(deopt_id_ != kNoDeoptId); - const intptr_t id = deopt_id_; - deopt_id_ += kDeoptIdStep; - return id; - } - - static intptr_t ToDeoptAfter(intptr_t deopt_id) { - ASSERT(IsDeoptBefore(deopt_id)); - return deopt_id + kDeoptIdAfterOffset; - } - - static bool IsDeoptBefore(intptr_t deopt_id) { - return (deopt_id % kDeoptIdStep) == kDeoptIdBeforeOffset; - } - - static bool IsDeoptAfter(intptr_t deopt_id) { - return (deopt_id % kDeoptIdStep) == kDeoptIdAfterOffset; - } - LongJumpScope* long_jump_base() const { return long_jump_base_; } void set_long_jump_base(LongJumpScope* value) { long_jump_base_ = value; } @@ -819,6 +784,13 @@ class Thread : public BaseThread { template T* AllocateReusableHandle(); + // Set the current compiler state and return the previous compiler state. + CompilerState* SetCompilerState(CompilerState* state) { + CompilerState* previous = compiler_state_; + compiler_state_ = state; + return previous; + } + // Accessed from generated code. // ** This block of fields must come first! ** // For AOT cross-compilation, we rely on these members having the same offsets @@ -886,10 +858,9 @@ class Thread : public BaseThread { int32_t stack_overflow_count_; // Compiler state: - CHA* cha_; + CompilerState* compiler_state_ = nullptr; HierarchyInfo* hierarchy_info_; TypeUsageInfo* type_usage_info_; - intptr_t deopt_id_; // Compilation specific counter. RawGrowableObjectArray* pending_functions_; // JumpToExceptionHandler state: @@ -958,6 +929,7 @@ class Thread : public BaseThread { friend class Simulator; friend class StackZone; friend class ThreadRegistry; + friend class CompilerState; DISALLOW_COPY_AND_ASSIGN(Thread); };