Merge V8 5.3.332.45. DO NOT MERGE
Test: Manual
FPIIM-449
Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc
index da8b626..d8d60f3 100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -281,9 +281,9 @@
return NewPathToken(TokenDispenserForFinally::kFallThroughToken);
}
Node* NewPathDispatchCondition(Node* t1, Node* t2) {
- // TODO(mstarzinger): This should be machine()->WordEqual(), but our Phi
- // nodes all have kRepTagged|kTypeAny, which causes representation mismatch.
- return owner_->NewNode(owner_->javascript()->StrictEqual(), t1, t2);
+ return owner_->NewNode(
+ owner_->javascript()->StrictEqual(CompareOperationHints::Any()), t1,
+ t2);
}
private:
@@ -416,8 +416,15 @@
FrameStateBeforeAndAfter(AstGraphBuilder* builder, BailoutId id_before)
: builder_(builder), frame_state_before_(nullptr) {
frame_state_before_ = id_before == BailoutId::None()
- ? builder_->jsgraph()->EmptyFrameState()
+ ? builder_->GetEmptyFrameState()
: builder_->environment()->Checkpoint(id_before);
+ if (id_before != BailoutId::None()) {
+ // Create an explicit checkpoint node for before the operation.
+ Node* node = builder_->NewNode(builder_->common()->Checkpoint());
+ DCHECK_EQ(IrOpcode::kDead,
+ NodeProperties::GetFrameStateInput(node, 0)->opcode());
+ NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_before_);
+ }
}
void AddToNode(
@@ -435,7 +442,7 @@
Node* frame_state_after =
id_after == BailoutId::None()
- ? builder_->jsgraph()->EmptyFrameState()
+ ? builder_->GetEmptyFrameState()
: builder_->environment()->Checkpoint(id_after, combine,
node_has_exception);
@@ -444,6 +451,7 @@
if (count >= 2) {
// Add the frame state for before the operation.
+ // TODO(mstarzinger): Get rid of frame state input before!
DCHECK_EQ(IrOpcode::kDead,
NodeProperties::GetFrameStateInput(node, 1)->opcode());
NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_);
@@ -539,6 +547,18 @@
return new_target_.get();
}
+Node* AstGraphBuilder::GetEmptyFrameState() {
+ if (!empty_frame_state_.is_set()) {
+ const Operator* op = common()->FrameState(
+ BailoutId::None(), OutputFrameStateCombine::Ignore(), nullptr);
+ Node* node = graph()->NewNode(
+ op, jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(),
+ jsgraph()->EmptyStateValues(), jsgraph()->NoContextConstant(),
+ jsgraph()->UndefinedConstant(), graph()->start());
+ empty_frame_state_.set(node);
+ }
+ return empty_frame_state_.get();
+}
bool AstGraphBuilder::CreateGraph(bool stack_check) {
Scope* scope = info()->scope();
@@ -875,7 +895,7 @@
OutputFrameStateCombine combine,
bool owner_has_exception) {
if (!builder()->info()->is_deoptimization_enabled()) {
- return builder()->jsgraph()->EmptyFrameState();
+ return builder()->GetEmptyFrameState();
}
UpdateStateValues(¶meters_node_, 0, parameters_count());
@@ -1112,18 +1132,10 @@
}
break;
case VariableLocation::LOOKUP: {
+ DCHECK(!hole_init);
Node* name = jsgraph()->Constant(variable->name());
- // For variables we must not push an initial value (such as 'undefined')
- // because we may have a (legal) redeclaration and we must not destroy
- // the current value.
- Node* value =
- hole_init ? jsgraph()->TheHoleConstant()
- : jsgraph()->ZeroConstant(); // Indicates no initial value.
- Node* attr =
- jsgraph()->Constant(variable->DeclarationPropertyAttributes());
- const Operator* op =
- javascript()->CallRuntime(Runtime::kDeclareLookupSlot);
- Node* store = NewNode(op, name, value, attr);
+ const Operator* op = javascript()->CallRuntime(Runtime::kDeclareEvalVar);
+ Node* store = NewNode(op, name);
PrepareFrameState(store, decl->proxy()->id());
break;
}
@@ -1162,11 +1174,9 @@
VisitForValue(decl->fun());
Node* value = environment()->Pop();
Node* name = jsgraph()->Constant(variable->name());
- Node* attr =
- jsgraph()->Constant(variable->DeclarationPropertyAttributes());
const Operator* op =
- javascript()->CallRuntime(Runtime::kDeclareLookupSlot);
- Node* store = NewNode(op, name, value, attr);
+ javascript()->CallRuntime(Runtime::kDeclareEvalFunction);
+ Node* store = NewNode(op, name, value);
PrepareFrameState(store, decl->proxy()->id());
break;
}
@@ -1289,7 +1299,15 @@
VisitForValue(clause->label());
Node* label = environment()->Pop();
Node* tag = environment()->Top();
- const Operator* op = javascript()->StrictEqual();
+
+ CompareOperationHints hints;
+ if (!type_hint_analysis_ ||
+ !type_hint_analysis_->GetCompareOperationHints(clause->CompareId(),
+ &hints)) {
+ hints = CompareOperationHints::Any();
+ }
+
+ const Operator* op = javascript()->StrictEqual(hints);
Node* condition = NewNode(op, tag, label);
compare_switch.BeginLabel(i, condition);
@@ -1365,10 +1383,12 @@
for_block.BeginBlock();
// Check for null or undefined before entering loop.
Node* is_null_cond =
- NewNode(javascript()->StrictEqual(), object, jsgraph()->NullConstant());
+ NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), object,
+ jsgraph()->NullConstant());
for_block.BreakWhen(is_null_cond, BranchHint::kFalse);
- Node* is_undefined_cond = NewNode(javascript()->StrictEqual(), object,
- jsgraph()->UndefinedConstant());
+ Node* is_undefined_cond =
+ NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), object,
+ jsgraph()->UndefinedConstant());
for_block.BreakWhen(is_undefined_cond, BranchHint::kFalse);
{
// Convert object to jsobject.
@@ -1411,8 +1431,9 @@
PrepareFrameState(value, stmt->FilterId(),
OutputFrameStateCombine::Push());
IfBuilder test_value(this);
- Node* test_value_cond = NewNode(javascript()->StrictEqual(), value,
- jsgraph()->UndefinedConstant());
+ Node* test_value_cond =
+ NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
+ value, jsgraph()->UndefinedConstant());
test_value.If(test_value_cond, BranchHint::kFalse);
test_value.Then();
test_value.Else();
@@ -1602,12 +1623,12 @@
environment()->Push(literal);
// Load the "prototype" from the constructor.
- FrameStateBeforeAndAfter states(this, expr->CreateLiteralId());
+ PrepareEagerCheckpoint(expr->CreateLiteralId());
Handle<Name> name = isolate()->factory()->prototype_string();
VectorSlotPair pair = CreateVectorSlotPair(expr->PrototypeSlot());
Node* prototype = BuildNamedLoad(literal, name, pair);
- states.AddToNode(prototype, expr->PrototypeId(),
- OutputFrameStateCombine::Push());
+ PrepareFrameState(prototype, expr->PrototypeId(),
+ OutputFrameStateCombine::Push());
environment()->Push(prototype);
// Create nodes to store method values into the literal.
@@ -1647,7 +1668,8 @@
jsgraph()->Constant(property->NeedsSetFunctionName());
const Operator* op =
javascript()->CallRuntime(Runtime::kDefineDataPropertyInLiteral);
- NewNode(op, receiver, key, value, attr, set_function_name);
+ Node* call = NewNode(op, receiver, key, value, attr, set_function_name);
+ PrepareFrameState(call, BailoutId::None());
break;
}
case ObjectLiteral::Property::GETTER: {
@@ -1676,12 +1698,11 @@
// Assign to class variable.
if (expr->class_variable_proxy() != nullptr) {
Variable* var = expr->class_variable_proxy()->var();
- FrameStateBeforeAndAfter states(this, BailoutId::None());
VectorSlotPair feedback = CreateVectorSlotPair(
expr->NeedsProxySlot() ? expr->ProxySlot()
: FeedbackVectorSlot::Invalid());
BuildVariableAssignment(var, literal, Token::INIT, feedback,
- BailoutId::None(), states);
+ BailoutId::None());
}
ast_context()->ProduceValue(literal);
}
@@ -1715,8 +1736,8 @@
void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
VectorSlotPair pair = CreateVectorSlotPair(expr->VariableFeedbackSlot());
- FrameStateBeforeAndAfter states(this, BeforeId(expr));
- Node* value = BuildVariableLoad(expr->var(), expr->id(), states, pair,
+ PrepareEagerCheckpoint(BeforeId(expr));
+ Node* value = BuildVariableLoad(expr->var(), expr->id(), pair,
ast_context()->GetStateCombine());
ast_context()->ProduceValue(value);
}
@@ -1776,15 +1797,15 @@
if (key->value()->IsInternalizedString()) {
if (property->emit_store()) {
VisitForValue(property->value());
- FrameStateBeforeAndAfter states(this, property->value()->id());
+ PrepareEagerCheckpoint(property->value()->id());
Node* value = environment()->Pop();
Node* literal = environment()->Top();
Handle<Name> name = key->AsPropertyName();
VectorSlotPair feedback =
CreateVectorSlotPair(property->GetSlot(0));
Node* store = BuildNamedStore(literal, name, value, feedback);
- states.AddToNode(store, key->id(),
- OutputFrameStateCombine::Ignore());
+ PrepareFrameState(store, key->id(),
+ OutputFrameStateCombine::Ignore());
BuildSetHomeObject(value, literal, property, 1);
} else {
VisitForEffect(property->value());
@@ -1823,12 +1844,16 @@
}
case ObjectLiteral::Property::GETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->getter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->getter = property;
}
break;
case ObjectLiteral::Property::SETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->setter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->setter = property;
}
break;
}
@@ -1849,8 +1874,7 @@
const Operator* op =
javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked);
Node* call = NewNode(op, literal, name, getter, setter, attr);
- // This should not lazy deopt on a new literal.
- PrepareFrameState(call, BailoutId::None());
+ PrepareFrameState(call, it->second->bailout_id);
}
// Object literals have two parts. The "static" part on the left contains no
@@ -1896,7 +1920,8 @@
jsgraph()->Constant(property->NeedsSetFunctionName());
const Operator* op =
javascript()->CallRuntime(Runtime::kDefineDataPropertyInLiteral);
- NewNode(op, receiver, key, value, attr, set_function_name);
+ Node* call = NewNode(op, receiver, key, value, attr, set_function_name);
+ PrepareFrameState(call, expr->GetIdForPropertySet(property_index));
break;
}
case ObjectLiteral::Property::PROTOTYPE:
@@ -1961,14 +1986,14 @@
VisitForValue(subexpr);
{
- FrameStateBeforeAndAfter states(this, subexpr->id());
+ PrepareEagerCheckpoint(subexpr->id());
VectorSlotPair pair = CreateVectorSlotPair(expr->LiteralFeedbackSlot());
Node* value = environment()->Pop();
Node* index = jsgraph()->Constant(array_index);
Node* literal = environment()->Top();
Node* store = BuildKeyedStore(literal, index, value, pair);
- states.AddToNode(store, expr->GetIdForElement(array_index),
- OutputFrameStateCombine::Ignore());
+ PrepareFrameState(store, expr->GetIdForElement(array_index),
+ OutputFrameStateCombine::Ignore());
}
}
@@ -2011,49 +2036,49 @@
case VARIABLE: {
Variable* var = expr->AsVariableProxy()->var();
environment()->Push(value);
- FrameStateBeforeAndAfter states(this, bailout_id_before);
+ PrepareEagerCheckpoint(bailout_id_before);
value = environment()->Pop();
BuildVariableAssignment(var, value, Token::ASSIGN, feedback,
- bailout_id_after, states);
+ bailout_id_after);
break;
}
case NAMED_PROPERTY: {
environment()->Push(value);
VisitForValue(property->obj());
- FrameStateBeforeAndAfter states(this, property->obj()->id());
+ PrepareEagerCheckpoint(property->obj()->id());
Node* object = environment()->Pop();
value = environment()->Pop();
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
Node* store = BuildNamedStore(object, name, value, feedback);
- states.AddToNode(store, bailout_id_after,
- OutputFrameStateCombine::Ignore());
+ PrepareFrameState(store, bailout_id_after,
+ OutputFrameStateCombine::Ignore());
break;
}
case KEYED_PROPERTY: {
environment()->Push(value);
VisitForValue(property->obj());
VisitForValue(property->key());
- FrameStateBeforeAndAfter states(this, property->key()->id());
+ PrepareEagerCheckpoint(property->key()->id());
Node* key = environment()->Pop();
Node* object = environment()->Pop();
value = environment()->Pop();
Node* store = BuildKeyedStore(object, key, value, feedback);
- states.AddToNode(store, bailout_id_after,
- OutputFrameStateCombine::Ignore());
+ PrepareFrameState(store, bailout_id_after,
+ OutputFrameStateCombine::Ignore());
break;
}
case NAMED_SUPER_PROPERTY: {
environment()->Push(value);
VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
- FrameStateBeforeAndAfter states(this, property->obj()->id());
+ PrepareEagerCheckpoint(property->obj()->id());
Node* home_object = environment()->Pop();
Node* receiver = environment()->Pop();
value = environment()->Pop();
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
Node* store = BuildNamedSuperStore(receiver, home_object, name, value);
- states.AddToNode(store, bailout_id_after,
- OutputFrameStateCombine::Ignore());
+ PrepareFrameState(store, bailout_id_after,
+ OutputFrameStateCombine::Ignore());
break;
}
case KEYED_SUPER_PROPERTY: {
@@ -2061,14 +2086,14 @@
VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
VisitForValue(property->key());
- FrameStateBeforeAndAfter states(this, property->key()->id());
+ PrepareEagerCheckpoint(property->key()->id());
Node* key = environment()->Pop();
Node* home_object = environment()->Pop();
Node* receiver = environment()->Pop();
value = environment()->Pop();
Node* store = BuildKeyedSuperStore(receiver, home_object, key, value);
- states.AddToNode(store, bailout_id_after,
- OutputFrameStateCombine::Ignore());
+ PrepareFrameState(store, bailout_id_after,
+ OutputFrameStateCombine::Ignore());
break;
}
}
@@ -2122,10 +2147,9 @@
VariableProxy* proxy = expr->target()->AsVariableProxy();
VectorSlotPair pair =
CreateVectorSlotPair(proxy->VariableFeedbackSlot());
- FrameStateBeforeAndAfter states(this, BeforeId(proxy));
- old_value =
- BuildVariableLoad(proxy->var(), expr->target()->id(), states, pair,
- OutputFrameStateCombine::Push());
+ PrepareEagerCheckpoint(BeforeId(proxy));
+ old_value = BuildVariableLoad(proxy->var(), expr->target()->id(), pair,
+ OutputFrameStateCombine::Push());
break;
}
case NAMED_PROPERTY: {
@@ -2133,10 +2157,10 @@
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
- FrameStateBeforeAndAfter states(this, property->obj()->id());
+ PrepareEagerCheckpoint(property->obj()->id());
old_value = BuildNamedLoad(object, name, pair);
- states.AddToNode(old_value, property->LoadId(),
- OutputFrameStateCombine::Push());
+ PrepareFrameState(old_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
break;
}
case KEYED_PROPERTY: {
@@ -2144,10 +2168,10 @@
Node* object = environment()->Peek(1);
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
- FrameStateBeforeAndAfter states(this, property->key()->id());
+ PrepareEagerCheckpoint(property->key()->id());
old_value = BuildKeyedLoad(object, key, pair);
- states.AddToNode(old_value, property->LoadId(),
- OutputFrameStateCombine::Push());
+ PrepareFrameState(old_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
break;
}
case NAMED_SUPER_PROPERTY: {
@@ -2156,10 +2180,10 @@
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
- FrameStateBeforeAndAfter states(this, property->obj()->id());
+ PrepareEagerCheckpoint(property->obj()->id());
old_value = BuildNamedSuperLoad(receiver, home_object, name, pair);
- states.AddToNode(old_value, property->LoadId(),
- OutputFrameStateCombine::Push());
+ PrepareFrameState(old_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
break;
}
case KEYED_SUPER_PROPERTY: {
@@ -2168,10 +2192,10 @@
Node* receiver = environment()->Peek(2);
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
- FrameStateBeforeAndAfter states(this, property->key()->id());
+ PrepareEagerCheckpoint(property->key()->id());
old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
- states.AddToNode(old_value, property->LoadId(),
- OutputFrameStateCombine::Push());
+ PrepareFrameState(old_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
break;
}
}
@@ -2199,31 +2223,29 @@
}
}
- FrameStateBeforeAndAfter store_states(this, before_store_id);
// Store the value.
+ PrepareEagerCheckpoint(before_store_id);
Node* value = environment()->Pop();
VectorSlotPair feedback = CreateVectorSlotPair(expr->AssignmentSlot());
switch (assign_type) {
case VARIABLE: {
Variable* variable = expr->target()->AsVariableProxy()->var();
BuildVariableAssignment(variable, value, expr->op(), feedback, expr->id(),
- store_states, ast_context()->GetStateCombine());
+ ast_context()->GetStateCombine());
break;
}
case NAMED_PROPERTY: {
Node* object = environment()->Pop();
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
Node* store = BuildNamedStore(object, name, value, feedback);
- store_states.AddToNode(store, expr->id(),
- ast_context()->GetStateCombine());
+ PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine());
break;
}
case KEYED_PROPERTY: {
Node* key = environment()->Pop();
Node* object = environment()->Pop();
Node* store = BuildKeyedStore(object, key, value, feedback);
- store_states.AddToNode(store, expr->id(),
- ast_context()->GetStateCombine());
+ PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine());
break;
}
case NAMED_SUPER_PROPERTY: {
@@ -2231,8 +2253,7 @@
Node* receiver = environment()->Pop();
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
Node* store = BuildNamedSuperStore(receiver, home_object, name, value);
- store_states.AddToNode(store, expr->id(),
- ast_context()->GetStateCombine());
+ PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine());
break;
}
case KEYED_SUPER_PROPERTY: {
@@ -2240,8 +2261,7 @@
Node* home_object = environment()->Pop();
Node* receiver = environment()->Pop();
Node* store = BuildKeyedSuperStore(receiver, home_object, key, value);
- store_states.AddToNode(store, expr->id(),
- ast_context()->GetStateCombine());
+ PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine());
break;
}
}
@@ -2275,44 +2295,44 @@
break;
case NAMED_PROPERTY: {
VisitForValue(expr->obj());
- FrameStateBeforeAndAfter states(this, expr->obj()->id());
+ PrepareEagerCheckpoint(expr->obj()->id());
Node* object = environment()->Pop();
Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName();
value = BuildNamedLoad(object, name, pair);
- states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
+ PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
break;
}
case KEYED_PROPERTY: {
VisitForValue(expr->obj());
VisitForValue(expr->key());
- FrameStateBeforeAndAfter states(this, expr->key()->id());
+ PrepareEagerCheckpoint(expr->key()->id());
Node* key = environment()->Pop();
Node* object = environment()->Pop();
value = BuildKeyedLoad(object, key, pair);
- states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
+ PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
break;
}
case NAMED_SUPER_PROPERTY: {
VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var());
VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object());
- FrameStateBeforeAndAfter states(this, expr->obj()->id());
+ PrepareEagerCheckpoint(expr->obj()->id());
Node* home_object = environment()->Pop();
Node* receiver = environment()->Pop();
Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName();
value = BuildNamedSuperLoad(receiver, home_object, name, pair);
- states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
+ PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
break;
}
case KEYED_SUPER_PROPERTY: {
VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var());
VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object());
VisitForValue(expr->key());
- FrameStateBeforeAndAfter states(this, expr->key()->id());
+ PrepareEagerCheckpoint(expr->key()->id());
Node* key = environment()->Pop();
Node* home_object = environment()->Pop();
Node* receiver = environment()->Pop();
value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
- states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
+ PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
break;
}
}
@@ -2334,10 +2354,9 @@
case Call::GLOBAL_CALL: {
VariableProxy* proxy = callee->AsVariableProxy();
VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
- FrameStateBeforeAndAfter states(this, BeforeId(proxy));
- callee_value =
- BuildVariableLoad(proxy->var(), expr->expression()->id(), states,
- pair, OutputFrameStateCombine::Push());
+ PrepareEagerCheckpoint(BeforeId(proxy));
+ callee_value = BuildVariableLoad(proxy->var(), expr->expression()->id(),
+ pair, OutputFrameStateCombine::Push());
receiver_hint = ConvertReceiverMode::kNullOrUndefined;
receiver_value = jsgraph()->UndefinedConstant();
break;
@@ -2360,12 +2379,12 @@
VectorSlotPair feedback =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
VisitForValue(property->obj());
- FrameStateBeforeAndAfter states(this, property->obj()->id());
+ PrepareEagerCheckpoint(property->obj()->id());
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
Node* object = environment()->Top();
callee_value = BuildNamedLoad(object, name, feedback);
- states.AddToNode(callee_value, property->LoadId(),
- OutputFrameStateCombine::Push());
+ PrepareFrameState(callee_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
// Note that a property call requires the receiver to be wrapped into
// an object for sloppy callees. However the receiver is guaranteed
// not to be null or undefined at this point.
@@ -2379,12 +2398,12 @@
CreateVectorSlotPair(property->PropertyFeedbackSlot());
VisitForValue(property->obj());
VisitForValue(property->key());
- FrameStateBeforeAndAfter states(this, property->key()->id());
+ PrepareEagerCheckpoint(property->key()->id());
Node* key = environment()->Pop();
Node* object = environment()->Top();
callee_value = BuildKeyedLoad(object, key, feedback);
- states.AddToNode(callee_value, property->LoadId(),
- OutputFrameStateCombine::Push());
+ PrepareFrameState(callee_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
// Note that a property call requires the receiver to be wrapped into
// an object for sloppy callees. However the receiver is guaranteed
// not to be null or undefined at this point.
@@ -2401,10 +2420,10 @@
Node* home = environment()->Peek(1);
Node* object = environment()->Top();
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
- FrameStateBeforeAndAfter states(this, property->obj()->id());
+ PrepareEagerCheckpoint(property->obj()->id());
callee_value = BuildNamedSuperLoad(object, home, name, VectorSlotPair());
- states.AddToNode(callee_value, property->LoadId(),
- OutputFrameStateCombine::Push());
+ PrepareFrameState(callee_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
// Note that a property call requires the receiver to be wrapped into
// an object for sloppy callees. Since the receiver is not the target of
// the load, it could very well be null or undefined at this point.
@@ -2424,10 +2443,10 @@
Node* key = environment()->Pop();
Node* home = environment()->Pop();
Node* object = environment()->Pop();
- FrameStateBeforeAndAfter states(this, property->key()->id());
+ PrepareEagerCheckpoint(property->key()->id());
callee_value = BuildKeyedSuperLoad(object, home, key, VectorSlotPair());
- states.AddToNode(callee_value, property->LoadId(),
- OutputFrameStateCombine::Push());
+ PrepareFrameState(callee_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
// Note that a property call requires the receiver to be wrapped into
// an object for sloppy callees. Since the receiver is not the target of
// the load, it could very well be null or undefined at this point.
@@ -2500,10 +2519,10 @@
VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot());
const Operator* call = javascript()->CallFunction(
args->length() + 2, feedback, receiver_hint, expr->tail_call_mode());
- FrameStateBeforeAndAfter states(this, expr->CallId());
+ PrepareEagerCheckpoint(expr->CallId());
Node* value = ProcessArguments(call, args->length() + 2);
environment()->Push(value->InputAt(0)); // The callee passed to the call.
- states.AddToNode(value, expr->ReturnId(), OutputFrameStateCombine::Push());
+ PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push());
environment()->Drop(1);
ast_context()->ProduceValue(value);
}
@@ -2531,9 +2550,9 @@
// Create node to perform the super call.
const Operator* call =
javascript()->CallConstruct(args->length() + 2, VectorSlotPair());
- FrameStateBeforeAndAfter states(this, super->new_target_var()->id());
+ PrepareEagerCheckpoint(super->new_target_var()->id());
Node* value = ProcessArguments(call, args->length() + 2);
- states.AddToNode(value, expr->ReturnId(), OutputFrameStateCombine::Push());
+ PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push());
ast_context()->ProduceValue(value);
}
@@ -2547,8 +2566,8 @@
// The baseline compiler doesn't push the new.target, so we need to record
// the frame state before the push.
- FrameStateBeforeAndAfter states(
- this, args->is_empty() ? expr->expression()->id() : args->last()->id());
+ PrepareEagerCheckpoint(args->is_empty() ? expr->expression()->id()
+ : args->last()->id());
// The new target is the same as the callee.
environment()->Push(environment()->Peek(args->length()));
@@ -2558,7 +2577,7 @@
const Operator* call =
javascript()->CallConstruct(args->length() + 2, feedback);
Node* value = ProcessArguments(call, args->length() + 2);
- states.AddToNode(value, expr->ReturnId(), OutputFrameStateCombine::Push());
+ PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push());
ast_context()->ProduceValue(value);
}
@@ -2578,9 +2597,9 @@
// Create node to perform the JS runtime call.
const Operator* call = javascript()->CallFunction(args->length() + 2);
- FrameStateBeforeAndAfter states(this, expr->CallId());
+ PrepareEagerCheckpoint(expr->CallId());
Node* value = ProcessArguments(call, args->length() + 2);
- states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
+ PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
ast_context()->ProduceValue(value);
}
@@ -2599,9 +2618,9 @@
// Create node to perform the runtime call.
Runtime::FunctionId functionId = expr->function()->function_id;
const Operator* call = javascript()->CallRuntime(functionId, args->length());
- FrameStateBeforeAndAfter states(this, expr->CallId());
+ PrepareEagerCheckpoint(expr->CallId());
Node* value = ProcessArguments(call, args->length());
- states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
+ PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
ast_context()->ProduceValue(value);
}
@@ -2642,52 +2661,51 @@
case VARIABLE: {
VariableProxy* proxy = expr->expression()->AsVariableProxy();
VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
- FrameStateBeforeAndAfter states(this, BeforeId(proxy));
- old_value =
- BuildVariableLoad(proxy->var(), expr->expression()->id(), states,
- pair, OutputFrameStateCombine::Push());
+ PrepareEagerCheckpoint(BeforeId(proxy));
+ old_value = BuildVariableLoad(proxy->var(), expr->expression()->id(),
+ pair, OutputFrameStateCombine::Push());
stack_depth = 0;
break;
}
case NAMED_PROPERTY: {
VisitForValue(property->obj());
- FrameStateBeforeAndAfter states(this, property->obj()->id());
+ PrepareEagerCheckpoint(property->obj()->id());
Node* object = environment()->Top();
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
old_value = BuildNamedLoad(object, name, pair);
- states.AddToNode(old_value, property->LoadId(),
- OutputFrameStateCombine::Push());
+ PrepareFrameState(old_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
stack_depth = 1;
break;
}
case KEYED_PROPERTY: {
VisitForValue(property->obj());
VisitForValue(property->key());
- FrameStateBeforeAndAfter states(this, property->key()->id());
+ PrepareEagerCheckpoint(property->key()->id());
Node* key = environment()->Top();
Node* object = environment()->Peek(1);
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
old_value = BuildKeyedLoad(object, key, pair);
- states.AddToNode(old_value, property->LoadId(),
- OutputFrameStateCombine::Push());
+ PrepareFrameState(old_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
stack_depth = 2;
break;
}
case NAMED_SUPER_PROPERTY: {
VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
- FrameStateBeforeAndAfter states(this, property->obj()->id());
+ PrepareEagerCheckpoint(property->obj()->id());
Node* home_object = environment()->Top();
Node* receiver = environment()->Peek(1);
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
old_value = BuildNamedSuperLoad(receiver, home_object, name, pair);
- states.AddToNode(old_value, property->LoadId(),
- OutputFrameStateCombine::Push());
+ PrepareFrameState(old_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
stack_depth = 2;
break;
}
@@ -2695,15 +2713,15 @@
VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
VisitForValue(property->key());
- FrameStateBeforeAndAfter states(this, property->obj()->id());
+ PrepareEagerCheckpoint(property->obj()->id());
Node* key = environment()->Top();
Node* home_object = environment()->Peek(1);
Node* receiver = environment()->Peek(2);
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
- states.AddToNode(old_value, property->LoadId(),
- OutputFrameStateCombine::Push());
+ PrepareFrameState(old_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
stack_depth = 3;
break;
}
@@ -2716,7 +2734,7 @@
// Create a proper eager frame state for the stores.
environment()->Push(old_value);
- FrameStateBeforeAndAfter store_states(this, expr->ToNumberId());
+ FrameStateBeforeAndAfter binop_states(this, expr->ToNumberId());
old_value = environment()->Pop();
// Save result for postfix expressions at correct stack depth.
@@ -2729,16 +2747,12 @@
}
// Create node to perform +1/-1 operation.
- Node* value;
- {
- // TODO(bmeurer): Cleanup this feedback/bailout mess!
- FrameStateBeforeAndAfter states(this, BailoutId::None());
- value = BuildBinaryOp(old_value, jsgraph()->OneConstant(),
- expr->binary_op(), expr->CountBinOpFeedbackId());
- // This should never deoptimize because we have converted to number before.
- states.AddToNode(value, BailoutId::None(),
- OutputFrameStateCombine::Ignore());
- }
+ // TODO(bmeurer): Cleanup this feedback/bailout mess!
+ Node* value = BuildBinaryOp(old_value, jsgraph()->OneConstant(),
+ expr->binary_op(), expr->CountBinOpFeedbackId());
+ // This should never deoptimize because we have converted to number before.
+ binop_states.AddToNode(value, BailoutId::None(),
+ OutputFrameStateCombine::Ignore());
// Store the value.
VectorSlotPair feedback = CreateVectorSlotPair(expr->CountSlot());
@@ -2747,7 +2761,7 @@
Variable* variable = expr->expression()->AsVariableProxy()->var();
environment()->Push(value);
BuildVariableAssignment(variable, value, expr->op(), feedback,
- expr->AssignmentId(), store_states);
+ expr->AssignmentId());
environment()->Pop();
break;
}
@@ -2756,8 +2770,8 @@
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
Node* store = BuildNamedStore(object, name, value, feedback);
environment()->Push(value);
- store_states.AddToNode(store, expr->AssignmentId(),
- OutputFrameStateCombine::Ignore());
+ PrepareFrameState(store, expr->AssignmentId(),
+ OutputFrameStateCombine::Ignore());
environment()->Pop();
break;
}
@@ -2766,8 +2780,8 @@
Node* object = environment()->Pop();
Node* store = BuildKeyedStore(object, key, value, feedback);
environment()->Push(value);
- store_states.AddToNode(store, expr->AssignmentId(),
- OutputFrameStateCombine::Ignore());
+ PrepareFrameState(store, expr->AssignmentId(),
+ OutputFrameStateCombine::Ignore());
environment()->Pop();
break;
}
@@ -2777,8 +2791,8 @@
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
Node* store = BuildNamedSuperStore(receiver, home_object, name, value);
environment()->Push(value);
- store_states.AddToNode(store, expr->AssignmentId(),
- OutputFrameStateCombine::Ignore());
+ PrepareFrameState(store, expr->AssignmentId(),
+ OutputFrameStateCombine::Ignore());
environment()->Pop();
break;
}
@@ -2788,8 +2802,8 @@
Node* receiver = environment()->Pop();
Node* store = BuildKeyedSuperStore(receiver, home_object, key, value);
environment()->Push(value);
- store_states.AddToNode(store, expr->AssignmentId(),
- OutputFrameStateCombine::Ignore());
+ PrepareFrameState(store, expr->AssignmentId(),
+ OutputFrameStateCombine::Ignore());
environment()->Pop();
break;
}
@@ -2829,19 +2843,19 @@
const Operator* op = nullptr;
switch (expr->op()) {
case Token::EQ:
- op = javascript()->Equal();
+ op = javascript()->Equal(CompareOperationHints::Any());
break;
case Token::EQ_STRICT:
- op = javascript()->StrictEqual();
+ op = javascript()->StrictEqual(CompareOperationHints::Any());
break;
default:
UNREACHABLE();
}
VisitForValue(sub_expr);
- FrameStateBeforeAndAfter states(this, sub_expr->id());
+ PrepareEagerCheckpoint(sub_expr->id());
Node* value_to_compare = environment()->Pop();
Node* value = NewNode(op, value_to_compare, nil_value);
- states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
+ PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
return ast_context()->ProduceValue(value);
}
@@ -2849,11 +2863,11 @@
Expression* sub_expr,
Handle<String> check) {
VisitTypeofExpression(sub_expr);
- FrameStateBeforeAndAfter states(this, sub_expr->id());
+ PrepareEagerCheckpoint(sub_expr->id());
Node* typeof_arg = NewNode(javascript()->TypeOf(), environment()->Pop());
- Node* value = NewNode(javascript()->StrictEqual(), typeof_arg,
- jsgraph()->Constant(check));
- states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
+ Node* value = NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
+ typeof_arg, jsgraph()->Constant(check));
+ PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
return ast_context()->ProduceValue(value);
}
@@ -2874,31 +2888,38 @@
return VisitLiteralCompareNil(expr, sub_expr, jsgraph()->NullConstant());
}
+ CompareOperationHints hints;
+ if (!type_hint_analysis_ ||
+ !type_hint_analysis_->GetCompareOperationHints(
+ expr->CompareOperationFeedbackId(), &hints)) {
+ hints = CompareOperationHints::Any();
+ }
+
const Operator* op;
switch (expr->op()) {
case Token::EQ:
- op = javascript()->Equal();
+ op = javascript()->Equal(hints);
break;
case Token::NE:
- op = javascript()->NotEqual();
+ op = javascript()->NotEqual(hints);
break;
case Token::EQ_STRICT:
- op = javascript()->StrictEqual();
+ op = javascript()->StrictEqual(hints);
break;
case Token::NE_STRICT:
- op = javascript()->StrictNotEqual();
+ op = javascript()->StrictNotEqual(hints);
break;
case Token::LT:
- op = javascript()->LessThan();
+ op = javascript()->LessThan(hints);
break;
case Token::GT:
- op = javascript()->GreaterThan();
+ op = javascript()->GreaterThan(hints);
break;
case Token::LTE:
- op = javascript()->LessThanOrEqual();
+ op = javascript()->LessThanOrEqual(hints);
break;
case Token::GTE:
- op = javascript()->GreaterThanOrEqual();
+ op = javascript()->GreaterThanOrEqual(hints);
break;
case Token::INSTANCEOF:
op = javascript()->InstanceOf();
@@ -3039,9 +3060,9 @@
// perform a non-contextual load in case the operand is a variable proxy.
VariableProxy* proxy = expr->AsVariableProxy();
VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
- FrameStateBeforeAndAfter states(this, BeforeId(proxy));
+ PrepareEagerCheckpoint(BeforeId(proxy));
Node* load =
- BuildVariableLoad(proxy->var(), expr->id(), states, pair,
+ BuildVariableLoad(proxy->var(), expr->id(), pair,
OutputFrameStateCombine::Push(), INSIDE_TYPEOF);
environment()->Push(load);
} else {
@@ -3109,7 +3130,7 @@
VectorSlotPair AstGraphBuilder::CreateVectorSlotPair(
FeedbackVectorSlot slot) const {
- return VectorSlotPair(handle(info()->shared_info()->feedback_vector()), slot);
+ return VectorSlotPair(handle(info()->closure()->feedback_vector()), slot);
}
@@ -3260,9 +3281,8 @@
// Assign the object to the {arguments} variable. This should never lazy
// deopt, so it is fine to send invalid bailout id.
DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated());
- FrameStateBeforeAndAfter states(this, BailoutId::None());
BuildVariableAssignment(arguments, object, Token::ASSIGN, VectorSlotPair(),
- BailoutId::None(), states);
+ BailoutId::None());
return object;
}
@@ -3279,9 +3299,8 @@
// Assign the object to the {rest} variable. This should never lazy
// deopt, so it is fine to send invalid bailout id.
DCHECK(rest->IsContextSlot() || rest->IsStackAllocated());
- FrameStateBeforeAndAfter states(this, BailoutId::None());
BuildVariableAssignment(rest, object, Token::ASSIGN, VectorSlotPair(),
- BailoutId::None(), states);
+ BailoutId::None());
return object;
}
@@ -3294,9 +3313,8 @@
// Assign the object to the {.this_function} variable. This should never lazy
// deopt, so it is fine to send invalid bailout id.
- FrameStateBeforeAndAfter states(this, BailoutId::None());
BuildVariableAssignment(this_function_var, this_function, Token::INIT,
- VectorSlotPair(), BailoutId::None(), states);
+ VectorSlotPair(), BailoutId::None());
return this_function;
}
@@ -3309,9 +3327,8 @@
// Assign the object to the {new.target} variable. This should never lazy
// deopt, so it is fine to send invalid bailout id.
- FrameStateBeforeAndAfter states(this, BailoutId::None());
BuildVariableAssignment(new_target_var, object, Token::INIT, VectorSlotPair(),
- BailoutId::None(), states);
+ BailoutId::None());
return object;
}
@@ -3321,7 +3338,8 @@
BailoutId bailout_id) {
IfBuilder hole_check(this);
Node* the_hole = jsgraph()->TheHoleConstant();
- Node* check = NewNode(javascript()->StrictEqual(), value, the_hole);
+ Node* check = NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
+ value, the_hole);
hole_check.If(check);
hole_check.Then();
Node* error = BuildThrowReferenceError(variable, bailout_id);
@@ -3338,7 +3356,8 @@
BailoutId bailout_id) {
IfBuilder hole_check(this);
Node* the_hole = jsgraph()->TheHoleConstant();
- Node* check = NewNode(javascript()->StrictEqual(), value, the_hole);
+ Node* check = NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
+ value, the_hole);
hole_check.If(check);
hole_check.Then();
environment()->Push(for_hole);
@@ -3355,7 +3374,8 @@
IfBuilder prototype_check(this);
Node* prototype_string =
jsgraph()->Constant(isolate()->factory()->prototype_string());
- Node* check = NewNode(javascript()->StrictEqual(), name, prototype_string);
+ Node* check = NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
+ name, prototype_string);
prototype_check.If(check);
prototype_check.Then();
Node* error = BuildThrowStaticPrototypeError(bailout_id);
@@ -3369,7 +3389,6 @@
Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
BailoutId bailout_id,
- FrameStateBeforeAndAfter& states,
const VectorSlotPair& feedback,
OutputFrameStateCombine combine,
TypeofMode typeof_mode) {
@@ -3382,7 +3401,7 @@
Handle<Name> name = variable->name();
if (Node* node = TryLoadGlobalConstant(name)) return node;
Node* value = BuildGlobalLoad(name, feedback, typeof_mode);
- states.AddToNode(value, bailout_id, combine);
+ PrepareFrameState(value, bailout_id, combine);
return value;
}
case VariableLocation::PARAMETER:
@@ -3418,13 +3437,12 @@
case VariableLocation::LOOKUP: {
// Dynamic lookup of context variable (anywhere in the chain).
Handle<String> name = variable->name();
- if (Node* node =
- TryLoadDynamicVariable(variable, name, bailout_id, states,
- feedback, combine, typeof_mode)) {
+ if (Node* node = TryLoadDynamicVariable(variable, name, bailout_id,
+ feedback, combine, typeof_mode)) {
return node;
}
Node* value = BuildDynamicLoad(name, typeof_mode);
- states.AddToNode(value, bailout_id, combine);
+ PrepareFrameState(value, bailout_id, combine);
return value;
}
}
@@ -3467,11 +3485,10 @@
return nullptr;
}
-
Node* AstGraphBuilder::BuildVariableAssignment(
Variable* variable, Node* value, Token::Value op,
const VectorSlotPair& feedback, BailoutId bailout_id,
- FrameStateBeforeAndAfter& states, OutputFrameStateCombine combine) {
+ OutputFrameStateCombine combine) {
Node* the_hole = jsgraph()->TheHoleConstant();
VariableMode mode = variable->mode();
switch (variable->location()) {
@@ -3480,7 +3497,7 @@
// Global var, const, or let variable.
Handle<Name> name = variable->name();
Node* store = BuildGlobalStore(name, value, feedback);
- states.AddToNode(store, bailout_id, combine);
+ PrepareFrameState(store, bailout_id, combine);
return store;
}
case VariableLocation::PARAMETER:
@@ -3740,11 +3757,11 @@
Expression* expr = property->value();
if (!FunctionLiteral::NeedsHomeObject(expr)) return value;
Handle<Name> name = isolate()->factory()->home_object_symbol();
- FrameStateBeforeAndAfter states(this, BailoutId::None());
VectorSlotPair feedback =
CreateVectorSlotPair(property->GetSlot(slot_number));
Node* store = BuildNamedStore(value, name, home_object, feedback);
- states.AddToNode(store, BailoutId::None(), OutputFrameStateCombine::Ignore());
+ PrepareFrameState(store, BailoutId::None(),
+ OutputFrameStateCombine::Ignore());
return store;
}
@@ -3881,11 +3898,12 @@
return nullptr;
}
-
-Node* AstGraphBuilder::TryLoadDynamicVariable(
- Variable* variable, Handle<String> name, BailoutId bailout_id,
- FrameStateBeforeAndAfter& states, const VectorSlotPair& feedback,
- OutputFrameStateCombine combine, TypeofMode typeof_mode) {
+Node* AstGraphBuilder::TryLoadDynamicVariable(Variable* variable,
+ Handle<String> name,
+ BailoutId bailout_id,
+ const VectorSlotPair& feedback,
+ OutputFrameStateCombine combine,
+ TypeofMode typeof_mode) {
VariableMode mode = variable->mode();
if (mode == DYNAMIC_GLOBAL) {
@@ -3907,8 +3925,9 @@
Node* load = NewNode(
javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false),
current_context());
- Node* check = NewNode(javascript()->StrictEqual(), load,
- jsgraph()->TheHoleConstant());
+ Node* check =
+ NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), load,
+ jsgraph()->TheHoleConstant());
fast_block.BreakUnless(check, BranchHint::kTrue);
}
@@ -3918,7 +3937,7 @@
} else {
// Perform global slot load.
Node* fast = BuildGlobalLoad(name, feedback, typeof_mode);
- states.AddToNode(fast, bailout_id, combine);
+ PrepareFrameState(fast, bailout_id, combine);
environment()->Push(fast);
}
slow_block.Break();
@@ -3927,7 +3946,7 @@
// Slow case, because variable potentially shadowed. Perform dynamic lookup.
Node* slow = BuildDynamicLoad(name, typeof_mode);
- states.AddToNode(slow, bailout_id, combine);
+ PrepareFrameState(slow, bailout_id, combine);
environment()->Push(slow);
slow_block.EndBlock();
@@ -3953,16 +3972,17 @@
Node* load = NewNode(
javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false),
current_context());
- Node* check = NewNode(javascript()->StrictEqual(), load,
- jsgraph()->TheHoleConstant());
+ Node* check =
+ NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), load,
+ jsgraph()->TheHoleConstant());
fast_block.BreakUnless(check, BranchHint::kTrue);
}
// Fast case, because variable is not shadowed. Perform context slot load.
Variable* local = variable->local_if_not_shadowed();
DCHECK(local->location() == VariableLocation::CONTEXT); // Must be context.
- Node* fast = BuildVariableLoad(local, bailout_id, states, feedback, combine,
- typeof_mode);
+ Node* fast =
+ BuildVariableLoad(local, bailout_id, feedback, combine, typeof_mode);
environment()->Push(fast);
slow_block.Break();
environment()->Pop();
@@ -3970,7 +3990,7 @@
// Slow case, because variable potentially shadowed. Perform dynamic lookup.
Node* slow = BuildDynamicLoad(name, typeof_mode);
- states.AddToNode(slow, bailout_id, combine);
+ PrepareFrameState(slow, bailout_id, combine);
environment()->Push(slow);
slow_block.EndBlock();
@@ -4053,6 +4073,20 @@
}
}
+void AstGraphBuilder::PrepareEagerCheckpoint(BailoutId ast_id) {
+ if (environment()->GetEffectDependency()->opcode() == IrOpcode::kCheckpoint) {
+ // We skip preparing a checkpoint if there already is one the current effect
+ // dependency. This is just an optimization and not need for correctness.
+ return;
+ }
+ if (ast_id != BailoutId::None()) {
+ Node* node = NewNode(common()->Checkpoint());
+ DCHECK_EQ(IrOpcode::kDead,
+ NodeProperties::GetFrameStateInput(node, 0)->opcode());
+ NodeProperties::ReplaceFrameStateInput(node, 0,
+ environment()->Checkpoint(ast_id));
+ }
+}
BitVector* AstGraphBuilder::GetVariablesAssignedInLoop(
IterationStatement* stmt) {
@@ -4298,7 +4332,6 @@
}
-// TODO(mstarzinger): Revisit this once we have proper effect states.
Node* AstGraphBuilder::NewEffectPhi(int count, Node* input, Node* control) {
const Operator* phi_op = common()->EffectPhi(count);
Node** buffer = EnsureInputBufferSize(count + 1);