Revert "Upgrade to 5.0.71.48"
This reverts commit 8389745919cae02139ddc085a63c00d024269cf2.
Change-Id: Ic5c75c8b3ddaf795972372fbc863a514862953c1
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc
index abcf828..c70dfbf 100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -206,6 +206,7 @@
int stack_height_;
};
+
// Helper class for a try-finally control scope. It can record intercepted
// control-flow commands that cause entry into a finally-block, and re-apply
// them after again leaving that block. Special tokens are used to identify
@@ -213,10 +214,7 @@
class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject {
public:
explicit DeferredCommands(AstGraphBuilder* owner)
- : owner_(owner),
- deferred_(owner->local_zone()),
- return_token_(nullptr),
- throw_token_(nullptr) {}
+ : owner_(owner), deferred_(owner->local_zone()) {}
// One recorded control-flow command.
struct Entry {
@@ -228,24 +226,7 @@
// Records a control-flow command while entering the finally-block. This also
// generates a new dispatch token that identifies one particular path.
Node* RecordCommand(Command cmd, Statement* stmt, Node* value) {
- Node* token = nullptr;
- switch (cmd) {
- case CMD_BREAK:
- case CMD_CONTINUE:
- token = NewPathToken(dispenser_.GetBreakContinueToken());
- break;
- case CMD_THROW:
- if (throw_token_) return throw_token_;
- token = NewPathToken(TokenDispenserForFinally::kThrowToken);
- throw_token_ = token;
- break;
- case CMD_RETURN:
- if (return_token_) return return_token_;
- token = NewPathToken(TokenDispenserForFinally::kReturnToken);
- return_token_ = token;
- break;
- }
- DCHECK_NOT_NULL(token);
+ Node* token = NewPathTokenForDeferredCommand();
deferred_.push_back({cmd, stmt, token});
return token;
}
@@ -274,11 +255,11 @@
}
protected:
- Node* NewPathToken(int token_id) {
- return owner_->jsgraph()->Constant(token_id);
+ Node* NewPathTokenForDeferredCommand() {
+ return owner_->jsgraph()->Constant(static_cast<int>(deferred_.size()));
}
Node* NewPathTokenForImplicitFallThrough() {
- return NewPathToken(TokenDispenserForFinally::kFallThroughToken);
+ return owner_->jsgraph()->Constant(-1);
}
Node* NewPathDispatchCondition(Node* t1, Node* t2) {
// TODO(mstarzinger): This should be machine()->WordEqual(), but our Phi
@@ -287,11 +268,8 @@
}
private:
- TokenDispenserForFinally dispenser_;
AstGraphBuilder* owner_;
ZoneVector<Entry> deferred_;
- Node* return_token_;
- Node* throw_token_;
};
@@ -431,13 +409,10 @@
DCHECK_EQ(IrOpcode::kDead,
NodeProperties::GetFrameStateInput(node, 0)->opcode());
- bool node_has_exception = NodeProperties::IsExceptionalCall(node);
-
Node* frame_state_after =
id_after == BailoutId::None()
? builder_->jsgraph()->EmptyFrameState()
- : builder_->environment()->Checkpoint(id_after, combine,
- node_has_exception);
+ : builder_->environment()->Checkpoint(id_after, combine);
NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after);
}
@@ -480,7 +455,8 @@
local_zone),
frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
FrameStateType::kJavaScriptFunction, info->num_parameters() + 1,
- info->scope()->num_stack_slots(), info->shared_info())) {
+ info->scope()->num_stack_slots(), info->shared_info(),
+ CALL_MAINTAINS_NATIVE_CONTEXT)) {
InitializeAstVisitor(info->isolate());
}
@@ -613,7 +589,7 @@
// Emit tracing call if requested to do so.
if (FLAG_trace) {
- NewNode(javascript()->CallRuntime(Runtime::kTraceEnter));
+ NewNode(javascript()->CallRuntime(Runtime::kTraceEnter, 0));
}
// Visit illegal re-declaration and bail out if it exists.
@@ -634,6 +610,13 @@
// Visit statements in the function body.
VisitStatements(info()->literal()->body());
+ // Emit tracing call if requested to do so.
+ if (FLAG_trace) {
+ // TODO(mstarzinger): Only traces implicit return.
+ Node* return_value = jsgraph()->UndefinedConstant();
+ NewNode(javascript()->CallRuntime(Runtime::kTraceExit, 1), return_value);
+ }
+
// Return 'undefined' in case we can fall off the end.
BuildReturn(jsgraph()->UndefinedConstant());
}
@@ -871,9 +854,9 @@
env_values, static_cast<size_t>(count));
}
-Node* AstGraphBuilder::Environment::Checkpoint(BailoutId ast_id,
- OutputFrameStateCombine combine,
- bool owner_has_exception) {
+
+Node* AstGraphBuilder::Environment::Checkpoint(
+ BailoutId ast_id, OutputFrameStateCombine combine) {
if (!builder()->info()->is_deoptimization_enabled()) {
return builder()->jsgraph()->EmptyFrameState();
}
@@ -893,15 +876,7 @@
DCHECK(IsLivenessBlockConsistent());
if (liveness_block() != nullptr) {
- // If the owning node has an exception, register the checkpoint to the
- // predecessor so that the checkpoint is used for both the normal and the
- // exceptional paths. Yes, this is a terrible hack and we might want
- // to use an explicit frame state for the exceptional path.
- if (owner_has_exception) {
- liveness_block()->GetPredecessor()->Checkpoint(result);
- } else {
- liveness_block()->Checkpoint(result);
- }
+ liveness_block()->Checkpoint(result);
}
return result;
}
@@ -1356,8 +1331,7 @@
// Prepare for-in cache.
Node* prepare = NewNode(javascript()->ForInPrepare(), object);
- PrepareFrameState(prepare, stmt->PrepareId(),
- OutputFrameStateCombine::Push(3));
+ PrepareFrameState(prepare, stmt->EnumId(), OutputFrameStateCombine::Push());
Node* cache_type = NewNode(common()->Projection(0), prepare);
Node* cache_array = NewNode(common()->Projection(1), prepare);
Node* cache_length = NewNode(common()->Projection(2), prepare);
@@ -1448,6 +1422,14 @@
}
try_control.EndTry();
+ // Insert lazy bailout point.
+ // TODO(mstarzinger): We are only using a 'call' to get a lazy bailout
+ // point. Ideally, we whould not re-enter optimized code when deoptimized
+ // lazily. Tracked by issue v8:4195.
+ NewNode(common()->LazyBailout(),
+ jsgraph()->ZeroConstant(), // dummy target.
+ environment()->Checkpoint(stmt->HandlerId())); // frame state.
+
// Clear message object as we enter the catch block.
Node* the_hole = jsgraph()->TheHoleConstant();
NewNode(javascript()->StoreMessage(), the_hole);
@@ -1492,6 +1474,14 @@
}
try_control.EndTry(commands->GetFallThroughToken(), fallthrough_result);
+ // Insert lazy bailout point.
+ // TODO(mstarzinger): We are only using a 'call' to get a lazy bailout
+ // point. Ideally, we whould not re-enter optimized code when deoptimized
+ // lazily. Tracked by issue v8:4195.
+ NewNode(common()->LazyBailout(),
+ jsgraph()->ZeroConstant(), // dummy target.
+ environment()->Checkpoint(stmt->HandlerId())); // frame state.
+
// The result value semantics depend on how the block was entered:
// - ReturnStatement: It represents the return value being returned.
// - ThrowStatement: It represents the exception being thrown.
@@ -1503,7 +1493,7 @@
// The result value, dispatch token and message is expected on the operand
// stack (this is in sync with FullCodeGenerator::EnterFinallyBlock).
Node* message = NewNode(javascript()->LoadMessage());
- environment()->Push(token);
+ environment()->Push(token); // TODO(mstarzinger): Cook token!
environment()->Push(result);
environment()->Push(message);
@@ -1519,17 +1509,20 @@
// stack (this is in sync with FullCodeGenerator::ExitFinallyBlock).
message = environment()->Pop();
result = environment()->Pop();
- token = environment()->Pop();
+ token = environment()->Pop(); // TODO(mstarzinger): Uncook token!
NewNode(javascript()->StoreMessage(), message);
// Dynamic dispatch after the finally-block.
commands->ApplyDeferredCommands(token, result);
+
+ // TODO(mstarzinger): Remove bailout once everything works.
+ if (!FLAG_turbo_try_finally) SetStackOverflow();
}
void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
Node* node =
- NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement));
+ NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement, 0));
PrepareFrameState(node, stmt->DebugBreakId());
environment()->MarkAllLocalsLive();
}
@@ -1564,27 +1557,33 @@
void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
+ Node* class_name = expr->raw_name() ? jsgraph()->Constant(expr->name())
+ : jsgraph()->UndefinedConstant();
+
+ // The class name is expected on the operand stack.
+ environment()->Push(class_name);
VisitForValueOrTheHole(expr->extends());
VisitForValue(expr->constructor());
// Create node to instantiate a new class.
Node* constructor = environment()->Pop();
Node* extends = environment()->Pop();
+ Node* name = environment()->Pop();
Node* start = jsgraph()->Constant(expr->start_position());
Node* end = jsgraph()->Constant(expr->end_position());
- const Operator* opc = javascript()->CallRuntime(Runtime::kDefineClass);
- Node* literal = NewNode(opc, extends, constructor, start, end);
+ const Operator* opc = javascript()->CallRuntime(Runtime::kDefineClass, 5);
+ Node* literal = NewNode(opc, name, extends, constructor, start, end);
PrepareFrameState(literal, expr->CreateLiteralId(),
OutputFrameStateCombine::Push());
- environment()->Push(literal);
- // Load the "prototype" from the constructor.
- FrameStateBeforeAndAfter states(this, 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());
+ // The prototype is ensured to exist by Runtime_DefineClass. No access check
+ // is needed here since the constructor is created by the class literal.
+ Node* prototype =
+ BuildLoadObjectField(literal, JSFunction::kPrototypeOrInitialMapOffset);
+
+ // The class literal and the prototype are both expected on the operand stack
+ // during evaluation of the method values.
+ environment()->Push(literal);
environment()->Push(prototype);
// Create nodes to store method values into the literal.
@@ -1619,12 +1618,9 @@
case ObjectLiteral::Property::PROTOTYPE:
UNREACHABLE();
case ObjectLiteral::Property::COMPUTED: {
- Node* attr = jsgraph()->Constant(DONT_ENUM);
- Node* set_function_name =
- jsgraph()->Constant(property->NeedsSetFunctionName());
const Operator* op =
- javascript()->CallRuntime(Runtime::kDefineDataPropertyInLiteral);
- NewNode(op, receiver, key, value, attr, set_function_name);
+ javascript()->CallRuntime(Runtime::kDefineClassMethod, 3);
+ NewNode(op, receiver, key, value);
break;
}
case ObjectLiteral::Property::GETTER: {
@@ -1649,7 +1645,7 @@
prototype = environment()->Pop();
literal = environment()->Pop();
const Operator* op =
- javascript()->CallRuntime(Runtime::kFinalizeClassDefinition);
+ javascript()->CallRuntime(Runtime::kFinalizeClassDefinition, 2);
literal = NewNode(op, literal, prototype);
// Assign to class variable.
@@ -1778,7 +1774,8 @@
Node* receiver = environment()->Pop();
if (property->emit_store()) {
Node* language = jsgraph()->Constant(SLOPPY);
- const Operator* op = javascript()->CallRuntime(Runtime::kSetProperty);
+ const Operator* op =
+ javascript()->CallRuntime(Runtime::kSetProperty, 4);
Node* set_property = NewNode(op, receiver, key, value, language);
// SetProperty should not lazy deopt on an object literal.
PrepareFrameState(set_property, BailoutId::None());
@@ -1793,7 +1790,7 @@
Node* receiver = environment()->Pop();
DCHECK(property->emit_store());
const Operator* op =
- javascript()->CallRuntime(Runtime::kInternalSetPrototype);
+ javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
Node* set_prototype = NewNode(op, receiver, value);
// SetPrototype should not lazy deopt on an object literal.
PrepareFrameState(set_prototype,
@@ -1826,7 +1823,7 @@
Node* name = environment()->Pop();
Node* attr = jsgraph()->Constant(NONE);
const Operator* op =
- javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked);
+ javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
Node* call = NewNode(op, literal, name, getter, setter, attr);
// This should not lazy deopt on a new literal.
PrepareFrameState(call, BailoutId::None());
@@ -1850,7 +1847,7 @@
Node* value = environment()->Pop();
Node* receiver = environment()->Pop();
const Operator* op =
- javascript()->CallRuntime(Runtime::kInternalSetPrototype);
+ javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
Node* call = NewNode(op, receiver, value);
PrepareFrameState(call, expr->GetIdForPropertySet(property_index));
continue;
@@ -1871,11 +1868,10 @@
case ObjectLiteral::Property::COMPUTED:
case ObjectLiteral::Property::MATERIALIZED_LITERAL: {
Node* attr = jsgraph()->Constant(NONE);
- Node* set_function_name =
- jsgraph()->Constant(property->NeedsSetFunctionName());
const Operator* op =
- javascript()->CallRuntime(Runtime::kDefineDataPropertyInLiteral);
- NewNode(op, receiver, key, value, attr, set_function_name);
+ javascript()->CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
+ Node* call = NewNode(op, receiver, key, value, attr);
+ PrepareFrameState(call, BailoutId::None());
break;
}
case ObjectLiteral::Property::PROTOTYPE:
@@ -1903,7 +1899,8 @@
// Transform literals that contain functions to fast properties.
literal = environment()->Top(); // Reload from operand stack.
if (expr->has_function()) {
- const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties);
+ const Operator* op =
+ javascript()->CallRuntime(Runtime::kToFastProperties, 1);
NewNode(op, literal);
}
@@ -1942,7 +1939,7 @@
int array_index = 0;
for (; array_index < expr->values()->length(); array_index++) {
Expression* subexpr = expr->values()->at(array_index);
- DCHECK(!subexpr->IsSpread());
+ if (subexpr->IsSpread()) break;
if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
VisitForValue(subexpr);
@@ -1965,17 +1962,30 @@
// number elements an iterable produces is unknown ahead of time.
for (; array_index < expr->values()->length(); array_index++) {
Expression* subexpr = expr->values()->at(array_index);
- DCHECK(!subexpr->IsSpread());
+ Node* result;
- VisitForValue(subexpr);
- {
+ if (subexpr->IsSpread()) {
+ VisitForValue(subexpr->AsSpread()->expression());
+ FrameStateBeforeAndAfter states(this,
+ subexpr->AsSpread()->expression()->id());
+ Node* iterable = environment()->Pop();
+ Node* array = environment()->Pop();
+ Node* function = BuildLoadNativeContextField(
+ Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX);
+ result = NewNode(javascript()->CallFunction(3, language_mode()), function,
+ array, iterable);
+ states.AddToNode(result, expr->GetIdForElement(array_index));
+ } else {
+ VisitForValue(subexpr);
Node* value = environment()->Pop();
Node* array = environment()->Pop();
- const Operator* op = javascript()->CallRuntime(Runtime::kAppendElement);
- Node* result = NewNode(op, array, value);
+ const Operator* op =
+ javascript()->CallRuntime(Runtime::kAppendElement, 2);
+ result = NewNode(op, array, value);
PrepareFrameState(result, expr->GetIdForElement(array_index));
- environment()->Push(result);
}
+
+ environment()->Push(result);
}
ast_context()->ProduceValue(environment()->Pop());
@@ -2333,8 +2343,8 @@
DCHECK(variable->location() == VariableLocation::LOOKUP);
Node* name = jsgraph()->Constant(variable->name());
const Operator* op =
- javascript()->CallRuntime(Runtime::kLoadLookupSlotForCall);
- Node* pair = NewNode(op, name);
+ javascript()->CallRuntime(Runtime::kLoadLookupSlot, 2);
+ Node* pair = NewNode(op, current_context(), name);
callee_value = NewNode(common()->Projection(0), pair);
receiver_value = NewNode(common()->Projection(1), pair);
PrepareFrameState(pair, expr->LookupId(),
@@ -2429,8 +2439,8 @@
Variable* variable = callee->AsVariableProxy()->var();
Node* name = jsgraph()->Constant(variable->name());
const Operator* op =
- javascript()->CallRuntime(Runtime::kLoadLookupSlotForCall);
- Node* pair = NewNode(op, name);
+ javascript()->CallRuntime(Runtime::kLoadLookupSlot, 2);
+ Node* pair = NewNode(op, current_context(), name);
callee_value = NewNode(common()->Projection(0), pair);
receiver_value = NewNode(common()->Projection(1), pair);
PrepareFrameState(pair, expr->LookupId(),
@@ -2470,7 +2480,7 @@
Node* language = jsgraph()->Constant(language_mode());
Node* position = jsgraph()->Constant(current_scope()->start_position());
const Operator* op =
- javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval);
+ javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
Node* new_callee =
NewNode(op, callee, source, function, language, position);
PrepareFrameState(new_callee, expr->EvalId(),
@@ -2483,7 +2493,7 @@
// Create node to perform the function call.
VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot());
const Operator* call = javascript()->CallFunction(
- args->length() + 2, feedback, receiver_hint, expr->tail_call_mode());
+ args->length() + 2, language_mode(), feedback, receiver_hint);
FrameStateBeforeAndAfter states(this, expr->CallId());
Node* value = ProcessArguments(call, args->length() + 2);
environment()->Push(value->InputAt(0)); // The callee passed to the call.
@@ -2561,7 +2571,8 @@
VisitForValues(args);
// Create node to perform the JS runtime call.
- const Operator* call = javascript()->CallFunction(args->length() + 2);
+ const Operator* call =
+ javascript()->CallFunction(args->length() + 2, language_mode());
FrameStateBeforeAndAfter states(this, expr->CallId());
Node* value = ProcessArguments(call, args->length() + 2);
states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
@@ -2580,7 +2591,6 @@
// TODO(mstarzinger): This bailout is a gigantic hack, the owner is ashamed.
if (function->function_id == Runtime::kInlineGeneratorNext ||
- function->function_id == Runtime::kInlineGeneratorReturn ||
function->function_id == Runtime::kInlineGeneratorThrow) {
ast_context()->ProduceValue(jsgraph()->TheHoleConstant());
return SetStackOverflow();
@@ -2730,7 +2740,7 @@
// TODO(bmeurer): Cleanup this feedback/bailout mess!
FrameStateBeforeAndAfter states(this, BailoutId::None());
value = BuildBinaryOp(old_value, jsgraph()->OneConstant(),
- expr->binary_op(), expr->CountBinOpFeedbackId());
+ expr->binary_op(), TypeFeedbackId::None());
// This should never deoptimize outside strong mode because otherwise we
// have converted to number before.
states.AddToNode(value, is_strong(language_mode()) ? expr->ToNumberId()
@@ -2838,16 +2848,16 @@
op = javascript()->StrictNotEqual();
break;
case Token::LT:
- op = javascript()->LessThan();
+ op = javascript()->LessThan(language_mode());
break;
case Token::GT:
- op = javascript()->GreaterThan();
+ op = javascript()->GreaterThan(language_mode());
break;
case Token::LTE:
- op = javascript()->LessThanOrEqual();
+ op = javascript()->LessThanOrEqual(language_mode());
break;
case Token::GTE:
- op = javascript()->GreaterThanOrEqual();
+ op = javascript()->GreaterThanOrEqual(language_mode());
break;
case Token::INSTANCEOF:
op = javascript()->InstanceOf();
@@ -2920,7 +2930,7 @@
DeclareGlobalsLanguageMode::encode(language_mode());
Node* flags = jsgraph()->Constant(encoded_flags);
Node* pairs = jsgraph()->Constant(data);
- const Operator* op = javascript()->CallRuntime(Runtime::kDeclareGlobals);
+ const Operator* op = javascript()->CallRuntime(Runtime::kDeclareGlobals, 2);
Node* call = NewNode(op, pairs, flags);
PrepareFrameState(call, BailoutId::Declarations());
globals()->clear();
@@ -3062,7 +3072,8 @@
}
-void AstGraphBuilder::VisitRewritableExpression(RewritableExpression* node) {
+void AstGraphBuilder::VisitRewritableAssignmentExpression(
+ RewritableAssignmentExpression* node) {
Visit(node->expression());
}
@@ -3198,11 +3209,11 @@
if (arguments == nullptr) return nullptr;
// Allocate and initialize a new arguments object.
- CreateArgumentsType type =
+ CreateArgumentsParameters::Type type =
is_strict(language_mode()) || !info()->has_simple_parameters()
- ? CreateArgumentsType::kUnmappedArguments
- : CreateArgumentsType::kMappedArguments;
- const Operator* op = javascript()->CreateArguments(type);
+ ? CreateArgumentsParameters::kUnmappedArguments
+ : CreateArgumentsParameters::kMappedArguments;
+ const Operator* op = javascript()->CreateArguments(type, 0);
Node* object = NewNode(op, GetFunctionClosure());
PrepareFrameState(object, BailoutId::None());
@@ -3220,8 +3231,8 @@
if (rest == nullptr) return nullptr;
// Allocate and initialize a new arguments object.
- CreateArgumentsType type = CreateArgumentsType::kRestParameter;
- const Operator* op = javascript()->CreateArguments(type);
+ CreateArgumentsParameters::Type type = CreateArgumentsParameters::kRestArray;
+ const Operator* op = javascript()->CreateArguments(type, index);
Node* object = NewNode(op, GetFunctionClosure());
PrepareFrameState(object, BailoutId::None());
@@ -3394,7 +3405,8 @@
feedback, combine, typeof_mode)) {
return node;
}
- Node* value = BuildDynamicLoad(name, typeof_mode);
+ const Operator* op = javascript()->LoadDynamic(name, typeof_mode);
+ Node* value = NewNode(op, BuildLoadFeedbackVector(), current_context());
states.AddToNode(value, bailout_id, combine);
return value;
}
@@ -3428,8 +3440,8 @@
// Dynamic lookup of context variable (anywhere in the chain).
Node* name = jsgraph()->Constant(variable->name());
const Operator* op =
- javascript()->CallRuntime(Runtime::kDeleteLookupSlot);
- Node* result = NewNode(op, name);
+ javascript()->CallRuntime(Runtime::kDeleteLookupSlot, 2);
+ Node* result = NewNode(op, current_context(), name);
PrepareFrameState(result, bailout_id, combine);
return result;
}
@@ -3551,10 +3563,13 @@
}
case VariableLocation::LOOKUP: {
// Dynamic lookup of context variable (anywhere in the chain).
- Handle<Name> name = variable->name();
+ Node* name = jsgraph()->Constant(variable->name());
+ Node* language = jsgraph()->Constant(language_mode());
// TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for
// initializations of const declarations.
- Node* store = BuildDynamicStore(name, value);
+ const Operator* op =
+ javascript()->CallRuntime(Runtime::kStoreLookupSlot, 4);
+ Node* store = NewNode(op, value, current_context(), name, language);
PrepareFrameState(store, bailout_id, combine);
return store;
}
@@ -3566,16 +3581,16 @@
Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key,
const VectorSlotPair& feedback) {
- const Operator* op = javascript()->LoadProperty(feedback);
- Node* node = NewNode(op, object, key, GetFunctionClosure());
+ const Operator* op = javascript()->LoadProperty(language_mode(), feedback);
+ Node* node = NewNode(op, object, key, BuildLoadFeedbackVector());
return node;
}
Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name,
const VectorSlotPair& feedback) {
- const Operator* op = javascript()->LoadNamed(name, feedback);
- Node* node = NewNode(op, object, GetFunctionClosure());
+ const Operator* op = javascript()->LoadNamed(language_mode(), name, feedback);
+ Node* node = NewNode(op, object, BuildLoadFeedbackVector());
return node;
}
@@ -3583,7 +3598,7 @@
Node* AstGraphBuilder::BuildKeyedStore(Node* object, Node* key, Node* value,
const VectorSlotPair& feedback) {
const Operator* op = javascript()->StoreProperty(language_mode(), feedback);
- Node* node = NewNode(op, object, key, value, GetFunctionClosure());
+ Node* node = NewNode(op, object, key, value, BuildLoadFeedbackVector());
return node;
}
@@ -3593,7 +3608,7 @@
const VectorSlotPair& feedback) {
const Operator* op =
javascript()->StoreNamed(language_mode(), name, feedback);
- Node* node = NewNode(op, object, value, GetFunctionClosure());
+ Node* node = NewNode(op, object, value, BuildLoadFeedbackVector());
return node;
}
@@ -3602,8 +3617,9 @@
Handle<Name> name,
const VectorSlotPair& feedback) {
Node* name_node = jsgraph()->Constant(name);
- const Operator* op = javascript()->CallRuntime(Runtime::kLoadFromSuper);
- Node* node = NewNode(op, receiver, home_object, name_node);
+ Node* language = jsgraph()->Constant(language_mode());
+ const Operator* op = javascript()->CallRuntime(Runtime::kLoadFromSuper, 4);
+ Node* node = NewNode(op, receiver, home_object, name_node, language);
return node;
}
@@ -3611,8 +3627,10 @@
Node* AstGraphBuilder::BuildKeyedSuperLoad(Node* receiver, Node* home_object,
Node* key,
const VectorSlotPair& feedback) {
- const Operator* op = javascript()->CallRuntime(Runtime::kLoadKeyedFromSuper);
- Node* node = NewNode(op, receiver, home_object, key);
+ Node* language = jsgraph()->Constant(language_mode());
+ const Operator* op =
+ javascript()->CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
+ Node* node = NewNode(op, receiver, home_object, key, language);
return node;
}
@@ -3644,7 +3662,7 @@
const VectorSlotPair& feedback,
TypeofMode typeof_mode) {
const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
- Node* node = NewNode(op, GetFunctionClosure());
+ Node* node = NewNode(op, BuildLoadFeedbackVector());
return node;
}
@@ -3653,30 +3671,22 @@
const VectorSlotPair& feedback) {
const Operator* op =
javascript()->StoreGlobal(language_mode(), name, feedback);
- Node* node = NewNode(op, value, GetFunctionClosure());
+ Node* node = NewNode(op, value, BuildLoadFeedbackVector());
return node;
}
-Node* AstGraphBuilder::BuildDynamicLoad(Handle<Name> name,
- TypeofMode typeof_mode) {
- Node* name_node = jsgraph()->Constant(name);
- const Operator* op =
- javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
- ? Runtime::kLoadLookupSlot
- : Runtime::kLoadLookupSlotInsideTypeof);
- Node* node = NewNode(op, name_node);
- return node;
+Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
+ return NewNode(jsgraph()->machine()->Load(MachineType::AnyTagged()), object,
+ jsgraph()->IntPtrConstant(offset - kHeapObjectTag));
}
-Node* AstGraphBuilder::BuildDynamicStore(Handle<Name> name, Node* value) {
- Node* name_node = jsgraph()->Constant(name);
- const Operator* op = javascript()->CallRuntime(
- is_strict(language_mode()) ? Runtime::kStoreLookupSlot_Strict
- : Runtime::kStoreLookupSlot_Sloppy);
- Node* node = NewNode(op, name_node, value);
- return node;
+Node* AstGraphBuilder::BuildLoadImmutableObjectField(Node* object, int offset) {
+ return graph()->NewNode(jsgraph()->machine()->Load(MachineType::AnyTagged()),
+ object,
+ jsgraph()->IntPtrConstant(offset - kHeapObjectTag),
+ graph()->start(), graph()->start());
}
@@ -3693,6 +3703,19 @@
}
+Node* AstGraphBuilder::BuildLoadFeedbackVector() {
+ if (!feedback_vector_.is_set()) {
+ Node* closure = GetFunctionClosure();
+ Node* shared = BuildLoadImmutableObjectField(
+ closure, JSFunction::kSharedFunctionInfoOffset);
+ Node* vector = BuildLoadImmutableObjectField(
+ shared, SharedFunctionInfo::kFeedbackVectorOffset);
+ feedback_vector_.set(vector);
+ }
+ return feedback_vector_.get();
+}
+
+
Node* AstGraphBuilder::BuildToBoolean(Node* input, TypeFeedbackId feedback_id) {
if (Node* node = TryFastToBoolean(input)) return node;
ToBooleanHints hints;
@@ -3735,7 +3758,7 @@
Node* AstGraphBuilder::BuildThrowError(Node* exception, BailoutId bailout_id) {
- const Operator* op = javascript()->CallRuntime(Runtime::kThrow);
+ const Operator* op = javascript()->CallRuntime(Runtime::kThrow, 1);
Node* call = NewNode(op, exception);
PrepareFrameState(call, bailout_id);
Node* control = NewNode(common()->Throw(), call);
@@ -3747,7 +3770,8 @@
Node* AstGraphBuilder::BuildThrowReferenceError(Variable* variable,
BailoutId bailout_id) {
Node* variable_name = jsgraph()->Constant(variable->name());
- const Operator* op = javascript()->CallRuntime(Runtime::kThrowReferenceError);
+ const Operator* op =
+ javascript()->CallRuntime(Runtime::kThrowReferenceError, 1);
Node* call = NewNode(op, variable_name);
PrepareFrameState(call, bailout_id);
Node* control = NewNode(common()->Throw(), call);
@@ -3758,7 +3782,7 @@
Node* AstGraphBuilder::BuildThrowConstAssignError(BailoutId bailout_id) {
const Operator* op =
- javascript()->CallRuntime(Runtime::kThrowConstAssignError);
+ javascript()->CallRuntime(Runtime::kThrowConstAssignError, 0);
Node* call = NewNode(op);
PrepareFrameState(call, bailout_id);
Node* control = NewNode(common()->Throw(), call);
@@ -3769,7 +3793,7 @@
Node* AstGraphBuilder::BuildThrowStaticPrototypeError(BailoutId bailout_id) {
const Operator* op =
- javascript()->CallRuntime(Runtime::kThrowStaticPrototypeError);
+ javascript()->CallRuntime(Runtime::kThrowStaticPrototypeError, 0);
Node* call = NewNode(op);
PrepareFrameState(call, bailout_id);
Node* control = NewNode(common()->Throw(), call);
@@ -3780,7 +3804,7 @@
Node* AstGraphBuilder::BuildThrowUnsupportedSuperError(BailoutId bailout_id) {
const Operator* op =
- javascript()->CallRuntime(Runtime::kThrowUnsupportedSuperError);
+ javascript()->CallRuntime(Runtime::kThrowUnsupportedSuperError, 0);
Node* call = NewNode(op);
PrepareFrameState(call, bailout_id);
Node* control = NewNode(common()->Throw(), call);
@@ -3790,11 +3814,6 @@
Node* AstGraphBuilder::BuildReturn(Node* return_value) {
- // Emit tracing call if requested to do so.
- if (FLAG_trace) {
- return_value =
- NewNode(javascript()->CallRuntime(Runtime::kTraceExit), return_value);
- }
Node* control = NewNode(common()->Return(), return_value);
UpdateControlDependencyToLeaveFunction(control);
return control;
@@ -3802,7 +3821,7 @@
Node* AstGraphBuilder::BuildThrow(Node* exception_value) {
- NewNode(javascript()->CallRuntime(Runtime::kReThrow), exception_value);
+ NewNode(javascript()->CallRuntime(Runtime::kReThrow, 1), exception_value);
Node* control = NewNode(common()->Throw(), exception_value);
UpdateControlDependencyToLeaveFunction(control);
return control;
@@ -3819,37 +3838,37 @@
}
switch (op) {
case Token::BIT_OR:
- js_op = javascript()->BitwiseOr(hints);
+ js_op = javascript()->BitwiseOr(language_mode(), hints);
break;
case Token::BIT_AND:
- js_op = javascript()->BitwiseAnd(hints);
+ js_op = javascript()->BitwiseAnd(language_mode(), hints);
break;
case Token::BIT_XOR:
- js_op = javascript()->BitwiseXor(hints);
+ js_op = javascript()->BitwiseXor(language_mode(), hints);
break;
case Token::SHL:
- js_op = javascript()->ShiftLeft(hints);
+ js_op = javascript()->ShiftLeft(language_mode(), hints);
break;
case Token::SAR:
- js_op = javascript()->ShiftRight(hints);
+ js_op = javascript()->ShiftRight(language_mode(), hints);
break;
case Token::SHR:
- js_op = javascript()->ShiftRightLogical(hints);
+ js_op = javascript()->ShiftRightLogical(language_mode(), hints);
break;
case Token::ADD:
- js_op = javascript()->Add(hints);
+ js_op = javascript()->Add(language_mode(), hints);
break;
case Token::SUB:
- js_op = javascript()->Subtract(hints);
+ js_op = javascript()->Subtract(language_mode(), hints);
break;
case Token::MUL:
- js_op = javascript()->Multiply(hints);
+ js_op = javascript()->Multiply(language_mode(), hints);
break;
case Token::DIV:
- js_op = javascript()->Divide(hints);
+ js_op = javascript()->Divide(language_mode(), hints);
break;
case Token::MOD:
- js_op = javascript()->Modulus(hints);
+ js_op = javascript()->Modulus(language_mode(), hints);
break;
default:
UNREACHABLE();
@@ -3897,21 +3916,17 @@
fast_block.BreakUnless(check, BranchHint::kTrue);
}
- // Fast case, because variable is not shadowed.
- if (Node* constant = TryLoadGlobalConstant(name)) {
- environment()->Push(constant);
- } else {
- // Perform global slot load.
- Node* fast = BuildGlobalLoad(name, feedback, typeof_mode);
- states.AddToNode(fast, bailout_id, combine);
- environment()->Push(fast);
- }
+ // Fast case, because variable is not shadowed. Perform global slot load.
+ Node* fast = BuildGlobalLoad(name, feedback, typeof_mode);
+ states.AddToNode(fast, bailout_id, combine);
+ environment()->Push(fast);
slow_block.Break();
environment()->Pop();
fast_block.EndBlock();
// Slow case, because variable potentially shadowed. Perform dynamic lookup.
- Node* slow = BuildDynamicLoad(name, typeof_mode);
+ const Operator* op = javascript()->LoadDynamic(name, typeof_mode);
+ Node* slow = NewNode(op, BuildLoadFeedbackVector(), current_context());
states.AddToNode(slow, bailout_id, combine);
environment()->Push(slow);
slow_block.EndBlock();
@@ -3954,7 +3969,8 @@
fast_block.EndBlock();
// Slow case, because variable potentially shadowed. Perform dynamic lookup.
- Node* slow = BuildDynamicLoad(name, typeof_mode);
+ const Operator* op = javascript()->LoadDynamic(name, typeof_mode);
+ Node* slow = NewNode(op, BuildLoadFeedbackVector(), current_context());
states.AddToNode(slow, bailout_id, combine);
environment()->Push(slow);
slow_block.EndBlock();
@@ -4031,10 +4047,8 @@
DCHECK_EQ(IrOpcode::kDead,
NodeProperties::GetFrameStateInput(node, 0)->opcode());
- bool node_has_exception = NodeProperties::IsExceptionalCall(node);
NodeProperties::ReplaceFrameStateInput(
- node, 0,
- environment()->Checkpoint(ast_id, combine, node_has_exception));
+ node, 0, environment()->Checkpoint(ast_id, combine));
}
}