diff options
Diffstat (limited to 'deps/v8/src/compiler/ast-graph-builder.cc')
-rw-r--r-- | deps/v8/src/compiler/ast-graph-builder.cc | 130 |
1 files changed, 78 insertions, 52 deletions
diff --git a/deps/v8/src/compiler/ast-graph-builder.cc b/deps/v8/src/compiler/ast-graph-builder.cc index abcf828c39..89bb61949a 100644 --- a/deps/v8/src/compiler/ast-graph-builder.cc +++ b/deps/v8/src/compiler/ast-graph-builder.cc @@ -616,12 +616,6 @@ void AstGraphBuilder::CreateGraphBody(bool stack_check) { NewNode(javascript()->CallRuntime(Runtime::kTraceEnter)); } - // Visit illegal re-declaration and bail out if it exists. - if (scope->HasIllegalRedeclaration()) { - VisitForEffect(scope->GetIllegalRedeclaration()); - return; - } - // Visit declarations within the function scope. VisitDeclarations(scope->declarations()); @@ -646,7 +640,7 @@ void AstGraphBuilder::ClearNonLiveSlotsInFrameStates() { } NonLiveFrameStateSlotReplacer replacer( - &state_values_cache_, jsgraph()->UndefinedConstant(), + &state_values_cache_, jsgraph()->OptimizedOutConstant(), liveness_analyzer()->local_count(), local_zone()); Variable* arguments = info()->scope()->arguments(); if (arguments != nullptr && arguments->IsStackAllocated()) { @@ -1448,9 +1442,11 @@ void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { } try_control.EndTry(); - // Clear message object as we enter the catch block. - Node* the_hole = jsgraph()->TheHoleConstant(); - NewNode(javascript()->StoreMessage(), the_hole); + // If requested, clear message object as we enter the catch block. + if (stmt->clear_pending_message()) { + Node* the_hole = jsgraph()->TheHoleConstant(); + NewNode(javascript()->StoreMessage(), the_hole); + } // Create a catch scope that binds the exception. Node* exception = try_control.GetExceptionNode(); @@ -1644,8 +1640,7 @@ void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) { } } - // Set both the prototype and constructor to have fast properties, and also - // freeze them in strong mode. + // Set both the prototype and constructor to have fast properties. prototype = environment()->Pop(); literal = environment()->Pop(); const Operator* op = @@ -1725,7 +1720,7 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { // Create node to deep-copy the literal boilerplate. const Operator* op = javascript()->CreateLiteralObject( expr->constant_properties(), expr->ComputeFlags(true), - expr->literal_index()); + expr->literal_index(), expr->properties_count()); Node* literal = NewNode(op, closure); PrepareFrameState(literal, expr->CreateLiteralId(), OutputFrameStateCombine::Push()); @@ -1900,13 +1895,6 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { } } - // 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); - NewNode(op, literal); - } - ast_context()->ProduceValue(environment()->Pop()); } @@ -1928,7 +1916,7 @@ void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { // Create node to deep-copy the literal boilerplate. const Operator* op = javascript()->CreateLiteralArray( expr->constant_elements(), expr->ComputeFlags(true), - expr->literal_index()); + expr->literal_index(), expr->values()->length()); Node* literal = NewNode(op, closure); PrepareFrameState(literal, expr->CreateLiteralId(), OutputFrameStateCombine::Push()); @@ -2576,22 +2564,12 @@ void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { return VisitCallJSRuntime(expr); } - const Runtime::Function* function = expr->function(); - - // 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(); - } - // 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; + Runtime::FunctionId functionId = expr->function()->function_id; const Operator* call = javascript()->CallRuntime(functionId, args->length()); FrameStateBeforeAndAfter states(this, expr->CallId()); Node* value = ProcessArguments(call, args->length()); @@ -2704,11 +2682,9 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) { } // Convert old value into a number. - if (!is_strong(language_mode())) { - old_value = NewNode(javascript()->ToNumber(), old_value); - PrepareFrameState(old_value, expr->ToNumberId(), - OutputFrameStateCombine::Push()); - } + old_value = NewNode(javascript()->ToNumber(), old_value); + PrepareFrameState(old_value, expr->ToNumberId(), + OutputFrameStateCombine::Push()); // Create a proper eager frame state for the stores. environment()->Push(old_value); @@ -2731,10 +2707,8 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) { FrameStateBeforeAndAfter states(this, BailoutId::None()); value = BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op(), expr->CountBinOpFeedbackId()); - // This should never deoptimize outside strong mode because otherwise we - // have converted to number before. - states.AddToNode(value, is_strong(language_mode()) ? expr->ToNumberId() - : BailoutId::None(), + // This should never deoptimize because we have converted to number before. + states.AddToNode(value, BailoutId::None(), OutputFrameStateCombine::Ignore()); } @@ -2821,8 +2795,57 @@ void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { } } +void AstGraphBuilder::VisitLiteralCompareNil(CompareOperation* expr, + Expression* sub_expr, + Node* nil_value) { + const Operator* op = nullptr; + switch (expr->op()) { + case Token::EQ: + op = javascript()->Equal(); + break; + case Token::EQ_STRICT: + op = javascript()->StrictEqual(); + break; + default: + UNREACHABLE(); + } + VisitForValue(sub_expr); + FrameStateBeforeAndAfter states(this, 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()); + return ast_context()->ProduceValue(value); +} + +void AstGraphBuilder::VisitLiteralCompareTypeof(CompareOperation* expr, + Expression* sub_expr, + Handle<String> check) { + VisitTypeofExpression(sub_expr); + FrameStateBeforeAndAfter states(this, 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()); + return ast_context()->ProduceValue(value); +} void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { + // Check for a few fast cases. The AST visiting behavior must be in sync + // with the full codegen: We don't push both left and right values onto + // the expression stack when one side is a special-case literal. + Expression* sub_expr = nullptr; + Handle<String> check; + if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { + return VisitLiteralCompareTypeof(expr, sub_expr, check); + } + if (expr->IsLiteralCompareUndefined(&sub_expr)) { + return VisitLiteralCompareNil(expr, sub_expr, + jsgraph()->UndefinedConstant()); + } + if (expr->IsLiteralCompareNull(&sub_expr)) { + return VisitLiteralCompareNil(expr, sub_expr, jsgraph()->NullConstant()); + } + const Operator* op; switch (expr->op()) { case Token::EQ: @@ -2850,6 +2873,7 @@ void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { op = javascript()->GreaterThanOrEqual(); break; case Token::INSTANCEOF: + DCHECK(!FLAG_harmony_instanceof); op = javascript()->InstanceOf(); break; case Token::IN: @@ -2984,23 +3008,25 @@ void AstGraphBuilder::VisitVoid(UnaryOperation* expr) { ast_context()->ProduceValue(value); } - -void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) { - Node* operand; - if (expr->expression()->IsVariableProxy()) { +void AstGraphBuilder::VisitTypeofExpression(Expression* expr) { + if (expr->IsVariableProxy()) { // Typeof does not throw a reference error on global variables, hence we // perform a non-contextual load in case the operand is a variable proxy. - VariableProxy* proxy = expr->expression()->AsVariableProxy(); + VariableProxy* proxy = expr->AsVariableProxy(); VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); FrameStateBeforeAndAfter states(this, BeforeId(proxy)); - operand = - BuildVariableLoad(proxy->var(), expr->expression()->id(), states, pair, + Node* load = + BuildVariableLoad(proxy->var(), expr->id(), states, pair, OutputFrameStateCombine::Push(), INSIDE_TYPEOF); + environment()->Push(load); } else { - VisitForValue(expr->expression()); - operand = environment()->Pop(); + VisitForValue(expr); } - Node* value = NewNode(javascript()->TypeOf(), operand); +} + +void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) { + VisitTypeofExpression(expr->expression()); + Node* value = NewNode(javascript()->TypeOf(), environment()->Pop()); ast_context()->ProduceValue(value); } @@ -3052,7 +3078,7 @@ void AstGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) { LanguageMode AstGraphBuilder::language_mode() const { - return info()->language_mode(); + return current_scope()->language_mode(); } |