Reapply "Shuffle around deopt id allocation to give the flow graph builder a chance to record other data as they are allocated".

- Fix inlining of new List(n) to propogate deopt id.
 - Fix CreateArrayOpt to check for a Smi length.

R=vegorov@google.com

Review-Url: https://codereview.chromium.org/2900963008 .
This commit is contained in:
Ryan Macnak
2017-05-25 10:12:19 -07:00
parent 2248502611
commit bcf2900a26
21 changed files with 582 additions and 414 deletions
+4 -5
View File
@@ -710,7 +710,7 @@ bool AotOptimizer::TryReplaceWithEqualityOp(InstanceCallInstr* call,
StrictCompareInstr* comp = new (Z)
StrictCompareInstr(call->token_pos(), Token::kEQ_STRICT,
new (Z) Value(left), new (Z) Value(right),
false); // No number check.
/* number_check = */ false, Thread::kNoDeoptId);
ReplaceCall(call, comp);
return true;
}
@@ -1441,10 +1441,9 @@ void AotOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) {
ConstantInstr* cid =
flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(type_cid)));
StrictCompareInstr* check_cid =
new (Z) StrictCompareInstr(call->token_pos(), Token::kEQ_STRICT,
new (Z) Value(left_cid), new (Z) Value(cid),
false); // No number check.
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);
ReplaceCall(call, check_cid);
return;
}
+17 -11
View File
@@ -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());
JoinEntryInstr* join = new (zone) JoinEntryInstr(
target->block_id(), target->try_index(), Thread::kNoDeoptId);
join->InheritDeoptTarget(zone, target);
join->LinkTo(target->next());
join->set_last_instruction(target->last_instruction());
@@ -82,7 +82,8 @@ BranchInstr* BranchSimplifier::CloneBranch(Zone* zone,
ComparisonInstr* comparison = branch->comparison();
ComparisonInstr* new_comparison =
comparison->CopyWithNewOperands(new_left, new_right);
BranchInstr* new_branch = new (zone) BranchInstr(new_comparison);
BranchInstr* new_branch =
new (zone) BranchInstr(new_comparison, Thread::kNoDeoptId);
return new_branch;
}
@@ -183,20 +184,24 @@ 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());
TargetEntryInstr* true_target =
new (zone) TargetEntryInstr(flow_graph->max_block_id() + 1,
block->try_index(), Thread::kNoDeoptId);
true_target->InheritDeoptTarget(zone, join_true);
TargetEntryInstr* false_target = new (zone) TargetEntryInstr(
flow_graph->max_block_id() + 2, block->try_index());
TargetEntryInstr* false_target =
new (zone) TargetEntryInstr(flow_graph->max_block_id() + 2,
block->try_index(), Thread::kNoDeoptId);
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);
GotoInstr* goto_true =
new (zone) GotoInstr(join_true, Thread::kNoDeoptId);
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);
GotoInstr* goto_false =
new (zone) GotoInstr(join_false, Thread::kNoDeoptId);
goto_false->InheritDeoptTarget(zone, join_false);
false_target->LinkTo(goto_false);
false_target->set_last_instruction(goto_false);
@@ -295,8 +300,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));
IfThenElseInstr* if_then_else = new (zone)
IfThenElseInstr(new_comparison, if_true->Copy(zone),
if_false->Copy(zone), Thread::kNoDeoptId);
flow_graph->InsertBefore(branch, if_then_else, NULL,
FlowGraph::kValue);
+7 -6
View File
@@ -1551,7 +1551,8 @@ void ConstantPropagator::EliminateRedundantBranches() {
// Drop the comparison, which does not have side effects
JoinEntryInstr* join = if_true->AsJoinEntry();
if (join->phis() == NULL) {
GotoInstr* jump = new (Z) GotoInstr(if_true->AsJoinEntry());
GotoInstr* jump =
new (Z) GotoInstr(if_true->AsJoinEntry(), Thread::kNoDeoptId);
jump->InheritDeoptTarget(Z, branch);
Instruction* previous = branch->previous();
@@ -1694,16 +1695,16 @@ 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());
join = new (Z) JoinEntryInstr(
if_false->block_id(), if_false->try_index(), Thread::kNoDeoptId);
join->InheritDeoptTarget(Z, if_false);
if_false->UnuseAllInputs();
next = if_false->next();
} else if (!reachable_->Contains(if_false->preorder_number())) {
ASSERT(if_true->parallel_move() == NULL);
ASSERT(if_true->loop_info() == NULL);
join =
new (Z) JoinEntryInstr(if_true->block_id(), if_true->try_index());
join = new (Z) JoinEntryInstr(if_true->block_id(), if_true->try_index(),
Thread::kNoDeoptId);
join->InheritDeoptTarget(Z, if_true);
if_true->UnuseAllInputs();
next = if_true->next();
@@ -1714,7 +1715,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);
GotoInstr* jump = new (Z) GotoInstr(join, Thread::kNoDeoptId);
jump->InheritDeoptTarget(Z, branch);
Instruction* previous = branch->previous();
+2 -1
View File
@@ -1018,7 +1018,8 @@ void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis,
for (intptr_t i = parameter_count(); i < variable_count(); ++i) {
if (i == CurrentContextEnvIndex()) {
if (function().IsClosureFunction()) {
CurrentContextInstr* context = new CurrentContextInstr();
CurrentContextInstr* context =
new CurrentContextInstr(Thread::kNoDeoptId);
context->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp.
AddToInitialDefinitions(context);
env.Add(context);
+185 -142
View File
@@ -173,8 +173,8 @@ intptr_t FlowGraphBuilder::context_level() const {
JoinEntryInstr* NestedStatement::BreakTargetFor(SourceLabel* label) {
if (label != label_) return NULL;
if (break_target_ == NULL) {
break_target_ = new (owner()->zone())
JoinEntryInstr(owner()->AllocateBlockId(), try_index());
break_target_ = new (owner()->zone()) JoinEntryInstr(
owner()->AllocateBlockId(), try_index(), owner()->GetNextDeoptId());
}
return break_target_;
}
@@ -246,8 +246,8 @@ class NestedLoop : public NestedStatement {
JoinEntryInstr* NestedLoop::ContinueTargetFor(SourceLabel* label) {
if (label != this->label()) return NULL;
if (continue_target_ == NULL) {
continue_target_ = new (owner()->zone())
JoinEntryInstr(owner()->AllocateBlockId(), try_index());
continue_target_ = new (owner()->zone()) JoinEntryInstr(
owner()->AllocateBlockId(), try_index(), owner()->GetNextDeoptId());
}
return continue_target_;
}
@@ -289,8 +289,8 @@ JoinEntryInstr* NestedSwitch::ContinueTargetFor(SourceLabel* label) {
for (intptr_t i = 0; i < case_labels_.length(); ++i) {
if (label != case_labels_[i]) continue;
if (case_targets_[i] == NULL) {
case_targets_[i] = new (owner()->zone())
JoinEntryInstr(owner()->AllocateBlockId(), try_index());
case_targets_[i] = new (owner()->zone()) JoinEntryInstr(
owner()->AllocateBlockId(), try_index(), owner()->GetNextDeoptId());
}
return case_targets_[i];
}
@@ -442,7 +442,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);
JoinEntryInstr* join = new (Z)
JoinEntryInstr(join_id, try_index, Thread::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
@@ -460,7 +461,8 @@ Definition* InlineExitCollector::JoinReturns(BlockEntryInstr** exit_block,
GrowableArray<BlockEntryInstr*> join_dominators;
for (intptr_t i = 0; i < num_exits; ++i) {
// Add the control-flow edge.
GotoInstr* goto_instr = new (Z) GotoInstr(join);
GotoInstr* goto_instr =
new (Z) GotoInstr(join, Thread::Current()->GetNextDeoptId());
goto_instr->InheritDeoptTarget(zone(), ReturnAt(i));
LastInstructionAt(i)->LinkTo(goto_instr);
ExitBlockAt(i)->set_last_instruction(LastInstructionAt(i)->next());
@@ -546,16 +548,19 @@ void InlineExitCollector::ReplaceCall(TargetEntryInstr* callee_entry) {
// goes to the rest of the caller graph. It is removed as unreachable code
// by the constant propagation.
TargetEntryInstr* false_block = new (Z) TargetEntryInstr(
caller_graph_->allocate_block_id(), call_block->try_index());
caller_graph_->allocate_block_id(), call_block->try_index(),
Thread::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)); // 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, Thread::Current()->GetNextDeoptId()),
Thread::Current()->GetNextDeoptId()); // No number check.
branch->InheritDeoptTarget(zone(), call_);
*branch->true_successor_address() = callee_entry;
*branch->false_successor_address() = false_block;
@@ -699,7 +704,8 @@ void EffectGraphVisitor::AddInstruction(Instruction* instruction) {
void EffectGraphVisitor::AddReturnExit(TokenPosition token_pos, Value* value) {
ASSERT(is_open());
ReturnInstr* return_instr = new (Z) ReturnInstr(token_pos, value);
ReturnInstr* return_instr =
new (Z) ReturnInstr(token_pos, value, owner()->GetNextDeoptId());
AddInstruction(return_instr);
InlineExitCollector* exit_collector = owner()->exit_collector();
if (exit_collector != NULL) {
@@ -712,7 +718,7 @@ void EffectGraphVisitor::AddReturnExit(TokenPosition token_pos, Value* value) {
void EffectGraphVisitor::Goto(JoinEntryInstr* join) {
ASSERT(is_open());
if (is_empty()) {
entry_ = new (Z) GotoInstr(join);
entry_ = new (Z) GotoInstr(join, owner()->GetNextDeoptId());
} else {
exit()->Goto(join);
}
@@ -761,8 +767,9 @@ void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment,
} else if (false_exit == NULL) {
exit_ = true_exit;
} else {
JoinEntryInstr* join = new (Z)
JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
JoinEntryInstr* join =
new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
owner()->GetNextDeoptId());
true_exit->Goto(join);
false_exit->Goto(join);
exit_ = join;
@@ -792,10 +799,11 @@ void EffectGraphVisitor::TieLoop(
Append(test_preamble_fragment);
Append(test_fragment);
} else {
JoinEntryInstr* join = new (Z)
JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
CheckStackOverflowInstr* check =
new (Z) CheckStackOverflowInstr(token_pos, owner()->loop_depth());
JoinEntryInstr* join =
new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
owner()->GetNextDeoptId());
CheckStackOverflowInstr* check = new (Z) CheckStackOverflowInstr(
token_pos, owner()->loop_depth(), owner()->GetNextDeoptId());
join->LinkTo(check);
if (!test_preamble_fragment.is_empty()) {
check->LinkTo(test_preamble_fragment.entry());
@@ -929,7 +937,8 @@ void TestGraphVisitor::ConnectBranchesTo(
ASSERT(!branches.is_empty());
for (intptr_t i = 0; i < branches.length(); i++) {
TargetEntryInstr* target = new (Z)
TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
owner()->GetNextDeoptId());
*(branches[i]) = target;
target->Goto(join);
}
@@ -952,13 +961,15 @@ BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor(
if (branches.length() == 1) {
TargetEntryInstr* target = new (Z)
TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
owner()->GetNextDeoptId());
*(branches[0]) = target;
return target;
}
JoinEntryInstr* join =
new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
owner()->GetNextDeoptId());
ConnectBranchesTo(branches, join);
return join;
}
@@ -977,13 +988,14 @@ BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const {
void TestGraphVisitor::ReturnValue(Value* value) {
Isolate* isolate = Isolate::Current();
if (isolate->type_checks() || isolate->asserts()) {
value = Bind(new (Z) AssertBooleanInstr(condition_token_pos(), value));
value = Bind(new (Z) AssertBooleanInstr(condition_token_pos(), value,
owner()->GetNextDeoptId()));
}
Value* constant_true = Bind(new (Z) ConstantInstr(Bool::True()));
StrictCompareInstr* comp = new (Z) StrictCompareInstr(
condition_token_pos(), Token::kEQ_STRICT, value, constant_true,
false); // No number check.
BranchInstr* branch = new (Z) BranchInstr(comp);
condition_token_pos(), Token::kEQ_STRICT, value, constant_true, false,
owner()->GetNextDeoptId()); // No number check.
BranchInstr* branch = new (Z) BranchInstr(comp, owner()->GetNextDeoptId());
AddInstruction(branch);
CloseFragment();
@@ -993,7 +1005,7 @@ void TestGraphVisitor::ReturnValue(Value* value) {
void TestGraphVisitor::MergeBranchWithStrictCompare(StrictCompareInstr* comp) {
BranchInstr* branch = new (Z) BranchInstr(comp);
BranchInstr* branch = new (Z) BranchInstr(comp, owner()->GetNextDeoptId());
AddInstruction(branch);
CloseFragment();
true_successor_addresses_.Add(branch->true_successor_address());
@@ -1006,8 +1018,8 @@ void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) {
Value* constant_true = Bind(new (Z) ConstantInstr(Bool::True()));
StrictCompareInstr* comp = new (Z) StrictCompareInstr(
condition_token_pos(), Token::kNE_STRICT, neg->value(), constant_true,
false); // No number check.
BranchInstr* branch = new (Z) BranchInstr(comp);
false, owner()->GetNextDeoptId()); // No number check.
BranchInstr* branch = new (Z) BranchInstr(comp, owner()->GetNextDeoptId());
AddInstruction(branch);
CloseFragment();
true_successor_addresses_.Add(branch->true_successor_address());
@@ -1141,11 +1153,11 @@ void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) {
ZoneGrowableArray<PushArgumentInstr*>* no_arguments =
new (Z) ZoneGrowableArray<PushArgumentInstr*>(0);
const int kTypeArgsLen = 0;
StaticCallInstr* call_async_clear_thread_stack_trace =
new (Z) StaticCallInstr(node->token_pos().ToSynthetic(),
async_clear_thread_stack_trace, kTypeArgsLen,
Object::null_array(), no_arguments,
owner()->ic_data_array());
StaticCallInstr* call_async_clear_thread_stack_trace = new (Z)
StaticCallInstr(node->token_pos().ToSynthetic(),
async_clear_thread_stack_trace, kTypeArgsLen,
Object::null_array(), no_arguments,
owner()->ic_data_array(), owner()->GetNextDeoptId());
Do(call_async_clear_thread_stack_trace);
}
@@ -1180,7 +1192,8 @@ void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) {
const int kTypeArgsLen = 0;
StaticCallInstr* call = new (Z) StaticCallInstr(
node->token_pos().ToSynthetic(), complete_on_async_return, kTypeArgsLen,
Object::null_array(), arguments, owner()->ic_data_array());
Object::null_array(), arguments, owner()->ic_data_array(),
owner()->GetNextDeoptId());
Do(call);
// Rebind the return value for the actual return call to be null.
@@ -1198,8 +1211,9 @@ void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) {
if ((function.IsAsyncClosure() || function.IsSyncGenClosure() ||
function.IsAsyncGenClosure()) &&
(node->return_type() == ReturnNode::kContinuationTarget)) {
JoinEntryInstr* const join = new (Z)
JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
JoinEntryInstr* const join =
new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
owner()->GetNextDeoptId());
owner()->await_joins()->Add(join);
exit_ = join;
}
@@ -1242,7 +1256,8 @@ void ValueGraphVisitor::VisitTypeNode(TypeNode* node) {
function_type_arguments = BuildFunctionTypeArguments(token_pos);
}
ReturnDefinition(new (Z) InstantiateTypeInstr(
token_pos, type, instantiator_type_arguments, function_type_arguments));
token_pos, type, instantiator_type_arguments, function_type_arguments,
owner()->GetNextDeoptId()));
}
@@ -1332,8 +1347,8 @@ void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
ValueGraphVisitor for_right(owner());
node->right()->Visit(&for_right);
Value* right_value = for_right.value();
for_right.Do(
new (Z) AssertBooleanInstr(node->right()->token_pos(), right_value));
for_right.Do(new (Z) AssertBooleanInstr(
node->right()->token_pos(), right_value, owner()->GetNextDeoptId()));
if (node->kind() == Token::kAND) {
Join(for_left, for_right, empty);
} else {
@@ -1368,9 +1383,10 @@ void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
const String& name = Symbols::Token(node->kind());
const intptr_t kTypeArgsLen = 0;
const intptr_t kNumArgsChecked = 2;
InstanceCallInstr* call = new (Z) InstanceCallInstr(
node->token_pos(), name, node->kind(), arguments, kTypeArgsLen,
Object::null_array(), kNumArgsChecked, owner()->ic_data_array());
InstanceCallInstr* call = new (Z)
InstanceCallInstr(node->token_pos(), name, node->kind(), arguments,
kTypeArgsLen, Object::null_array(), kNumArgsChecked,
owner()->ic_data_array(), owner()->GetNextDeoptId());
ReturnDefinition(call);
}
@@ -1393,13 +1409,13 @@ void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
Value* right_value = for_right.value();
Isolate* isolate = Isolate::Current();
if (isolate->type_checks() || isolate->asserts()) {
right_value = for_right.Bind(
new (Z) AssertBooleanInstr(node->right()->token_pos(), right_value));
right_value = for_right.Bind(new (Z) AssertBooleanInstr(
node->right()->token_pos(), right_value, owner()->GetNextDeoptId()));
}
Value* constant_true = for_right.Bind(new (Z) ConstantInstr(Bool::True()));
Value* compare = for_right.Bind(new (Z) StrictCompareInstr(
node->token_pos(), Token::kEQ_STRICT, right_value, constant_true,
false)); // No number check.
node->token_pos(), Token::kEQ_STRICT, right_value, constant_true, false,
owner()->GetNextDeoptId())); // No number check.
for_right.Do(BuildStoreExprTemp(compare, node->token_pos()));
if (node->kind() == Token::kAND) {
@@ -1535,7 +1551,7 @@ void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) {
Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()), node->kind(),
arguments, kTypeArgsLen,
Object::null_array(), // No argument names.
kNumArgsChecked, owner()->ic_data_array());
kNumArgsChecked, owner()->ic_data_array(), owner()->GetNextDeoptId());
if (negate_result) {
result = new (Z) BooleanNegateInstr(Bind(result));
}
@@ -1560,7 +1576,7 @@ void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) {
node->token_pos(), Library::PrivateCoreLibName(Symbols::_instanceOf()),
node->kind(), arguments, kTypeArgsLen,
Object::null_array(), // No argument names.
kNumArgsChecked, owner()->ic_data_array());
kNumArgsChecked, owner()->ic_data_array(), owner()->GetNextDeoptId());
if (negate_result) {
result = new (Z) BooleanNegateInstr(Bind(result));
}
@@ -1599,7 +1615,7 @@ void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) {
node->token_pos(), Library::PrivateCoreLibName(Symbols::_as()),
node->kind(), arguments, kTypeArgsLen,
Object::null_array(), // No argument names.
kNumArgsChecked, owner()->ic_data_array());
kNumArgsChecked, owner()->ic_data_array(), owner()->GetNextDeoptId());
ReturnDefinition(call);
}
@@ -1616,8 +1632,8 @@ StrictCompareInstr* EffectGraphVisitor::BuildStrictCompare(
right->Visit(&for_right_value);
Append(for_right_value);
StrictCompareInstr* comp = new (Z) StrictCompareInstr(
token_pos, kind, for_left_value.value(), for_right_value.value(),
true); // Number check.
token_pos, kind, for_left_value.value(), for_right_value.value(), true,
owner()->GetNextDeoptId()); // Number check.
return comp;
}
@@ -1673,16 +1689,17 @@ void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
const intptr_t kTypeArgsLen = 0;
const intptr_t kNumArgsChecked = 2;
Definition* result = new (Z)
InstanceCallInstr(node->token_pos(), Symbols::EqualOperator(),
Token::kEQ, // Result is negated later for kNE.
arguments, kTypeArgsLen, Object::null_array(),
kNumArgsChecked, owner()->ic_data_array());
Definition* result = new (Z) InstanceCallInstr(
node->token_pos(), Symbols::EqualOperator(),
Token::kEQ, // Result is negated later for kNE.
arguments, kTypeArgsLen, Object::null_array(), kNumArgsChecked,
owner()->ic_data_array(), owner()->GetNextDeoptId());
if (node->kind() == Token::kNE) {
Isolate* isolate = Isolate::Current();
if (isolate->type_checks() || isolate->asserts()) {
Value* value = Bind(result);
result = new (Z) AssertBooleanInstr(node->token_pos(), value);
result = new (Z) AssertBooleanInstr(node->token_pos(), value,
owner()->GetNextDeoptId());
}
Value* value = Bind(result);
result = new (Z) BooleanNegateInstr(value);
@@ -1710,7 +1727,8 @@ void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
const intptr_t kTypeArgsLen = 0;
InstanceCallInstr* comp = new (Z) InstanceCallInstr(
node->token_pos(), Symbols::Token(node->kind()), node->kind(), arguments,
kTypeArgsLen, Object::null_array(), 2, owner()->ic_data_array());
kTypeArgsLen, Object::null_array(), 2, owner()->ic_data_array(),
owner()->GetNextDeoptId());
ReturnDefinition(comp);
}
@@ -1724,8 +1742,8 @@ void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
Value* value = for_value.value();
Isolate* isolate = Isolate::Current();
if (isolate->type_checks() || isolate->asserts()) {
value =
Bind(new (Z) AssertBooleanInstr(node->operand()->token_pos(), value));
value = Bind(new (Z) AssertBooleanInstr(
node->operand()->token_pos(), value, owner()->GetNextDeoptId()));
}
BooleanNegateInstr* negate = new (Z) BooleanNegateInstr(value);
ReturnDefinition(negate);
@@ -1742,7 +1760,8 @@ void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
const intptr_t kTypeArgsLen = 0;
InstanceCallInstr* call = new (Z) InstanceCallInstr(
node->token_pos(), Symbols::Token(node->kind()), node->kind(), arguments,
kTypeArgsLen, Object::null_array(), 1, owner()->ic_data_array());
kTypeArgsLen, Object::null_array(), 1, owner()->ic_data_array(),
owner()->GetNextDeoptId());
ReturnDefinition(call);
}
@@ -1840,8 +1859,9 @@ void EffectGraphVisitor::VisitCaseNode(CaseNode* node) {
// Compute the start of the statements fragment.
JoinEntryInstr* statement_start = NULL;
if (node->label() == NULL) {
statement_start = new (Z)
JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
statement_start =
new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
owner()->GetNextDeoptId());
} else {
// The case nodes are nested inside a SequenceNode that is the body of a
// SwitchNode. The SwitchNode on the nesting stack contains the
@@ -1893,7 +1913,8 @@ void EffectGraphVisitor::VisitCaseNode(CaseNode* node) {
} else {
if (statement_exit != NULL) {
JoinEntryInstr* join = new (Z)
JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
owner()->GetNextDeoptId());
statement_exit->Goto(join);
next_target->Goto(join);
exit_instruction = join;
@@ -1976,7 +1997,8 @@ void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
// Tie do-while loop (test is after the body).
JoinEntryInstr* body_entry_join =
new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
owner()->GetNextDeoptId());
Goto(body_entry_join);
Instruction* body_exit = AppendFragment(body_entry_join, for_body);
@@ -1984,10 +2006,11 @@ void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
if ((body_exit != NULL) || (join != NULL)) {
if (join == NULL) {
join = new (Z)
JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
owner()->GetNextDeoptId());
}
CheckStackOverflowInstr* check = new (Z)
CheckStackOverflowInstr(node->token_pos(), owner()->loop_depth());
CheckStackOverflowInstr* check = new (Z) CheckStackOverflowInstr(
node->token_pos(), owner()->loop_depth(), owner()->GetNextDeoptId());
join->LinkTo(check);
check->LinkTo(for_test.entry());
if (body_exit != NULL) {
@@ -2035,8 +2058,9 @@ void EffectGraphVisitor::VisitForNode(ForNode* node) {
// Join the loop body and increment and then tie the loop.
JoinEntryInstr* continue_join = nested_loop.continue_target();
if ((continue_join != NULL) || for_body.is_open()) {
JoinEntryInstr* loop_entry = new (Z)
JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
JoinEntryInstr* loop_entry =
new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
owner()->GetNextDeoptId());
if (continue_join != NULL) {
if (for_body.is_open()) for_body.Goto(continue_join);
Instruction* current = AppendFragment(continue_join, for_increment);
@@ -2053,7 +2077,8 @@ void EffectGraphVisitor::VisitForNode(ForNode* node) {
// the context level (if any) matches the that of the increment
// expression.
AddInstruction(new (Z) CheckStackOverflowInstr(
node->increment()->token_pos(), owner()->loop_depth()));
node->increment()->token_pos(), owner()->loop_depth(),
owner()->GetNextDeoptId()));
}
if (node->condition() == NULL) {
@@ -2248,8 +2273,8 @@ void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
BuildInstantiatedTypeArguments(node->token_pos(), type_args);
Value* num_elements =
Bind(new (Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(node->length()))));
CreateArrayInstr* create =
new (Z) CreateArrayInstr(node->token_pos(), element_type, num_elements);
CreateArrayInstr* create = new (Z) CreateArrayInstr(
node->token_pos(), element_type, num_elements, owner()->GetNextDeoptId());
Value* array_val = Bind(create);
{
@@ -2299,16 +2324,16 @@ void EffectGraphVisitor::VisitStringInterpolateNode(
Z, Resolver::ResolveStatic(
cls, Library::PrivateCoreLibName(Symbols::InterpolateSingle()),
kTypeArgsLen, kNumberOfArguments, kNoArgumentNames));
StaticCallInstr* call = new (Z)
StaticCallInstr(node->token_pos(), function, kTypeArgsLen,
kNoArgumentNames, values, owner()->ic_data_array());
StaticCallInstr* call = new (Z) StaticCallInstr(
node->token_pos(), function, kTypeArgsLen, kNoArgumentNames, values,
owner()->ic_data_array(), owner()->GetNextDeoptId());
ReturnDefinition(call);
return;
}
arguments->Visit(&for_argument);
Append(for_argument);
StringInterpolateInstr* instr =
new (Z) StringInterpolateInstr(for_argument.value(), node->token_pos());
StringInterpolateInstr* instr = new (Z) StringInterpolateInstr(
for_argument.value(), node->token_pos(), owner()->GetNextDeoptId());
ReturnDefinition(instr);
}
@@ -2530,7 +2555,7 @@ void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
InstanceCallInstr* call = new (Z) InstanceCallInstr(
node->token_pos(), node->function_name(), Token::kILLEGAL, arguments,
node->arguments()->type_args_len(), node->arguments()->names(), 1,
owner()->ic_data_array());
owner()->ic_data_array(), owner()->GetNextDeoptId());
ReturnDefinition(call);
}
}
@@ -2546,7 +2571,8 @@ void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
BuildPushArguments(*node->arguments(), arguments);
StaticCallInstr* call = new (Z) StaticCallInstr(
node->token_pos(), node->function(), node->arguments()->type_args_len(),
node->arguments()->names(), arguments, owner()->ic_data_array());
node->arguments()->names(), arguments, owner()->ic_data_array(),
owner()->GetNextDeoptId());
if (node->function().recognized_kind() != MethodRecognizer::kUnknown) {
call->set_result_cid(MethodRecognizer::ResultCid(node->function()));
}
@@ -2580,8 +2606,8 @@ void EffectGraphVisitor::BuildClosureCall(ClosureCallNode* node,
function_load->set_is_immutable(true);
Value* function_val = Bind(function_load);
Definition* closure_call =
new (Z) ClosureCallInstr(function_val, node, arguments);
Definition* closure_call = new (Z) ClosureCallInstr(
function_val, node, arguments, owner()->GetNextDeoptId());
if (result_needed) {
Value* result = Bind(closure_call);
Do(new (Z) StoreLocalInstr(*tmp_var, result, ST(node->token_pos())));
@@ -2605,13 +2631,15 @@ void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
void EffectGraphVisitor::VisitInitStaticFieldNode(InitStaticFieldNode* node) {
Value* field = Bind(
new (Z) ConstantInstr(Field::ZoneHandle(Z, node->field().Original())));
AddInstruction(new (Z) InitStaticFieldInstr(field, node->field()));
AddInstruction(new (Z) InitStaticFieldInstr(field, node->field(),
owner()->GetNextDeoptId()));
}
void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
Value* context = Bind(BuildCurrentContext(node->token_pos()));
Value* clone = Bind(new (Z) CloneContextInstr(node->token_pos(), context));
Value* clone = Bind(new (Z) CloneContextInstr(node->token_pos(), context,
owner()->GetNextDeoptId()));
Do(BuildStoreContext(clone, node->token_pos()));
}
@@ -2645,9 +2673,10 @@ void EffectGraphVisitor::BuildConstructorCall(
BuildPushArguments(*node->arguments(), arguments);
const intptr_t kTypeArgsLen = 0;
Do(new (Z) StaticCallInstr(node->token_pos(), node->constructor(),
kTypeArgsLen, node->arguments()->names(),
arguments, owner()->ic_data_array()));
Do(new (Z)
StaticCallInstr(node->token_pos(), node->constructor(), kTypeArgsLen,
node->arguments()->names(), arguments,
owner()->ic_data_array(), owner()->GetNextDeoptId()));
}
@@ -2686,9 +2715,10 @@ void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
ASSERT(arguments->length() == 1);
BuildPushArguments(*node->arguments(), arguments);
const int kTypeArgsLen = 0;
StaticCallInstr* call = new (Z) StaticCallInstr(
node->token_pos(), node->constructor(), kTypeArgsLen,
node->arguments()->names(), arguments, owner()->ic_data_array());
StaticCallInstr* call = new (Z)
StaticCallInstr(node->token_pos(), node->constructor(), kTypeArgsLen,
node->arguments()->names(), arguments,
owner()->ic_data_array(), owner()->GetNextDeoptId());
const intptr_t result_cid = GetResultCidOfListFactory(node);
if (result_cid != kDynamicCid) {
call->set_result_cid(result_cid);
@@ -2830,7 +2860,7 @@ Value* EffectGraphVisitor::BuildInstantiatedTypeArguments(
}
return Bind(new (Z) InstantiateTypeArgumentsInstr(
token_pos, type_arguments, instantiator_class, instantiator_type_args,
function_type_args));
function_type_args, owner()->GetNextDeoptId()));
}
@@ -2919,9 +2949,10 @@ void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
const String& name =
String::ZoneHandle(Z, Field::GetterSymbol(node->field_name()));
const intptr_t kTypeArgsLen = 0;
InstanceCallInstr* call = new (Z) InstanceCallInstr(
node->token_pos(), name, Token::kGET, arguments, kTypeArgsLen,
Object::null_array(), 1, owner()->ic_data_array());
InstanceCallInstr* call = new (Z)
InstanceCallInstr(node->token_pos(), name, Token::kGET, arguments,
kTypeArgsLen, Object::null_array(), 1,
owner()->ic_data_array(), owner()->GetNextDeoptId());
ReturnDefinition(call);
}
}
@@ -2983,9 +3014,10 @@ void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
const int kTypeArgsLen = 0;
const intptr_t kNumArgsChecked = 1; // Do not check value type.
InstanceCallInstr* call = new (Z) InstanceCallInstr(
token_pos, name, Token::kSET, arguments, kTypeArgsLen,
Object::null_array(), kNumArgsChecked, owner()->ic_data_array());
InstanceCallInstr* call = new (Z)
InstanceCallInstr(token_pos, name, Token::kSET, arguments, kTypeArgsLen,
Object::null_array(), kNumArgsChecked,
owner()->ic_data_array(), owner()->GetNextDeoptId());
ReturnDefinition(call);
}
@@ -3030,7 +3062,8 @@ void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
const intptr_t kNumArgsChecked = 1; // Do not check value type.
Do(new (Z) InstanceCallInstr(token_pos, name, Token::kSET, arguments,
kTypeArgsLen, Object::null_array(),
kNumArgsChecked, owner()->ic_data_array()));
kNumArgsChecked, owner()->ic_data_array(),
owner()->GetNextDeoptId()));
ReturnDefinition(BuildLoadExprTemp(token_pos));
}
@@ -3093,10 +3126,10 @@ void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) {
}
ASSERT(!getter_function.IsNull());
const intptr_t kTypeArgsLen = 0;
StaticCallInstr* call =
new (Z) StaticCallInstr(node->token_pos(), getter_function, kTypeArgsLen,
Object::null_array(), // No names
arguments, owner()->ic_data_array());
StaticCallInstr* call = new (Z) StaticCallInstr(
node->token_pos(), getter_function, kTypeArgsLen,
Object::null_array(), // No names
arguments, owner()->ic_data_array(), owner()->GetNextDeoptId());
ReturnDefinition(call);
}
@@ -3158,7 +3191,8 @@ void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node,
const intptr_t kTypeArgsLen = 0;
call = new (Z) StaticCallInstr(token_pos, setter_function, kTypeArgsLen,
Object::null_array(), // No names.
arguments, owner()->ic_data_array());
arguments, owner()->ic_data_array(),
owner()->GetNextDeoptId());
}
if (result_is_needed) {
Do(call);
@@ -3250,8 +3284,9 @@ void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
Value* other = Bind(new (Z) LoadLocalInstr(*other_var, token_pos));
// Receiver is not a number because numbers override equality.
const bool kNoNumberCheck = false;
StrictCompareInstr* compare = new (Z) StrictCompareInstr(
token_pos, Token::kEQ_STRICT, receiver, other, kNoNumberCheck);
StrictCompareInstr* compare = new (Z)
StrictCompareInstr(token_pos, Token::kEQ_STRICT, receiver, other,
kNoNumberCheck, owner()->GetNextDeoptId());
return ReturnDefinition(compare);
}
case MethodRecognizer::kStringBaseLength:
@@ -3271,9 +3306,9 @@ void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
Value* zero_val =
Bind(new (Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(0))));
Value* load_val = Bind(load);
StrictCompareInstr* compare = new (Z)
StrictCompareInstr(token_pos, Token::kEQ_STRICT, load_val, zero_val,
false); // No number check.
StrictCompareInstr* compare = new (Z) StrictCompareInstr(
token_pos, Token::kEQ_STRICT, load_val, zero_val, false,
owner()->GetNextDeoptId()); // No number check.
return ReturnDefinition(compare);
}
case MethodRecognizer::kGrowableArrayLength:
@@ -3316,8 +3351,8 @@ void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
node->scope()->LookupVariable(Symbols::Length(), true);
Value* length =
Bind(new (Z) LoadLocalInstr(*length_parameter, token_pos));
CreateArrayInstr* create_array =
new CreateArrayInstr(token_pos, element_type, length);
CreateArrayInstr* create_array = new CreateArrayInstr(
token_pos, element_type, length, owner()->GetNextDeoptId());
return ReturnDefinition(create_array);
}
case MethodRecognizer::kBigint_getDigits: {
@@ -3607,7 +3642,7 @@ void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
// Generate static call to super operator.
StaticCallInstr* load = new (Z) StaticCallInstr(
node->token_pos(), *super_function, kTypeArgsLen, Object::null_array(),
arguments, owner()->ic_data_array());
arguments, owner()->ic_data_array(), owner()->GetNextDeoptId());
ReturnDefinition(load);
} else {
// Generate dynamic call to index operator.
@@ -3615,7 +3650,7 @@ void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
InstanceCallInstr* load = new (Z) InstanceCallInstr(
node->token_pos(), Symbols::IndexToken(), Token::kINDEX, arguments,
kTypeArgsLen, Object::null_array(), checked_argument_count,
owner()->ic_data_array());
owner()->ic_data_array(), owner()->GetNextDeoptId());
ReturnDefinition(load);
}
}
@@ -3681,7 +3716,7 @@ Definition* EffectGraphVisitor::BuildStoreIndexedValues(StoreIndexedNode* node,
StaticCallInstr* store = new (Z) StaticCallInstr(
token_pos, *super_function, kTypeArgsLen, Object::null_array(),
arguments, owner()->ic_data_array());
arguments, owner()->ic_data_array(), owner()->GetNextDeoptId());
if (result_is_needed) {
Do(store);
return BuildLoadExprTemp(token_pos);
@@ -3694,7 +3729,7 @@ Definition* EffectGraphVisitor::BuildStoreIndexedValues(StoreIndexedNode* node,
InstanceCallInstr* store = new (Z) InstanceCallInstr(
token_pos, Symbols::AssignIndexToken(), Token::kASSIGN_INDEX, arguments,
kTypeArgsLen, Object::null_array(), checked_argument_count,
owner()->ic_data_array());
owner()->ic_data_array(), owner()->GetNextDeoptId());
if (result_is_needed) {
Do(store);
return BuildLoadExprTemp(token_pos);
@@ -3865,11 +3900,11 @@ void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) {
ASSERT(!async_set_thread_stack_trace.IsNull());
// Call _asyncSetThreadStackTrace
const intptr_t kTypeArgsLen = 0;
StaticCallInstr* call_async_set_thread_stack_trace =
new (Z) StaticCallInstr(node->token_pos().ToSynthetic(),
async_set_thread_stack_trace, kTypeArgsLen,
Object::null_array(), arguments,
owner()->ic_data_array());
StaticCallInstr* call_async_set_thread_stack_trace = new (Z)
StaticCallInstr(node->token_pos().ToSynthetic(),
async_set_thread_stack_trace, kTypeArgsLen,
Object::null_array(), arguments,
owner()->ic_data_array(), owner()->GetNextDeoptId());
Do(call_async_set_thread_stack_trace);
}
@@ -3903,8 +3938,8 @@ void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) {
// if we inline or not.
if (!function.IsImplicitGetterFunction() &&
!function.IsImplicitSetterFunction()) {
CheckStackOverflowInstr* check =
new (Z) CheckStackOverflowInstr(node->token_pos(), 0);
CheckStackOverflowInstr* check = new (Z) CheckStackOverflowInstr(
node->token_pos(), 0, owner()->GetNextDeoptId());
// If we are inlining don't actually attach the stack check. We must still
// create the stack check in order to allocate a deopt id.
if (!owner()->IsInlining()) {
@@ -3944,8 +3979,9 @@ void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) {
if (is_top_level_sequence &&
(function.IsAsyncClosure() || function.IsSyncGenClosure() ||
function.IsAsyncGenClosure())) {
JoinEntryInstr* preamble_end = new (Z)
JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
JoinEntryInstr* preamble_end =
new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
owner()->GetNextDeoptId());
ASSERT(exit() != NULL);
exit()->Goto(preamble_end);
ASSERT(exit()->next()->IsGoto());
@@ -4087,13 +4123,14 @@ void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) {
if (for_try.is_open()) {
JoinEntryInstr* after_try = new (Z)
JoinEntryInstr(owner()->AllocateBlockId(), original_handler_index);
JoinEntryInstr(owner()->AllocateBlockId(), original_handler_index,
owner()->GetNextDeoptId());
for_try.Goto(after_try);
for_try.exit_ = after_try;
}
JoinEntryInstr* try_entry =
new (Z) JoinEntryInstr(owner()->AllocateBlockId(), try_handler_index);
JoinEntryInstr* try_entry = new (Z) JoinEntryInstr(
owner()->AllocateBlockId(), try_handler_index, owner()->GetNextDeoptId());
Goto(try_entry);
AppendFragment(try_entry, for_try);
@@ -4133,7 +4170,8 @@ void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) {
if (for_catch.is_open()) {
JoinEntryInstr* join = new (Z)
JoinEntryInstr(owner()->AllocateBlockId(), original_handler_index);
JoinEntryInstr(owner()->AllocateBlockId(), original_handler_index,
owner()->GetNextDeoptId());
for_catch.Goto(join);
if (is_open()) Goto(join);
exit_ = join;
@@ -4158,7 +4196,8 @@ void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) {
catch_block->rethrow_stacktrace_var(), finally_block->token_pos()));
for_finally.PushArgument(stacktrace);
for_finally.AddInstruction(
new (Z) ReThrowInstr(catch_block->token_pos(), catch_handler_index));
new (Z) ReThrowInstr(catch_block->token_pos(), catch_handler_index,
owner()->GetNextDeoptId()));
for_finally.CloseFragment();
}
ASSERT(!for_finally.is_open());
@@ -4221,9 +4260,9 @@ StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall(
ZoneGrowableArray<PushArgumentInstr*>* push_arguments =
new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
BuildPushArguments(*args, push_arguments);
return new (Z) StaticCallInstr(args_pos, no_such_method_func, kTypeArgsLen,
Object::null_array(), push_arguments,
owner()->ic_data_array());
return new (Z) StaticCallInstr(
args_pos, no_such_method_func, kTypeArgsLen, Object::null_array(),
push_arguments, owner()->ic_data_array(), owner()->GetNextDeoptId());
}
@@ -4289,7 +4328,8 @@ StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError(
ASSERT(!func.IsNull());
return new (Z) StaticCallInstr(token_pos, func, kTypeArgsLen,
Object::null_array(), // No names.
arguments, owner()->ic_data_array());
arguments, owner()->ic_data_array(),
owner()->GetNextDeoptId());
}
@@ -4309,13 +4349,14 @@ void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) {
PushArgument(for_exception.value());
Instruction* instr = NULL;
if (node->stacktrace() == NULL) {
instr = new (Z) ThrowInstr(node->token_pos());
instr = new (Z) ThrowInstr(node->token_pos(), owner()->GetNextDeoptId());
} else {
ValueGraphVisitor for_stack_trace(owner());
node->stacktrace()->Visit(&for_stack_trace);
Append(for_stack_trace);
PushArgument(for_stack_trace.value());
instr = new (Z) ReThrowInstr(node->token_pos(), owner()->catch_try_index());
instr = new (Z) ReThrowInstr(node->token_pos(), owner()->catch_try_index(),
owner()->GetNextDeoptId());
}
AddInstruction(instr);
}
@@ -4355,7 +4396,8 @@ void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
// context variable.
JoinEntryInstr* finally_entry =
new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
owner()->GetNextDeoptId());
EffectGraphVisitor for_finally_block(owner());
for_finally_block.AdjustContextLevel(node->finally_block()->scope());
node->finally_block()->Visit(&for_finally_block);
@@ -4365,8 +4407,9 @@ void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
}
if (for_finally_block.is_open()) {
JoinEntryInstr* after_finally = new (Z)
JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
JoinEntryInstr* after_finally =
new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
owner()->GetNextDeoptId());
for_finally_block.Goto(after_finally);
for_finally_block.exit_ = after_finally;
}
@@ -4396,8 +4439,8 @@ FlowGraph* FlowGraphBuilder::BuildGraph() {
AstPrinter ast_printer;
ast_printer.PrintFunctionScope(parsed_function());
}
TargetEntryInstr* normal_entry = new (Z)
TargetEntryInstr(AllocateBlockId(), CatchClauseNode::kInvalidTryIndex);
TargetEntryInstr* normal_entry = new (Z) TargetEntryInstr(
AllocateBlockId(), CatchClauseNode::kInvalidTryIndex, GetNextDeoptId());
graph_entry_ =
new (Z) GraphEntryInstr(parsed_function(), normal_entry, osr_id_);
EffectGraphVisitor for_effect(this);
+5
View File
@@ -114,6 +114,11 @@ class FlowGraphBuilder : public ValueObject {
intptr_t AllocateBlockId() { return ++last_used_block_id_; }
void SetInitialBlockId(intptr_t id) { last_used_block_id_ = id; }
intptr_t GetNextDeoptId() {
// TODO(rmacnak): Record current scope / context level.
return thread()->GetNextDeoptId();
}
intptr_t context_level() const;
void IncrementLoopDepth() { ++loop_depth_; }
+92 -67
View File
@@ -1480,10 +1480,10 @@ bool PolymorphicInliner::CheckInlinedDuplicate(const Function& target) {
new_join->AddDominatedBlock(block);
}
// Create a new target with the join as unconditional successor.
TargetEntryInstr* new_target =
new TargetEntryInstr(AllocateBlockId(), old_target->try_index());
TargetEntryInstr* new_target = new TargetEntryInstr(
AllocateBlockId(), old_target->try_index(), Thread::kNoDeoptId);
new_target->InheritDeoptTarget(zone(), new_join);
GotoInstr* new_goto = new (Z) GotoInstr(new_join);
GotoInstr* new_goto = new (Z) GotoInstr(new_join, Thread::kNoDeoptId);
new_goto->InheritDeoptTarget(zone(), new_join);
new_target->LinkTo(new_goto);
new_target->set_last_instruction(new_goto);
@@ -1622,8 +1622,9 @@ bool PolymorphicInliner::TryInlineRecognizedMethod(intptr_t receiver_cid,
InlineExitCollector* exit_collector =
new (Z) InlineExitCollector(owner_->caller_graph(), call_);
ReturnInstr* result = new (Z)
ReturnInstr(call_->instance_call()->token_pos(), new (Z) Value(last));
ReturnInstr* result =
new (Z) ReturnInstr(call_->instance_call()->token_pos(),
new (Z) Value(last), Thread::kNoDeoptId);
owner_->caller_graph()->AppendTo(
last, result,
call_->env(), // Return can become deoptimization target.
@@ -1653,8 +1654,8 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() {
const intptr_t try_idx = call_->GetBlock()->try_index();
// Start with a fresh target entry.
TargetEntryInstr* entry =
new (Z) TargetEntryInstr(AllocateBlockId(), try_idx);
TargetEntryInstr* entry = new (Z) TargetEntryInstr(
AllocateBlockId(), try_idx, Thread::Current()->GetNextDeoptId());
entry->InheritDeoptTarget(zone(), call_);
// This function uses a cursor (a pointer to the 'current' instruction) to
@@ -1719,7 +1720,7 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() {
// the join.
JoinEntryInstr* join = callee_entry->AsJoinEntry();
ASSERT(join->dominator() != NULL);
GotoInstr* goto_join = new GotoInstr(join);
GotoInstr* goto_join = new GotoInstr(join, Thread::kNoDeoptId);
goto_join->InheritDeoptTarget(zone(), join);
cursor->LinkTo(goto_join);
current_block->set_last_instruction(goto_join);
@@ -1749,13 +1750,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);
new BranchInstr(compare_top, Thread::kNoDeoptId);
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);
TargetEntryInstr* below_target = new TargetEntryInstr(
AllocateBlockId(), try_idx, Thread::kNoDeoptId);
below_target->InheritDeoptTarget(zone(), call_);
current_block->AddDominatedBlock(below_target);
cursor = current_block = below_target;
@@ -1765,13 +1766,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);
branch = new BranchInstr(compare_bottom, Thread::kNoDeoptId);
} else {
StrictCompareInstr* compare = new StrictCompareInstr(
call_->instance_call()->token_pos(), Token::kEQ_STRICT,
new Value(load_cid), new Value(cid_constant),
false); // No number check.
branch = new BranchInstr(compare);
/* number_check = */ false, Thread::kNoDeoptId);
branch = new BranchInstr(compare, Thread::kNoDeoptId);
}
branch->InheritDeoptTarget(zone(), call_);
@@ -1802,9 +1803,10 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() {
JoinEntryInstr* join = callee_entry->AsJoinEntry();
ASSERT(join != NULL);
ASSERT(join->dominator() != NULL);
true_target = new TargetEntryInstr(AllocateBlockId(), try_idx);
true_target = new TargetEntryInstr(AllocateBlockId(), try_idx,
Thread::kNoDeoptId);
true_target->InheritDeoptTarget(zone(), join);
GotoInstr* goto_join = new GotoInstr(join);
GotoInstr* goto_join = new GotoInstr(join, Thread::kNoDeoptId);
goto_join->InheritDeoptTarget(zone(), join);
true_target->LinkTo(goto_join);
true_target->set_last_instruction(goto_join);
@@ -1816,7 +1818,7 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() {
// fall-through code below for non-inlined variants.
TargetEntryInstr* false_target =
new TargetEntryInstr(AllocateBlockId(), try_idx);
new TargetEntryInstr(AllocateBlockId(), try_idx, Thread::kNoDeoptId);
false_target->InheritDeoptTarget(zone(), call_);
*branch->false_successor_address() = false_target;
cid_test_entry_block->AddDominatedBlock(false_target);
@@ -1826,14 +1828,15 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() {
if (test_is_range) {
// 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);
TargetEntryInstr* false_target2 =
new TargetEntryInstr(AllocateBlockId(), try_idx);
JoinEntryInstr* join =
new JoinEntryInstr(AllocateBlockId(), try_idx, Thread::kNoDeoptId);
TargetEntryInstr* false_target2 = new TargetEntryInstr(
AllocateBlockId(), try_idx, Thread::kNoDeoptId);
*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);
GotoInstr* goto_2 = new GotoInstr(join);
GotoInstr* goto_1 = new GotoInstr(join, Thread::kNoDeoptId);
GotoInstr* goto_2 = new GotoInstr(join, Thread::kNoDeoptId);
false_target->LinkTo(goto_1);
false_target2->LinkTo(goto_2);
false_target->set_last_instruction(goto_1);
@@ -1866,8 +1869,9 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() {
owner_->caller_graph()->alloc_ssa_temp_index());
fallback_call->InheritDeoptTarget(zone(), call_);
fallback_call->set_total_call_count(call_->CallCount());
ReturnInstr* fallback_return = new ReturnInstr(
call_->instance_call()->token_pos(), new Value(fallback_call));
ReturnInstr* fallback_return =
new ReturnInstr(call_->instance_call()->token_pos(),
new Value(fallback_call), Thread::kNoDeoptId);
fallback_return->InheritDeoptTargetAfter(owner_->caller_graph(), call_,
fallback_call);
AppendInstruction(AppendInstruction(cursor, fallback_call),
@@ -2243,8 +2247,9 @@ 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());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
Instruction* cursor = *entry;
@@ -2292,8 +2297,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());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
Instruction* cursor = *entry;
if (flow_graph->isolate()->type_checks()) {
@@ -2429,8 +2435,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());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
// Arguments are checked. No need for class check.
BinaryDoubleOpInstr* double_bin_op = new (Z)
@@ -2453,8 +2460,9 @@ static bool InlineDoubleTestOp(FlowGraph* flow_graph,
return false;
}
*entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
// Arguments are checked. No need for class check.
@@ -2475,8 +2483,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());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
// Right arguments is known to be smi: other._bitAndFromSmi(this);
BinarySmiOpInstr* smi_op =
@@ -2499,8 +2508,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());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
// This is an internal method, no need to check argument types.
@@ -2585,8 +2595,9 @@ static bool InlineByteArrayBaseLoad(FlowGraph* flow_graph,
ASSERT(array_cid != kIllegalCid);
Definition* array = receiver;
Definition* index = call->ArgumentAt(1);
*entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
Instruction* cursor = *entry;
@@ -2628,8 +2639,9 @@ static bool InlineByteArrayBaseStore(FlowGraph* flow_graph,
ASSERT(array_cid != kIllegalCid);
Definition* array = receiver;
Definition* index = call->ArgumentAt(1);
*entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
Instruction* cursor = *entry;
@@ -2794,8 +2806,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());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
*last = PrepareInlineStringIndexOp(flow_graph, call, cid, str, index, *entry);
@@ -2822,8 +2835,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());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
*last = PrepareInlineStringIndexOp(flow_graph, call, cid, str, index, *entry);
@@ -2935,8 +2949,9 @@ static bool InlineFloat32x4Method(FlowGraph* flow_graph,
return false;
}
*entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
Instruction* cursor = *entry;
switch (kind) {
@@ -3053,8 +3068,9 @@ static bool InlineSimdShuffleMethod(FlowGraph* flow_graph,
if (!ShouldInlineSimd()) {
return false;
}
*entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
Instruction* cursor = *entry;
Definition* mask_definition = call->ArgumentAt(1);
@@ -3081,8 +3097,9 @@ static bool InlineSimdShuffleMixMethod(FlowGraph* flow_graph,
if (!ShouldInlineSimd()) {
return false;
}
*entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
Instruction* cursor = *entry;
Definition* mask_definition = call->ArgumentAt(2);
@@ -3110,8 +3127,9 @@ static bool InlineInt32x4Method(FlowGraph* flow_graph,
if (!ShouldInlineSimd()) {
return false;
}
*entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
Instruction* cursor = *entry;
switch (kind) {
@@ -3166,8 +3184,9 @@ static bool InlineFloat64x2Method(FlowGraph* flow_graph,
if (!ShouldInlineSimd()) {
return false;
}
*entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
Instruction* cursor = *entry;
switch (kind) {
@@ -3217,8 +3236,9 @@ static bool InlineSimdConstructor(FlowGraph* flow_graph,
if (!ShouldInlineSimd()) {
return false;
}
*entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
Instruction* cursor = *entry;
switch (kind) {
@@ -3298,8 +3318,9 @@ static bool InlineMathCFunction(FlowGraph* flow_graph,
if (!CanUnboxDouble()) {
return false;
}
*entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
Instruction* cursor = *entry;
@@ -3660,8 +3681,9 @@ bool FlowGraphInliner::TryInlineRecognizedMethod(FlowGraph* flow_graph,
return InlineMathCFunction(flow_graph, call, kind, entry, last);
case MethodRecognizer::kObjectConstructor: {
*entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
ASSERT(!call->HasUses());
*last = NULL; // Empty body.
@@ -3676,10 +3698,11 @@ bool FlowGraphInliner::TryInlineRecognizedMethod(FlowGraph* flow_graph,
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());
call->GetBlock()->try_index(),
Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
*last =
new (Z) CreateArrayInstr(call->token_pos(), type, num_elements);
*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,
@@ -3707,8 +3730,9 @@ bool FlowGraphInliner::TryInlineRecognizedMethod(FlowGraph* flow_graph,
}
if (!type.IsNull()) {
*entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
*last = new (Z) ConstantInstr(type);
flow_graph->AppendTo(
@@ -3723,8 +3747,9 @@ bool FlowGraphInliner::TryInlineRecognizedMethod(FlowGraph* flow_graph,
case MethodRecognizer::kOneByteStringSetAt: {
// This is an internal method, no need to check argument types nor
// range.
*entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index());
*entry = new (Z)
TargetEntryInstr(flow_graph->allocate_block_id(),
call->GetBlock()->try_index(), Thread::kNoDeoptId);
(*entry)->InheritDeoptTarget(Z, call);
Definition* str = call->ArgumentAt(0);
Definition* index = call->ArgumentAt(1);
+10 -6
View File
@@ -604,7 +604,9 @@ const Object& Value::BoundConstant() const {
GraphEntryInstr::GraphEntryInstr(const ParsedFunction& parsed_function,
TargetEntryInstr* normal_entry,
intptr_t osr_id)
: BlockEntryInstr(0, CatchClauseNode::kInvalidTryIndex),
: BlockEntryInstr(0,
CatchClauseNode::kInvalidTryIndex,
Thread::Current()->GetNextDeoptId()),
parsed_function_(parsed_function),
normal_entry_(normal_entry),
catch_entries_(),
@@ -1109,7 +1111,8 @@ bool BlockEntryInstr::PruneUnreachable(GraphEntryInstr* graph_entry,
// we can simply jump to the beginning of the block.
ASSERT(instr->previous() == this);
GotoInstr* goto_join = new GotoInstr(AsJoinEntry());
GotoInstr* goto_join =
new GotoInstr(AsJoinEntry(), Thread::Current()->GetNextDeoptId());
goto_join->CopyDeoptIdFrom(*parent);
graph_entry->normal_entry()->LinkTo(goto_join);
return true;
@@ -1336,7 +1339,7 @@ BlockEntryInstr* GotoInstr::SuccessorAt(intptr_t index) const {
void Instruction::Goto(JoinEntryInstr* entry) {
LinkTo(new GotoInstr(entry));
LinkTo(new GotoInstr(entry, Thread::Current()->GetNextDeoptId()));
}
@@ -3222,8 +3225,9 @@ StrictCompareInstr::StrictCompareInstr(TokenPosition token_pos,
Token::Kind kind,
Value* left,
Value* right,
bool needs_number_check)
: TemplateComparison(token_pos, kind, Thread::Current()->GetNextDeoptId()),
bool needs_number_check,
intptr_t deopt_id)
: TemplateComparison(token_pos, kind, deopt_id),
needs_number_check_(needs_number_check) {
ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT));
SetInputAt(0, left);
@@ -3834,7 +3838,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());
needs_number_check(), Thread::kNoDeoptId);
}
+70 -60
View File
@@ -1262,8 +1262,8 @@ class BlockEntryInstr : public Instruction {
DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry)
protected:
BlockEntryInstr(intptr_t block_id, intptr_t try_index)
: Instruction(Thread::Current()->GetNextDeoptId()),
BlockEntryInstr(intptr_t block_id, intptr_t try_index, intptr_t deopt_id)
: Instruction(deopt_id),
block_id_(block_id),
try_index_(try_index),
preorder_number_(-1),
@@ -1442,8 +1442,8 @@ class GraphEntryInstr : public BlockEntryInstr {
class JoinEntryInstr : public BlockEntryInstr {
public:
JoinEntryInstr(intptr_t block_id, intptr_t try_index)
: BlockEntryInstr(block_id, try_index),
JoinEntryInstr(intptr_t block_id, intptr_t try_index, intptr_t deopt_id)
: BlockEntryInstr(block_id, try_index, deopt_id),
predecessors_(2), // Two is the assumed to be the common case.
phis_(NULL) {}
@@ -1512,8 +1512,8 @@ class PhiIterator : public ValueObject {
class TargetEntryInstr : public BlockEntryInstr {
public:
TargetEntryInstr(intptr_t block_id, intptr_t try_index)
: BlockEntryInstr(block_id, try_index),
TargetEntryInstr(intptr_t block_id, intptr_t try_index, intptr_t deopt_id)
: BlockEntryInstr(block_id, try_index, deopt_id),
predecessor_(NULL),
edge_weight_(0.0) {}
@@ -1553,8 +1553,10 @@ class IndirectEntryInstr : public JoinEntryInstr {
public:
IndirectEntryInstr(intptr_t block_id,
intptr_t indirect_id,
intptr_t try_index)
: JoinEntryInstr(block_id, try_index), indirect_id_(indirect_id) {}
intptr_t try_index,
intptr_t deopt_id)
: JoinEntryInstr(block_id, try_index, deopt_id),
indirect_id_(indirect_id) {}
DECLARE_INSTRUCTION(IndirectEntry)
@@ -1581,7 +1583,7 @@ class CatchBlockEntryInstr : public BlockEntryInstr {
bool needs_stacktrace,
intptr_t deopt_id,
bool should_restore_closure_context = false)
: BlockEntryInstr(block_id, try_index),
: BlockEntryInstr(block_id, try_index, deopt_id),
graph_entry_(graph_entry),
predecessor_(NULL),
catch_handler_types_(Array::ZoneHandle(handler_types.raw())),
@@ -1591,9 +1593,7 @@ class CatchBlockEntryInstr : public BlockEntryInstr {
needs_stacktrace_(needs_stacktrace),
should_restore_closure_context_(should_restore_closure_context),
handler_token_pos_(handler_token_pos),
is_generated_(is_generated) {
deopt_id_ = deopt_id;
}
is_generated_(is_generated) {}
DECLARE_INSTRUCTION(CatchBlockEntry)
@@ -2108,9 +2108,8 @@ inline Definition* Instruction::ArgumentAt(intptr_t index) const {
class ReturnInstr : public TemplateInstruction<1, NoThrow> {
public:
ReturnInstr(TokenPosition token_pos, Value* value)
: TemplateInstruction(Thread::Current()->GetNextDeoptId()),
token_pos_(token_pos) {
ReturnInstr(TokenPosition token_pos, Value* value, intptr_t deopt_id)
: TemplateInstruction(deopt_id), token_pos_(token_pos) {
SetInputAt(0, value);
}
@@ -2138,9 +2137,8 @@ class ReturnInstr : public TemplateInstruction<1, NoThrow> {
class ThrowInstr : public TemplateInstruction<0, Throws> {
public:
explicit ThrowInstr(TokenPosition token_pos)
: TemplateInstruction(Thread::Current()->GetNextDeoptId()),
token_pos_(token_pos) {}
explicit ThrowInstr(TokenPosition token_pos, intptr_t deopt_id)
: TemplateInstruction(deopt_id), token_pos_(token_pos) {}
DECLARE_INSTRUCTION(Throw)
@@ -2163,8 +2161,10 @@ class ReThrowInstr : public TemplateInstruction<0, Throws> {
public:
// 'catch_try_index' can be CatchClauseNode::kInvalidTryIndex if the
// rethrow has been artificially generated by the parser.
ReThrowInstr(TokenPosition token_pos, intptr_t catch_try_index)
: TemplateInstruction(Thread::Current()->GetNextDeoptId()),
ReThrowInstr(TokenPosition token_pos,
intptr_t catch_try_index,
intptr_t deopt_id)
: TemplateInstruction(deopt_id),
token_pos_(token_pos),
catch_try_index_(catch_try_index) {}
@@ -2214,8 +2214,8 @@ class StopInstr : public TemplateInstruction<0, NoThrow> {
class GotoInstr : public TemplateInstruction<0, NoThrow> {
public:
explicit GotoInstr(JoinEntryInstr* entry)
: TemplateInstruction(Thread::Current()->GetNextDeoptId()),
explicit GotoInstr(JoinEntryInstr* entry, intptr_t deopt_id)
: TemplateInstruction(deopt_id),
block_(NULL),
successor_(entry),
edge_weight_(0.0),
@@ -2428,10 +2428,8 @@ class TemplateComparison
class BranchInstr : public Instruction {
public:
explicit BranchInstr(ComparisonInstr* comparison)
: Instruction(Thread::Current()->GetNextDeoptId()),
comparison_(comparison),
constant_target_(NULL) {
explicit BranchInstr(ComparisonInstr* comparison, intptr_t deopt_id)
: Instruction(deopt_id), comparison_(comparison), constant_target_(NULL) {
ASSERT(comparison->env() == NULL);
for (intptr_t i = comparison->InputCount() - 1; i >= 0; --i) {
comparison->InputAt(i)->set_instruction(this);
@@ -2710,9 +2708,8 @@ class AssertAssignableInstr : public TemplateDefinition<3, Throws, Pure> {
class AssertBooleanInstr : public TemplateDefinition<1, Throws, Pure> {
public:
AssertBooleanInstr(TokenPosition token_pos, Value* value)
: TemplateDefinition(Thread::Current()->GetNextDeoptId()),
token_pos_(token_pos) {
AssertBooleanInstr(TokenPosition token_pos, Value* value, intptr_t deopt_id)
: TemplateDefinition(deopt_id), token_pos_(token_pos) {
SetInputAt(0, value);
}
@@ -2741,8 +2738,8 @@ class AssertBooleanInstr : public TemplateDefinition<1, Throws, Pure> {
// a computation, not a value, because it's mutable.
class CurrentContextInstr : public TemplateDefinition<0, NoThrow> {
public:
CurrentContextInstr()
: TemplateDefinition(Thread::Current()->GetNextDeoptId()) {}
explicit CurrentContextInstr(intptr_t deopt_id)
: TemplateDefinition(deopt_id) {}
DECLARE_INSTRUCTION(CurrentContext)
virtual CompileType ComputeType() const;
@@ -2825,8 +2822,9 @@ class ClosureCallInstr : public TemplateDartCall<1> {
public:
ClosureCallInstr(Value* function,
ClosureCallNode* node,
ZoneGrowableArray<PushArgumentInstr*>* arguments)
: TemplateDartCall(Thread::Current()->GetNextDeoptId(),
ZoneGrowableArray<PushArgumentInstr*>* arguments,
intptr_t deopt_id)
: TemplateDartCall(deopt_id,
node->arguments()->type_args_len(),
node->arguments()->names(),
arguments,
@@ -2839,8 +2837,9 @@ class ClosureCallInstr : public TemplateDartCall<1> {
ZoneGrowableArray<PushArgumentInstr*>* arguments,
intptr_t type_args_len,
const Array& argument_names,
TokenPosition token_pos)
: TemplateDartCall(Thread::Current()->GetNextDeoptId(),
TokenPosition token_pos,
intptr_t deopt_id)
: TemplateDartCall(deopt_id,
type_args_len,
argument_names,
arguments,
@@ -2874,8 +2873,9 @@ class InstanceCallInstr : public TemplateDartCall<0> {
intptr_t type_args_len,
const Array& argument_names,
intptr_t checked_argument_count,
const ZoneGrowableArray<const ICData*>& ic_data_array)
: TemplateDartCall(Thread::Current()->GetNextDeoptId(),
const ZoneGrowableArray<const ICData*>& ic_data_array,
intptr_t deopt_id)
: TemplateDartCall(deopt_id,
type_args_len,
argument_names,
arguments,
@@ -3033,7 +3033,8 @@ class StrictCompareInstr : public TemplateComparison<2, NoThrow, Pure> {
Token::Kind kind,
Value* left,
Value* right,
bool needs_number_check);
bool needs_number_check,
intptr_t deopt_id);
DECLARE_INSTRUCTION(StrictCompare)
@@ -3245,8 +3246,11 @@ class RelationalOpInstr : public TemplateComparison<2, NoThrow, Pure> {
// materialization of true and false constants.
class IfThenElseInstr : public Definition {
public:
IfThenElseInstr(ComparisonInstr* comparison, Value* if_true, Value* if_false)
: Definition(Thread::Current()->GetNextDeoptId()),
IfThenElseInstr(ComparisonInstr* comparison,
Value* if_true,
Value* if_false,
intptr_t deopt_id)
: Definition(deopt_id),
comparison_(comparison),
if_true_(Smi::Cast(if_true->BoundConstant()).Value()),
if_false_(Smi::Cast(if_false->BoundConstant()).Value()) {
@@ -3328,8 +3332,9 @@ class StaticCallInstr : public TemplateDartCall<0> {
intptr_t type_args_len,
const Array& argument_names,
ZoneGrowableArray<PushArgumentInstr*>* arguments,
const ZoneGrowableArray<const ICData*>& ic_data_array)
: TemplateDartCall(Thread::Current()->GetNextDeoptId(),
const ZoneGrowableArray<const ICData*>& ic_data_array,
intptr_t deopt_id)
: TemplateDartCall(deopt_id,
type_args_len,
argument_names,
arguments,
@@ -4049,8 +4054,10 @@ class StringToCharCodeInstr : public TemplateDefinition<1, NoThrow, Pure> {
class StringInterpolateInstr : public TemplateDefinition<1, Throws> {
public:
StringInterpolateInstr(Value* value, TokenPosition token_pos)
: TemplateDefinition(Thread::Current()->GetNextDeoptId()),
StringInterpolateInstr(Value* value,
TokenPosition token_pos,
intptr_t deopt_id)
: TemplateDefinition(deopt_id),
token_pos_(token_pos),
function_(Function::ZoneHandle()) {
SetInputAt(0, value);
@@ -4385,8 +4392,9 @@ class CreateArrayInstr : public TemplateDefinition<2, Throws> {
public:
CreateArrayInstr(TokenPosition token_pos,
Value* element_type,
Value* num_elements)
: TemplateDefinition(Thread::Current()->GetNextDeoptId()),
Value* num_elements,
intptr_t deopt_id)
: TemplateDefinition(deopt_id),
token_pos_(token_pos),
identity_(AliasIdentity::Unknown()) {
SetInputAt(kElementTypePos, element_type);
@@ -4594,10 +4602,9 @@ class InstantiateTypeInstr : public TemplateDefinition<2, Throws> {
InstantiateTypeInstr(TokenPosition token_pos,
const AbstractType& type,
Value* instantiator_type_arguments,
Value* function_type_arguments)
: TemplateDefinition(Thread::Current()->GetNextDeoptId()),
token_pos_(token_pos),
type_(type) {
Value* function_type_arguments,
intptr_t deopt_id)
: TemplateDefinition(deopt_id), token_pos_(token_pos), type_(type) {
ASSERT(type.IsZoneHandle() || type.IsReadOnlyHandle());
SetInputAt(0, instantiator_type_arguments);
SetInputAt(1, function_type_arguments);
@@ -4630,8 +4637,9 @@ class InstantiateTypeArgumentsInstr : public TemplateDefinition<2, Throws> {
const TypeArguments& type_arguments,
const Class& instantiator_class,
Value* instantiator_type_arguments,
Value* function_type_arguments)
: TemplateDefinition(Thread::Current()->GetNextDeoptId()),
Value* function_type_arguments,
intptr_t deopt_id)
: TemplateDefinition(deopt_id),
token_pos_(token_pos),
type_arguments_(type_arguments),
instantiator_class_(instantiator_class) {
@@ -4692,9 +4700,8 @@ class AllocateContextInstr : public TemplateDefinition<0, NoThrow> {
class InitStaticFieldInstr : public TemplateInstruction<1, Throws> {
public:
InitStaticFieldInstr(Value* input, const Field& field)
: TemplateInstruction(Thread::Current()->GetNextDeoptId()),
field_(field) {
InitStaticFieldInstr(Value* input, const Field& field, intptr_t deopt_id)
: TemplateInstruction(deopt_id), field_(field) {
SetInputAt(0, input);
CheckField(field);
}
@@ -4717,9 +4724,10 @@ class InitStaticFieldInstr : public TemplateInstruction<1, Throws> {
class CloneContextInstr : public TemplateDefinition<1, NoThrow> {
public:
CloneContextInstr(TokenPosition token_pos, Value* context_value)
: TemplateDefinition(Thread::Current()->GetNextDeoptId()),
token_pos_(token_pos) {
CloneContextInstr(TokenPosition token_pos,
Value* context_value,
intptr_t deopt_id)
: TemplateDefinition(deopt_id), token_pos_(token_pos) {
SetInputAt(0, context_value);
}
@@ -7254,8 +7262,10 @@ class UnaryDoubleOpInstr : public TemplateDefinition<1, NoThrow, Pure> {
class CheckStackOverflowInstr : public TemplateInstruction<0, NoThrow> {
public:
CheckStackOverflowInstr(TokenPosition token_pos, intptr_t loop_depth)
: TemplateInstruction(Thread::Current()->GetNextDeoptId()),
CheckStackOverflowInstr(TokenPosition token_pos,
intptr_t loop_depth,
intptr_t deopt_id)
: TemplateInstruction(deopt_id),
token_pos_(token_pos),
loop_depth_(loop_depth) {}
+5 -5
View File
@@ -8,19 +8,19 @@
namespace dart {
TEST_CASE(InstructionTests) {
TargetEntryInstr* target_instr =
new TargetEntryInstr(1, CatchClauseNode::kInvalidTryIndex);
TargetEntryInstr* target_instr = new TargetEntryInstr(
1, CatchClauseNode::kInvalidTryIndex, Thread::kNoDeoptId);
EXPECT(target_instr->IsBlockEntry());
EXPECT(!target_instr->IsDefinition());
CurrentContextInstr* context = new CurrentContextInstr();
CurrentContextInstr* context = new CurrentContextInstr(Thread::kNoDeoptId);
EXPECT(context->IsDefinition());
EXPECT(!context->IsBlockEntry());
}
TEST_CASE(OptimizationTests) {
JoinEntryInstr* join =
new JoinEntryInstr(1, CatchClauseNode::kInvalidTryIndex);
JoinEntryInstr* join = new JoinEntryInstr(
1, CatchClauseNode::kInvalidTryIndex, Thread::kNoDeoptId);
Definition* def1 = new PhiInstr(join, 0);
Definition* def2 = new PhiInstr(join, 0);
+4 -2
View File
@@ -170,7 +170,8 @@ bool Intrinsifier::GraphIntrinsify(const ParsedFunction& parsed_function,
intptr_t block_id = builder.AllocateBlockId();
TargetEntryInstr* normal_entry =
new TargetEntryInstr(block_id, CatchClauseNode::kInvalidTryIndex);
new TargetEntryInstr(block_id, CatchClauseNode::kInvalidTryIndex,
Thread::Current()->GetNextDeoptId());
GraphEntryInstr* graph_entry = new GraphEntryInstr(
parsed_function, normal_entry, Compiler::kNoOSRDeoptId);
FlowGraph* graph = new FlowGraph(parsed_function, graph_entry, block_id);
@@ -318,7 +319,8 @@ class BlockBuilder : public ValueObject {
}
void AddIntrinsicReturn(Value* value) {
ReturnInstr* instr = new ReturnInstr(TokenPos(), value);
ReturnInstr* instr =
new ReturnInstr(TokenPos(), value, Thread::Current()->GetNextDeoptId());
AddInstruction(instr);
entry_->set_last_instruction(instr);
}
+4 -5
View File
@@ -602,7 +602,7 @@ bool JitOptimizer::TryReplaceWithEqualityOp(InstanceCallInstr* call,
StrictCompareInstr* comp = new (Z)
StrictCompareInstr(call->token_pos(), Token::kEQ_STRICT,
new (Z) Value(left), new (Z) Value(right),
false); // No number check.
/* number_check = */ false, Thread::kNoDeoptId);
ReplaceCall(call, comp);
return true;
}
@@ -1356,10 +1356,9 @@ void JitOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) {
ConstantInstr* cid =
flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(type_cid)));
StrictCompareInstr* check_cid =
new (Z) StrictCompareInstr(call->token_pos(), Token::kEQ_STRICT,
new (Z) Value(left_cid), new (Z) Value(cid),
false); // No number check.
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);
ReplaceCall(call, check_cid);
return;
}
+3 -2
View File
@@ -3554,7 +3554,7 @@ Fragment StreamingFlowGraphBuilder::BuildWhileStatement() {
Fragment loop(join);
loop += CheckStackOverflow();
loop += condition;
entry = new (Z) GotoInstr(join);
entry = new (Z) GotoInstr(join, Thread::Current()->GetNextDeoptId());
} else {
entry = condition.entry;
}
@@ -3588,7 +3588,8 @@ Fragment StreamingFlowGraphBuilder::BuildDoStatement() {
repeat += Goto(join);
loop_depth_dec();
return Fragment(new (Z) GotoInstr(join), loop_exit);
return Fragment(new (Z) GotoInstr(join, Thread::Current()->GetNextDeoptId()),
loop_exit);
}
Fragment StreamingFlowGraphBuilder::BuildForStatement() {
+51 -42
View File
@@ -2017,6 +2017,7 @@ FlowGraphBuilder::FlowGraphBuilder(
intptr_t osr_id,
intptr_t first_block_id)
: translation_helper_(Thread::Current()),
thread_(translation_helper_.thread()),
zone_(translation_helper_.zone()),
node_(node),
parsed_function_(parsed_function),
@@ -2248,9 +2249,9 @@ Fragment FlowGraphBuilder::LoadFunctionTypeArguments() {
Fragment FlowGraphBuilder::InstantiateType(const AbstractType& type) {
Value* function_type_args = Pop();
Value* instantiator_type_args = Pop();
InstantiateTypeInstr* instr =
new (Z) InstantiateTypeInstr(TokenPosition::kNoSource, type,
instantiator_type_args, function_type_args);
InstantiateTypeInstr* instr = new (Z) InstantiateTypeInstr(
TokenPosition::kNoSource, type, instantiator_type_args,
function_type_args, GetNextDeoptId());
Push(instr);
return Fragment(instr);
}
@@ -2262,7 +2263,7 @@ Fragment FlowGraphBuilder::InstantiateTypeArguments(
Value* instantiator_type_args = Pop();
InstantiateTypeArgumentsInstr* instr = new (Z) InstantiateTypeArgumentsInstr(
TokenPosition::kNoSource, type_arguments, *active_class_.klass,
instantiator_type_args, function_type_args);
instantiator_type_args, function_type_args, GetNextDeoptId());
Push(instr);
return Fragment(instr);
}
@@ -2352,8 +2353,9 @@ Fragment FlowGraphBuilder::StrictCompare(Token::Kind kind,
bool number_check /* = false */) {
Value* right = Pop();
Value* left = Pop();
StrictCompareInstr* compare = new (Z) StrictCompareInstr(
TokenPosition::kNoSource, kind, left, right, number_check);
StrictCompareInstr* compare =
new (Z) StrictCompareInstr(TokenPosition::kNoSource, kind, left, right,
number_check, GetNextDeoptId());
Push(compare);
return Fragment(compare);
}
@@ -2381,8 +2383,8 @@ Fragment FlowGraphBuilder::BranchIfEqual(TargetEntryInstr** then_entry,
Value* left_value = Pop();
StrictCompareInstr* compare = new (Z) StrictCompareInstr(
TokenPosition::kNoSource, negate ? Token::kNE_STRICT : Token::kEQ_STRICT,
left_value, right_value, false);
BranchInstr* branch = new (Z) BranchInstr(compare);
left_value, right_value, false, GetNextDeoptId());
BranchInstr* branch = new (Z) BranchInstr(compare, GetNextDeoptId());
*then_entry = *branch->true_successor_address() = BuildTargetEntry();
*otherwise_entry = *branch->false_successor_address() = BuildTargetEntry();
return Fragment(branch).closed();
@@ -2394,9 +2396,10 @@ Fragment FlowGraphBuilder::BranchIfStrictEqual(
TargetEntryInstr** otherwise_entry) {
Value* rhs = Pop();
Value* lhs = Pop();
StrictCompareInstr* compare = new (Z) StrictCompareInstr(
TokenPosition::kNoSource, Token::kEQ_STRICT, lhs, rhs, false);
BranchInstr* branch = new (Z) BranchInstr(compare);
StrictCompareInstr* compare =
new (Z) StrictCompareInstr(TokenPosition::kNoSource, Token::kEQ_STRICT,
lhs, rhs, false, GetNextDeoptId());
BranchInstr* branch = new (Z) BranchInstr(compare, GetNextDeoptId());
*then_entry = *branch->true_successor_address() = BuildTargetEntry();
*otherwise_entry = *branch->false_successor_address() = BuildTargetEntry();
return Fragment(branch).closed();
@@ -2446,8 +2449,8 @@ Fragment FlowGraphBuilder::TryCatch(int try_handler_index) {
// => We therefore create a block for the body (fresh try index) and another
// join block (with current try index).
Fragment body;
JoinEntryInstr* entry =
new (Z) JoinEntryInstr(AllocateBlockId(), try_handler_index);
JoinEntryInstr* entry = new (Z)
JoinEntryInstr(AllocateBlockId(), try_handler_index, GetNextDeoptId());
body += LoadLocal(parsed_function_->current_context_var());
body += StoreLocal(TokenPosition::kNoSource, CurrentCatchContext());
body += Drop();
@@ -2468,8 +2471,8 @@ Fragment FlowGraphBuilder::CheckStackOverflowInPrologue() {
Fragment FlowGraphBuilder::CheckStackOverflow() {
return Fragment(
new (Z) CheckStackOverflowInstr(TokenPosition::kNoSource, loop_depth_));
return Fragment(new (Z) CheckStackOverflowInstr(
TokenPosition::kNoSource, loop_depth_, GetNextDeoptId()));
}
@@ -2478,8 +2481,8 @@ Fragment FlowGraphBuilder::CloneContext() {
Fragment instructions = LoadLocal(context_variable);
CloneContextInstr* clone_instruction =
new (Z) CloneContextInstr(TokenPosition::kNoSource, Pop());
CloneContextInstr* clone_instruction = new (Z)
CloneContextInstr(TokenPosition::kNoSource, Pop(), GetNextDeoptId());
instructions <<= clone_instruction;
Push(clone_instruction);
@@ -2499,16 +2502,17 @@ Fragment FlowGraphBuilder::Constant(const Object& value) {
Fragment FlowGraphBuilder::CreateArray() {
Value* element_count = Pop();
CreateArrayInstr* array = new (Z) CreateArrayInstr(TokenPosition::kNoSource,
Pop(), // Element type.
element_count);
CreateArrayInstr* array =
new (Z) CreateArrayInstr(TokenPosition::kNoSource,
Pop(), // Element type.
element_count, GetNextDeoptId());
Push(array);
return Fragment(array);
}
Fragment FlowGraphBuilder::Goto(JoinEntryInstr* destination) {
return Fragment(new (Z) GotoInstr(destination)).closed();
return Fragment(new (Z) GotoInstr(destination, GetNextDeoptId())).closed();
}
@@ -2536,9 +2540,9 @@ Fragment FlowGraphBuilder::InstanceCall(TokenPosition position,
intptr_t num_args_checked) {
ArgumentArray arguments = GetArguments(argument_count);
const intptr_t kTypeArgsLen = 0; // Generic instance calls not yet supported.
InstanceCallInstr* call = new (Z)
InstanceCallInstr(position, name, kind, arguments, kTypeArgsLen,
argument_names, num_args_checked, ic_data_array_);
InstanceCallInstr* call = new (Z) InstanceCallInstr(
position, name, kind, arguments, kTypeArgsLen, argument_names,
num_args_checked, ic_data_array_, GetNextDeoptId());
Push(call);
return Fragment(call);
}
@@ -2549,9 +2553,9 @@ Fragment FlowGraphBuilder::ClosureCall(int argument_count,
Value* function = Pop();
ArgumentArray arguments = GetArguments(argument_count);
const intptr_t kTypeArgsLen = 0; // Generic closures not yet supported.
ClosureCallInstr* call =
new (Z) ClosureCallInstr(function, arguments, kTypeArgsLen,
argument_names, TokenPosition::kNoSource);
ClosureCallInstr* call = new (Z)
ClosureCallInstr(function, arguments, kTypeArgsLen, argument_names,
TokenPosition::kNoSource, GetNextDeoptId());
Push(call);
return Fragment(call);
}
@@ -2560,7 +2564,8 @@ Fragment FlowGraphBuilder::ClosureCall(int argument_count,
Fragment FlowGraphBuilder::ThrowException(TokenPosition position) {
Fragment instructions;
instructions += Drop();
instructions += Fragment(new (Z) ThrowInstr(position)).closed();
instructions +=
Fragment(new (Z) ThrowInstr(position, GetNextDeoptId())).closed();
// Use it's side effect of leaving a constant on the stack (does not change
// the graph).
NullConstant();
@@ -2576,8 +2581,9 @@ Fragment FlowGraphBuilder::RethrowException(TokenPosition position,
Fragment instructions;
instructions += Drop();
instructions += Drop();
instructions +=
Fragment(new (Z) ReThrowInstr(position, catch_try_index)).closed();
instructions += Fragment(new (Z) ReThrowInstr(position, catch_try_index,
GetNextDeoptId()))
.closed();
// Use it's side effect of leaving a constant on the stack (does not change
// the graph).
NullConstant();
@@ -2657,8 +2663,8 @@ Fragment FlowGraphBuilder::LoadLocal(LocalVariable* variable) {
Fragment FlowGraphBuilder::InitStaticField(const dart::Field& field) {
InitStaticFieldInstr* init =
new (Z) InitStaticFieldInstr(Pop(), MayCloneField(Z, field));
InitStaticFieldInstr* init = new (Z)
InitStaticFieldInstr(Pop(), MayCloneField(Z, field), GetNextDeoptId());
return Fragment(init);
}
@@ -2721,7 +2727,8 @@ Fragment FlowGraphBuilder::Return(TokenPosition position) {
instructions += Drop();
}
ReturnInstr* return_instr = new (Z) ReturnInstr(position, value);
ReturnInstr* return_instr =
new (Z) ReturnInstr(position, value, GetNextDeoptId());
if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr);
instructions <<= return_instr;
@@ -2767,7 +2774,7 @@ Fragment FlowGraphBuilder::StaticCall(TokenPosition position,
const intptr_t kTypeArgsLen = 0; // Generic static calls not yet supported.
StaticCallInstr* call =
new (Z) StaticCallInstr(position, target, kTypeArgsLen, argument_names,
arguments, ic_data_array_);
arguments, ic_data_array_, GetNextDeoptId());
const intptr_t list_cid =
GetResultCidOfListFactory(Z, target, argument_count);
if (list_cid != kDynamicCid) {
@@ -2881,7 +2888,7 @@ Fragment FlowGraphBuilder::StoreStaticField(TokenPosition position,
Fragment FlowGraphBuilder::StringInterpolate(TokenPosition position) {
Value* array = Pop();
StringInterpolateInstr* interpolate =
new (Z) StringInterpolateInstr(array, position);
new (Z) StringInterpolateInstr(array, position, GetNextDeoptId());
Push(interpolate);
return Fragment(interpolate);
}
@@ -3931,8 +3938,8 @@ Fragment FlowGraphBuilder::CheckAssignableInCheckedMode(
Fragment FlowGraphBuilder::AssertBool() {
Value* value = Pop();
AssertBooleanInstr* instr =
new (Z) AssertBooleanInstr(TokenPosition::kNoSource, value);
AssertBooleanInstr* instr = new (Z)
AssertBooleanInstr(TokenPosition::kNoSource, value, GetNextDeoptId());
Push(instr);
return Fragment(instr);
}
@@ -4271,17 +4278,19 @@ void FlowGraphBuilder::SetupDefaultParameterValues(FunctionNode* function) {
TargetEntryInstr* FlowGraphBuilder::BuildTargetEntry() {
return new (Z) TargetEntryInstr(AllocateBlockId(), CurrentTryIndex());
return new (Z)
TargetEntryInstr(AllocateBlockId(), CurrentTryIndex(), GetNextDeoptId());
}
JoinEntryInstr* FlowGraphBuilder::BuildJoinEntry(intptr_t try_index) {
return new (Z) JoinEntryInstr(AllocateBlockId(), try_index);
return new (Z) JoinEntryInstr(AllocateBlockId(), try_index, GetNextDeoptId());
}
JoinEntryInstr* FlowGraphBuilder::BuildJoinEntry() {
return new (Z) JoinEntryInstr(AllocateBlockId(), CurrentTryIndex());
return new (Z)
JoinEntryInstr(AllocateBlockId(), CurrentTryIndex(), GetNextDeoptId());
}
@@ -5869,7 +5878,7 @@ void FlowGraphBuilder::VisitWhileStatement(WhileStatement* node) {
Fragment loop(join);
loop += CheckStackOverflow();
loop += condition;
entry = new (Z) GotoInstr(join);
entry = new (Z) GotoInstr(join, GetNextDeoptId());
} else {
entry = condition.entry;
}
@@ -5905,7 +5914,7 @@ void FlowGraphBuilder::VisitDoStatement(DoStatement* node) {
Fragment repeat(loop_repeat);
repeat += Goto(join);
fragment_ = Fragment(new (Z) GotoInstr(join), loop_exit);
fragment_ = Fragment(new (Z) GotoInstr(join, GetNextDeoptId()), loop_exit);
--loop_depth_;
}
+6
View File
@@ -1042,6 +1042,7 @@ class FlowGraphBuilder : public ExpressionVisitor, public StatementVisitor {
void InlineBailout(const char* reason);
TranslationHelper translation_helper_;
Thread* thread_;
Zone* zone_;
// The node we are currently compiling (e.g. FunctionNode, Constructor,
@@ -1056,6 +1057,11 @@ class FlowGraphBuilder : public ExpressionVisitor, public StatementVisitor {
intptr_t next_block_id_;
intptr_t AllocateBlockId() { return next_block_id_++; }
intptr_t GetNextDeoptId() {
// TODO(rmacnak): Record current scope / context level.
return thread_->GetNextDeoptId();
}
intptr_t next_function_id_;
intptr_t AllocateFunctionId() { return next_function_id_++; }
+1 -1
View File
@@ -13,7 +13,7 @@ BlockLabel::BlockLabel()
: block_(NULL), is_bound_(false), is_linked_(false), pos_(-1) {
if (!FLAG_interpret_irregexp) {
// Only needed by the compiled IR backend.
block_ = new JoinEntryInstr(-1, -1);
block_ = new JoinEntryInstr(-1, -1, Thread::Current()->GetNextDeoptId());
}
}
+39 -33
View File
@@ -80,6 +80,7 @@ IRRegExpMacroAssembler::IRRegExpMacroAssembler(
const ZoneGrowableArray<const ICData*>& ic_data_array,
Zone* zone)
: RegExpMacroAssembler(zone),
thread_(Thread::Current()),
specialization_cid_(specialization_cid),
parsed_function_(parsed_function),
ic_data_array_(ic_data_array),
@@ -122,14 +123,17 @@ IRRegExpMacroAssembler::IRRegExpMacroAssembler(
// Create and generate all preset blocks.
entry_block_ = new (zone) GraphEntryInstr(
*parsed_function_,
new (zone) TargetEntryInstr(block_id_.Alloc(), kInvalidTryIndex),
new (zone) TargetEntryInstr(block_id_.Alloc(), kInvalidTryIndex,
GetNextDeoptId()),
Compiler::kNoOSRDeoptId);
start_block_ = new (zone) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
success_block_ =
new (zone) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
backtrack_block_ =
new (zone) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
exit_block_ = new (zone) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
start_block_ = new (zone)
JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex, GetNextDeoptId());
success_block_ = new (zone)
JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex, GetNextDeoptId());
backtrack_block_ = new (zone)
JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex, GetNextDeoptId());
exit_block_ = new (zone)
JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex, GetNextDeoptId());
GenerateEntryBlock();
GenerateSuccessBlock();
@@ -252,8 +256,8 @@ void IRRegExpMacroAssembler::GenerateSuccessBlock() {
Value* type = Bind(new (Z) ConstantInstr(
TypeArguments::ZoneHandle(Z, TypeArguments::null())));
Value* length = Bind(Uint64Constant(saved_registers_count_));
Value* array =
Bind(new (Z) CreateArrayInstr(TokenPosition::kNoSource, type, length));
Value* array = Bind(new (Z) CreateArrayInstr(TokenPosition::kNoSource, type,
length, GetNextDeoptId()));
StoreLocal(result_, array);
// Store captured offsets in the `matches` parameter.
@@ -276,8 +280,8 @@ void IRRegExpMacroAssembler::GenerateSuccessBlock() {
PRINT(PushLocal(result_));
// Return true on success.
AppendInstruction(
new (Z) ReturnInstr(TokenPosition::kNoSource, Bind(LoadLocal(result_))));
AppendInstruction(new (Z) ReturnInstr(
TokenPosition::kNoSource, Bind(LoadLocal(result_)), GetNextDeoptId()));
}
@@ -286,8 +290,8 @@ void IRRegExpMacroAssembler::GenerateExitBlock() {
TAG();
// Return false on failure.
AppendInstruction(
new (Z) ReturnInstr(TokenPosition::kNoSource, Bind(LoadLocal(result_))));
AppendInstruction(new (Z) ReturnInstr(
TokenPosition::kNoSource, Bind(LoadLocal(result_)), GetNextDeoptId()));
}
@@ -489,8 +493,9 @@ ComparisonInstr* IRRegExpMacroAssembler::Comparison(ComparisonKind kind,
InstanceCallDescriptor::FromToken(intermediate_operator), lhs, rhs));
Value* rhs_value = Bind(BoolConstant(true));
return new (Z) StrictCompareInstr(TokenPosition::kNoSource, strict_comparison,
lhs_value, rhs_value, true);
return new (Z)
StrictCompareInstr(TokenPosition::kNoSource, strict_comparison, lhs_value,
rhs_value, true, GetNextDeoptId());
}
ComparisonInstr* IRRegExpMacroAssembler::Comparison(ComparisonKind kind,
@@ -538,9 +543,9 @@ StaticCallInstr* IRRegExpMacroAssembler::StaticCall(
const Function& function,
ZoneGrowableArray<PushArgumentInstr*>* arguments) const {
const intptr_t kTypeArgsLen = 0;
return new (Z)
StaticCallInstr(TokenPosition::kNoSource, function, kTypeArgsLen,
Object::null_array(), arguments, ic_data_array_);
return new (Z) StaticCallInstr(TokenPosition::kNoSource, function,
kTypeArgsLen, Object::null_array(), arguments,
ic_data_array_, GetNextDeoptId());
}
@@ -587,10 +592,10 @@ InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall(
const InstanceCallDescriptor& desc,
ZoneGrowableArray<PushArgumentInstr*>* arguments) const {
const intptr_t kTypeArgsLen = 0;
return new (Z)
InstanceCallInstr(TokenPosition::kNoSource, desc.name, desc.token_kind,
arguments, kTypeArgsLen, Object::null_array(),
desc.checked_argument_count, ic_data_array_);
return new (Z) InstanceCallInstr(
TokenPosition::kNoSource, desc.name, desc.token_kind, arguments,
kTypeArgsLen, Object::null_array(), desc.checked_argument_count,
ic_data_array_, GetNextDeoptId());
}
@@ -1571,8 +1576,8 @@ void IRRegExpMacroAssembler::CheckStackLimit() {
PushArgumentInstr* capacity_push = PushArgument(Bind(Sub(
length_push, PushArgument(Bind(Uint64Constant(stack_limit_slack()))))));
PushArgumentInstr* stack_pointer_push = PushLocal(stack_pointer_);
BranchInstr* branch =
new (Z) BranchInstr(Comparison(kGT, capacity_push, stack_pointer_push));
BranchInstr* branch = new (Z) BranchInstr(
Comparison(kGT, capacity_push, stack_pointer_push), GetNextDeoptId());
CloseBlockWith(branch);
BlockLabel grow_stack;
@@ -1728,7 +1733,7 @@ void IRRegExpMacroAssembler::BranchOrBacktrack(ComparisonInstr* comparison,
// If the condition is not true, fall through to a new block.
BlockLabel fallthrough;
BranchInstr* branch = new (Z) BranchInstr(comparison);
BranchInstr* branch = new (Z) BranchInstr(comparison, GetNextDeoptId());
*branch->true_successor_address() = TargetWithJoinGoto(true_successor_block);
*branch->false_successor_address() = TargetWithJoinGoto(fallthrough.block());
@@ -1739,11 +1744,11 @@ void IRRegExpMacroAssembler::BranchOrBacktrack(ComparisonInstr* comparison,
TargetEntryInstr* IRRegExpMacroAssembler::TargetWithJoinGoto(
JoinEntryInstr* dst) {
TargetEntryInstr* target =
new (Z) TargetEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
TargetEntryInstr* target = new (Z)
TargetEntryInstr(block_id_.Alloc(), kInvalidTryIndex, GetNextDeoptId());
blocks_.Add(target);
target->AppendInstruction(new (Z) GotoInstr(dst));
target->AppendInstruction(new (Z) GotoInstr(dst, GetNextDeoptId()));
return target;
}
@@ -1751,11 +1756,12 @@ TargetEntryInstr* IRRegExpMacroAssembler::TargetWithJoinGoto(
IndirectEntryInstr* IRRegExpMacroAssembler::IndirectWithJoinGoto(
JoinEntryInstr* dst) {
IndirectEntryInstr* target = new (Z) IndirectEntryInstr(
block_id_.Alloc(), indirect_id_.Alloc(), kInvalidTryIndex);
IndirectEntryInstr* target =
new (Z) IndirectEntryInstr(block_id_.Alloc(), indirect_id_.Alloc(),
kInvalidTryIndex, GetNextDeoptId());
blocks_.Add(target);
target->AppendInstruction(new (Z) GotoInstr(dst));
target->AppendInstruction(new (Z) GotoInstr(dst, GetNextDeoptId()));
return target;
}
@@ -1763,8 +1769,8 @@ IndirectEntryInstr* IRRegExpMacroAssembler::IndirectWithJoinGoto(
void IRRegExpMacroAssembler::CheckPreemption() {
TAG();
AppendInstruction(new (Z)
CheckStackOverflowInstr(TokenPosition::kNoSource, 0));
AppendInstruction(new (Z) CheckStackOverflowInstr(TokenPosition::kNoSource, 0,
GetNextDeoptId()));
}
+4
View File
@@ -132,6 +132,8 @@ class IRRegExpMacroAssembler : public RegExpMacroAssembler {
void FinalizeRegistersArray();
private:
intptr_t GetNextDeoptId() const { return thread_->GetNextDeoptId(); }
// Generate the contents of preset blocks. The entry block is the entry point
// of the generated code.
void GenerateEntryBlock();
@@ -359,6 +361,8 @@ class IRRegExpMacroAssembler : public RegExpMacroAssembler {
intptr_t next_id;
};
Thread* thread_;
// Which mode to generate code for (ASCII or UC16).
Mode mode_;
+29 -26
View File
@@ -2955,33 +2955,36 @@ RawObject* Simulator::Call(const Code& code,
{
BYTECODE(CreateArrayOpt, A_B_C);
const intptr_t length = Smi::Value(RAW_CAST(Smi, FP[rB]));
if (LIKELY(static_cast<uintptr_t>(length) <= Array::kMaxElements)) {
const intptr_t fixed_size_plus_alignment_padding =
sizeof(RawArray) + kObjectAlignment - 1;
const intptr_t instance_size =
(fixed_size_plus_alignment_padding + length * kWordSize) &
~(kObjectAlignment - 1);
const uword start =
thread->heap()->new_space()->TryAllocate(instance_size);
if (LIKELY(start != 0)) {
const intptr_t cid = kArrayCid;
uword tags = 0;
if (LIKELY(instance_size <= RawObject::SizeTag::kMaxSizeTag)) {
tags = RawObject::SizeTag::update(instance_size, tags);
if (LIKELY(!FP[rB]->IsHeapObject())) {
const intptr_t length = Smi::Value(RAW_CAST(Smi, FP[rB]));
if (LIKELY(static_cast<uintptr_t>(length) <= Array::kMaxElements)) {
const intptr_t fixed_size_plus_alignment_padding =
sizeof(RawArray) + kObjectAlignment - 1;
const intptr_t instance_size =
(fixed_size_plus_alignment_padding + length * kWordSize) &
~(kObjectAlignment - 1);
const uword start =
thread->heap()->new_space()->TryAllocate(instance_size);
if (LIKELY(start != 0)) {
const intptr_t cid = kArrayCid;
uword tags = 0;
if (LIKELY(instance_size <= RawObject::SizeTag::kMaxSizeTag)) {
tags = RawObject::SizeTag::update(instance_size, tags);
}
tags = RawObject::ClassIdTag::update(cid, tags);
*reinterpret_cast<uword*>(start + Instance::tags_offset()) = tags;
*reinterpret_cast<RawObject**>(start + Array::length_offset()) =
FP[rB];
*reinterpret_cast<RawObject**>(
start + Array::type_arguments_offset()) = FP[rC];
RawObject** data =
reinterpret_cast<RawObject**>(start + Array::data_offset());
for (intptr_t i = 0; i < length; i++) {
data[i] = null_value;
}
FP[rA] = reinterpret_cast<RawObject*>(start + kHeapObjectTag);
pc += 4;
}
tags = RawObject::ClassIdTag::update(cid, tags);
*reinterpret_cast<uword*>(start + Instance::tags_offset()) = tags;
*reinterpret_cast<RawObject**>(start + Array::length_offset()) = FP[rB];
*reinterpret_cast<RawObject**>(start + Array::type_arguments_offset()) =
FP[rC];
RawObject** data =
reinterpret_cast<RawObject**>(start + Array::data_offset());
for (intptr_t i = 0; i < length; i++) {
data[i] = null_value;
}
FP[rA] = reinterpret_cast<RawObject*>(start + kHeapObjectTag);
pc += 4;
}
}
DISPATCH();
@@ -0,0 +1,24 @@
// Copyright (c) 2017, 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.
// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation --enable_inlining_annotations
const NeverInline = "NeverInline";
foo(n) {
return new List(n);
}
@NeverInline
bar(n) {
try {
return foo(n);
} catch (e) {}
}
main() {
for (var i = 0; i < 20; i++) {
bar(5);
}
bar("");
}
@@ -0,0 +1,20 @@
// Copyright (c) 2017, 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.
// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation --enable_inlining_annotations
const NeverInline = "NeverInline";
@NeverInline
foo(n) {
try {
return new List(n);
} catch (e) {}
}
main() {
for (var i = 0; i < 20; i++) {
foo(5);
}
foo("");
}