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) {
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<Expression*>* 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<Declaration*>* 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);
......
......@@ -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);
......
......@@ -966,19 +966,12 @@ Handle<Code> 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<SharedFunctionInfo> shared = info()->shared_info();
for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
Object* builtin = isolate()->js_builtins_object()->javascript_builtin(id);
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;
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