Commit cc149578 authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[turbofan] Unify various bailout hacks for super call.

This removes various boilouts for super constructor calls from the
TurboFan pipeline and unifies them. It also disables and optimization
which breaks references to uninitialized const this variables.

R=bmeurer@chromium.org

Review URL: https://codereview.chromium.org/1222843004

Cr-Commit-Position: refs/heads/master@{#29516}
parent fe8c8c3b
...@@ -2537,15 +2537,21 @@ void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { ...@@ -2537,15 +2537,21 @@ void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
return VisitCallJSRuntime(expr); return VisitCallJSRuntime(expr);
} }
// TODO(mstarzinger): This bailout is a gigantic hack, the owner is ashamed.
if (function->function_id == Runtime::kInlineGeneratorNext ||
function->function_id == Runtime::kInlineGeneratorThrow ||
function->function_id == Runtime::kInlineDefaultConstructorCallSuper ||
function->function_id == Runtime::kInlineCallSuperWithSpread) {
ast_context()->ProduceValue(jsgraph()->TheHoleConstant());
return SetStackOverflow();
}
// Evaluate all arguments to the runtime call. // Evaluate all arguments to the runtime call.
ZoneList<Expression*>* args = expr->arguments(); ZoneList<Expression*>* args = expr->arguments();
VisitForValues(args); VisitForValues(args);
// Create node to perform the runtime call. // Create node to perform the runtime call.
Runtime::FunctionId functionId = function->function_id; Runtime::FunctionId functionId = function->function_id;
// TODO(mstarzinger): This bailout is a gigantic hack, the owner is ashamed.
if (functionId == Runtime::kInlineGeneratorNext) SetStackOverflow();
if (functionId == Runtime::kInlineGeneratorThrow) SetStackOverflow();
const Operator* call = javascript()->CallRuntime(functionId, args->length()); const Operator* call = javascript()->CallRuntime(functionId, args->length());
FrameStateBeforeAndAfter states(this, expr->CallId()); FrameStateBeforeAndAfter states(this, expr->CallId());
Node* value = ProcessArguments(call, args->length()); Node* value = ProcessArguments(call, args->length());
...@@ -2818,7 +2824,10 @@ void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { ...@@ -2818,7 +2824,10 @@ void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
} }
void AstGraphBuilder::VisitSpread(Spread* expr) { UNREACHABLE(); } void AstGraphBuilder::VisitSpread(Spread* expr) {
// Handled entirely by the parser itself.
UNREACHABLE();
}
void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) { void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) {
...@@ -2829,20 +2838,21 @@ void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) { ...@@ -2829,20 +2838,21 @@ void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) {
void AstGraphBuilder::VisitSuperPropertyReference( void AstGraphBuilder::VisitSuperPropertyReference(
SuperPropertyReference* expr) { SuperPropertyReference* expr) {
// TODO(turbofan): Implement super here. Node* value = BuildThrowUnsupportedSuperError(expr->id());
SetStackOverflow(); ast_context()->ProduceValue(value);
ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
} }
void AstGraphBuilder::VisitSuperCallReference(SuperCallReference* expr) { void AstGraphBuilder::VisitSuperCallReference(SuperCallReference* expr) {
// TODO(turbofan): Implement super here. Node* value = BuildThrowUnsupportedSuperError(expr->id());
SetStackOverflow(); ast_context()->ProduceValue(value);
ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
} }
void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { UNREACHABLE(); } void AstGraphBuilder::VisitCaseClause(CaseClause* expr) {
// Handled entirely in VisitSwitch.
UNREACHABLE();
}
void AstGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) { void AstGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) {
...@@ -3274,9 +3284,12 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable, ...@@ -3274,9 +3284,12 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
} }
} else if (mode == LET || mode == CONST) { } else if (mode == LET || mode == CONST) {
// Perform check for uninitialized let/const variables. // Perform check for uninitialized let/const variables.
// TODO(mstarzinger): For now we cannot use the below optimization for
// the {this} parameter, because JSConstructStubForDerived magically
// passes {the_hole} as a receiver.
if (value->op() == the_hole->op()) { if (value->op() == the_hole->op()) {
value = BuildThrowReferenceError(variable, bailout_id); value = BuildThrowReferenceError(variable, bailout_id);
} else if (value->opcode() == IrOpcode::kPhi) { } else if (value->opcode() == IrOpcode::kPhi || variable->is_this()) {
value = BuildHoleCheckThrow(value, variable, value, bailout_id); value = BuildHoleCheckThrow(value, variable, value, bailout_id);
} }
} }
...@@ -3796,6 +3809,17 @@ Node* AstGraphBuilder::BuildThrowStaticPrototypeError(BailoutId bailout_id) { ...@@ -3796,6 +3809,17 @@ Node* AstGraphBuilder::BuildThrowStaticPrototypeError(BailoutId bailout_id) {
} }
Node* AstGraphBuilder::BuildThrowUnsupportedSuperError(BailoutId bailout_id) {
const Operator* op =
javascript()->CallRuntime(Runtime::kThrowUnsupportedSuperError, 0);
Node* call = NewNode(op);
PrepareFrameState(call, bailout_id);
Node* control = NewNode(common()->Throw(), call);
UpdateControlDependencyToLeaveFunction(control);
return call;
}
Node* AstGraphBuilder::BuildReturn(Node* return_value) { Node* AstGraphBuilder::BuildReturn(Node* return_value) {
Node* control = NewNode(common()->Return(), return_value); Node* control = NewNode(common()->Return(), return_value);
UpdateControlDependencyToLeaveFunction(control); UpdateControlDependencyToLeaveFunction(control);
......
...@@ -341,6 +341,7 @@ class AstGraphBuilder : public AstVisitor { ...@@ -341,6 +341,7 @@ class AstGraphBuilder : public AstVisitor {
Node* BuildThrowReferenceError(Variable* var, BailoutId bailout_id); Node* BuildThrowReferenceError(Variable* var, BailoutId bailout_id);
Node* BuildThrowConstAssignError(BailoutId bailout_id); Node* BuildThrowConstAssignError(BailoutId bailout_id);
Node* BuildThrowStaticPrototypeError(BailoutId bailout_id); Node* BuildThrowStaticPrototypeError(BailoutId bailout_id);
Node* BuildThrowUnsupportedSuperError(BailoutId bailout_id);
// Builders for dynamic hole-checks at runtime. // Builders for dynamic hole-checks at runtime.
Node* BuildHoleCheckSilent(Node* value, Node* for_hole, Node* not_hole); Node* BuildHoleCheckSilent(Node* value, Node* for_hole, Node* not_hole);
......
...@@ -966,19 +966,12 @@ Handle<Code> Pipeline::GenerateCode() { ...@@ -966,19 +966,12 @@ Handle<Code> Pipeline::GenerateCode() {
// TODO(mstarzinger): This is just a temporary hack to make TurboFan work, // TODO(mstarzinger): This is just a temporary hack to make TurboFan work,
// the correct solution is to restore the context register after invoking // the correct solution is to restore the context register after invoking
// builtins from full-codegen. // builtins from full-codegen.
Handle<SharedFunctionInfo> shared = info()->shared_info();
for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) { for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i); Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
Object* builtin = isolate()->js_builtins_object()->javascript_builtin(id); Object* builtin = isolate()->js_builtins_object()->javascript_builtin(id);
if (*info()->closure() == builtin) return Handle<Code>::null(); if (*info()->closure() == builtin) return Handle<Code>::null();
} }
// TODO(dslomov): support turbo optimization of subclass constructors.
if (IsSubclassConstructor(shared->kind())) {
shared->DisableOptimization(kSuperReference);
return Handle<Code>::null();
}
ZonePool zone_pool; ZonePool zone_pool;
SmartPointer<PipelineStatistics> pipeline_statistics; SmartPointer<PipelineStatistics> pipeline_statistics;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment