From cc149578cf1ee5c59fbc8cb0ff4b1455b11717ba Mon Sep 17 00:00:00 2001 From: mstarzinger Date: Tue, 7 Jul 2015 06:25:53 -0700 Subject: [PATCH] [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} --- src/compiler/ast-graph-builder.cc | 48 +++++++++++++++++++++++-------- src/compiler/ast-graph-builder.h | 1 + src/compiler/pipeline.cc | 7 ----- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc index a3545ca8a..d04fc62c7 100644 --- a/src/compiler/ast-graph-builder.cc +++ b/src/compiler/ast-graph-builder.cc @@ -2537,15 +2537,21 @@ void AstGraphBuilder::VisitCallRuntime(CallRuntime* 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. ZoneList* args = expr->arguments(); VisitForValues(args); // Create node to perform the runtime call. 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()); FrameStateBeforeAndAfter states(this, expr->CallId()); Node* value = ProcessArguments(call, args->length()); @@ -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) { @@ -2829,20 +2838,21 @@ void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) { void AstGraphBuilder::VisitSuperPropertyReference( SuperPropertyReference* expr) { - // TODO(turbofan): Implement super here. - SetStackOverflow(); - ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); + Node* value = BuildThrowUnsupportedSuperError(expr->id()); + ast_context()->ProduceValue(value); } void AstGraphBuilder::VisitSuperCallReference(SuperCallReference* expr) { - // TODO(turbofan): Implement super here. - SetStackOverflow(); - ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); + Node* value = BuildThrowUnsupportedSuperError(expr->id()); + ast_context()->ProduceValue(value); } -void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { UNREACHABLE(); } +void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { + // Handled entirely in VisitSwitch. + UNREACHABLE(); +} void AstGraphBuilder::VisitDeclarations(ZoneList* declarations) { @@ -3274,9 +3284,12 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable, } } else if (mode == LET || mode == CONST) { // 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()) { 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); } } @@ -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* control = NewNode(common()->Return(), return_value); UpdateControlDependencyToLeaveFunction(control); diff --git a/src/compiler/ast-graph-builder.h b/src/compiler/ast-graph-builder.h index b2c6f4355..07de774c4 100644 --- a/src/compiler/ast-graph-builder.h +++ b/src/compiler/ast-graph-builder.h @@ -341,6 +341,7 @@ class AstGraphBuilder : public AstVisitor { Node* BuildThrowReferenceError(Variable* var, BailoutId bailout_id); Node* BuildThrowConstAssignError(BailoutId bailout_id); Node* BuildThrowStaticPrototypeError(BailoutId bailout_id); + Node* BuildThrowUnsupportedSuperError(BailoutId bailout_id); // Builders for dynamic hole-checks at runtime. Node* BuildHoleCheckSilent(Node* value, Node* for_hole, Node* not_hole); diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc index ef9adc974..55455690d 100644 --- a/src/compiler/pipeline.cc +++ b/src/compiler/pipeline.cc @@ -966,19 +966,12 @@ Handle Pipeline::GenerateCode() { // TODO(mstarzinger): This is just a temporary hack to make TurboFan work, // the correct solution is to restore the context register after invoking // builtins from full-codegen. - Handle shared = info()->shared_info(); for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) { Builtins::JavaScript id = static_cast(i); Object* builtin = isolate()->js_builtins_object()->javascript_builtin(id); if (*info()->closure() == builtin) return Handle::null(); } - // TODO(dslomov): support turbo optimization of subclass constructors. - if (IsSubclassConstructor(shared->kind())) { - shared->DisableOptimization(kSuperReference); - return Handle::null(); - } - ZonePool zone_pool; SmartPointer pipeline_statistics; -- 2.34.1