diff options
author | Zeno Albisser <zeno.albisser@digia.com> | 2013-11-21 14:09:57 +0100 |
---|---|---|
committer | Andras Becsi <andras.becsi@digia.com> | 2013-11-29 15:14:36 +0100 |
commit | eb32ba6f51d0c21d58cd7d89785285ff8fa64624 (patch) | |
tree | 2c7c940e1dbee81b89d935626110816b494aa32c /chromium/v8/src/typing.cc | |
parent | 9427c1a0222ebd67efef1a2c7990a0fa5c9aac84 (diff) | |
download | qtwebengine-chromium-eb32ba6f51d0c21d58cd7d89785285ff8fa64624.tar.gz |
Update chromium to branch 1599.
Change-Id: I04e775a946a208bb4500d3b722bcb05c82b9d7cb
Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/v8/src/typing.cc')
-rw-r--r-- | chromium/v8/src/typing.cc | 252 |
1 files changed, 73 insertions, 179 deletions
diff --git a/chromium/v8/src/typing.cc b/chromium/v8/src/typing.cc index f8e2a7c206d..4220d2110db 100644 --- a/chromium/v8/src/typing.cc +++ b/chromium/v8/src/typing.cc @@ -40,8 +40,7 @@ AstTyper::AstTyper(CompilationInfo* info) Handle<Code>(info->closure()->shared()->code()), Handle<Context>(info->closure()->context()->native_context()), info->isolate(), - info->zone()), - store_(info->zone()) { + info->zone()) { InitializeAstVisitor(); } @@ -80,16 +79,12 @@ void AstTyper::VisitStatements(ZoneList<Statement*>* stmts) { for (int i = 0; i < stmts->length(); ++i) { Statement* stmt = stmts->at(i); RECURSE(Visit(stmt)); - if (stmt->IsJump()) break; } } void AstTyper::VisitBlock(Block* stmt) { RECURSE(VisitStatements(stmt->statements())); - if (stmt->labels() != NULL) { - store_.Forget(); // Control may transfer here via 'break l'. - } } @@ -103,41 +98,30 @@ void AstTyper::VisitEmptyStatement(EmptyStatement* stmt) { void AstTyper::VisitIfStatement(IfStatement* stmt) { - // Collect type feedback. + RECURSE(Visit(stmt->condition())); + RECURSE(Visit(stmt->then_statement())); + RECURSE(Visit(stmt->else_statement())); + if (!stmt->condition()->ToBooleanIsTrue() && !stmt->condition()->ToBooleanIsFalse()) { stmt->condition()->RecordToBooleanTypeFeedback(oracle()); } - - RECURSE(Visit(stmt->condition())); - Effects then_effects = EnterEffects(); - RECURSE(Visit(stmt->then_statement())); - ExitEffects(); - Effects else_effects = EnterEffects(); - RECURSE(Visit(stmt->else_statement())); - ExitEffects(); - then_effects.Alt(else_effects); - store_.Seq(then_effects); } void AstTyper::VisitContinueStatement(ContinueStatement* stmt) { - // TODO(rossberg): is it worth having a non-termination effect? } void AstTyper::VisitBreakStatement(BreakStatement* stmt) { - // TODO(rossberg): is it worth having a non-termination effect? } void AstTyper::VisitReturnStatement(ReturnStatement* stmt) { - // Collect type feedback. + RECURSE(Visit(stmt->expression())); + // TODO(rossberg): we only need this for inlining into test contexts... stmt->expression()->RecordToBooleanTypeFeedback(oracle()); - - RECURSE(Visit(stmt->expression())); - // TODO(rossberg): is it worth having a non-termination effect? } @@ -149,18 +133,14 @@ void AstTyper::VisitWithStatement(WithStatement* stmt) { void AstTyper::VisitSwitchStatement(SwitchStatement* stmt) { RECURSE(Visit(stmt->tag())); - ZoneList<CaseClause*>* clauses = stmt->cases(); SwitchStatement::SwitchType switch_type = stmt->switch_type(); - Effects local_effects(zone()); - bool complex_effects = false; // True for label effects or fall-through. - for (int i = 0; i < clauses->length(); ++i) { CaseClause* clause = clauses->at(i); - Effects clause_effects = EnterEffects(); - if (!clause->is_default()) { Expression* label = clause->label(); + RECURSE(Visit(label)); + SwitchStatement::SwitchType label_switch_type = label->IsSmiLiteral() ? SwitchStatement::SMI_SWITCH : label->IsStringLiteral() ? SwitchStatement::STRING_SWITCH : @@ -169,32 +149,13 @@ void AstTyper::VisitSwitchStatement(SwitchStatement* stmt) { switch_type = label_switch_type; else if (switch_type != label_switch_type) switch_type = SwitchStatement::GENERIC_SWITCH; - - RECURSE(Visit(label)); - if (!clause_effects.IsEmpty()) complex_effects = true; - } - - ZoneList<Statement*>* stmts = clause->statements(); - RECURSE(VisitStatements(stmts)); - ExitEffects(); - if (stmts->is_empty() || stmts->last()->IsJump()) { - local_effects.Alt(clause_effects); - } else { - complex_effects = true; } + RECURSE(VisitStatements(clause->statements())); } - - if (complex_effects) { - store_.Forget(); // Reached this in unknown state. - } else { - store_.Seq(local_effects); - } - if (switch_type == SwitchStatement::UNKNOWN_SWITCH) switch_type = SwitchStatement::GENERIC_SWITCH; stmt->set_switch_type(switch_type); - // Collect type feedback. // TODO(rossberg): can we eliminate this special case and extra loop? if (switch_type == SwitchStatement::SMI_SWITCH) { for (int i = 0; i < clauses->length(); ++i) { @@ -207,31 +168,22 @@ void AstTyper::VisitSwitchStatement(SwitchStatement* stmt) { void AstTyper::VisitDoWhileStatement(DoWhileStatement* stmt) { - // Collect type feedback. + RECURSE(Visit(stmt->body())); + RECURSE(Visit(stmt->cond())); + if (!stmt->cond()->ToBooleanIsTrue()) { stmt->cond()->RecordToBooleanTypeFeedback(oracle()); } - - // TODO(rossberg): refine the unconditional Forget (here and elsewhere) by - // computing the set of variables assigned in only some of the origins of the - // control transfer (such as the loop body here). - store_.Forget(); // Control may transfer here via looping or 'continue'. - RECURSE(Visit(stmt->body())); - RECURSE(Visit(stmt->cond())); - store_.Forget(); // Control may transfer here via 'break'. } void AstTyper::VisitWhileStatement(WhileStatement* stmt) { - // Collect type feedback. + RECURSE(Visit(stmt->cond())); + RECURSE(Visit(stmt->body())); + if (!stmt->cond()->ToBooleanIsTrue()) { stmt->cond()->RecordToBooleanTypeFeedback(oracle()); } - - store_.Forget(); // Control may transfer here via looping or 'continue'. - RECURSE(Visit(stmt->cond())); - RECURSE(Visit(stmt->body())); - store_.Forget(); // Control may transfer here via termination or 'break'. } @@ -239,65 +191,45 @@ void AstTyper::VisitForStatement(ForStatement* stmt) { if (stmt->init() != NULL) { RECURSE(Visit(stmt->init())); } - store_.Forget(); // Control may transfer here via looping. if (stmt->cond() != NULL) { - // Collect type feedback. - stmt->cond()->RecordToBooleanTypeFeedback(oracle()); - RECURSE(Visit(stmt->cond())); + + stmt->cond()->RecordToBooleanTypeFeedback(oracle()); } RECURSE(Visit(stmt->body())); - store_.Forget(); // Control may transfer here via 'continue'. if (stmt->next() != NULL) { RECURSE(Visit(stmt->next())); } - store_.Forget(); // Control may transfer here via termination or 'break'. } void AstTyper::VisitForInStatement(ForInStatement* stmt) { - // Collect type feedback. - stmt->RecordTypeFeedback(oracle()); - RECURSE(Visit(stmt->enumerable())); - store_.Forget(); // Control may transfer here via looping or 'continue'. RECURSE(Visit(stmt->body())); - store_.Forget(); // Control may transfer here via 'break'. + + stmt->RecordTypeFeedback(oracle()); } void AstTyper::VisitForOfStatement(ForOfStatement* stmt) { RECURSE(Visit(stmt->iterable())); - store_.Forget(); // Control may transfer here via looping or 'continue'. RECURSE(Visit(stmt->body())); - store_.Forget(); // Control may transfer here via 'break'. } void AstTyper::VisitTryCatchStatement(TryCatchStatement* stmt) { - Effects try_effects = EnterEffects(); RECURSE(Visit(stmt->try_block())); - ExitEffects(); - Effects catch_effects = EnterEffects(); - store_.Forget(); // Control may transfer here via 'throw'. RECURSE(Visit(stmt->catch_block())); - ExitEffects(); - try_effects.Alt(catch_effects); - store_.Seq(try_effects); - // At this point, only variables that were reassigned in the catch block are - // still remembered. } void AstTyper::VisitTryFinallyStatement(TryFinallyStatement* stmt) { RECURSE(Visit(stmt->try_block())); - store_.Forget(); // Control may transfer here via 'throw'. RECURSE(Visit(stmt->finally_block())); } void AstTyper::VisitDebuggerStatement(DebuggerStatement* stmt) { - store_.Forget(); // May do whatever. } @@ -310,18 +242,11 @@ void AstTyper::VisitSharedFunctionInfoLiteral(SharedFunctionInfoLiteral* expr) { void AstTyper::VisitConditional(Conditional* expr) { - // Collect type feedback. - expr->condition()->RecordToBooleanTypeFeedback(oracle()); - RECURSE(Visit(expr->condition())); - Effects then_effects = EnterEffects(); RECURSE(Visit(expr->then_expression())); - ExitEffects(); - Effects else_effects = EnterEffects(); RECURSE(Visit(expr->else_expression())); - ExitEffects(); - then_effects.Alt(else_effects); - store_.Seq(then_effects); + + expr->condition()->RecordToBooleanTypeFeedback(oracle()); NarrowType(expr, Bounds::Either( expr->then_expression()->bounds(), @@ -330,10 +255,7 @@ void AstTyper::VisitConditional(Conditional* expr) { void AstTyper::VisitVariableProxy(VariableProxy* expr) { - Variable* var = expr->var(); - if (var->IsStackAllocated()) { - NarrowType(expr, store_.LookupBounds(variable_index(var))); - } + // TODO(rossberg): typing of variables } @@ -352,8 +274,8 @@ void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) { ZoneList<ObjectLiteral::Property*>* properties = expr->properties(); for (int i = 0; i < properties->length(); ++i) { ObjectLiteral::Property* prop = properties->at(i); + RECURSE(Visit(prop->value())); - // Collect type feedback. if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL && !CompileTimeValue::IsCompileTimeValue(prop->value())) || prop->kind() == ObjectLiteral::Property::COMPUTED) { @@ -361,8 +283,6 @@ void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) { prop->RecordTypeFeedback(oracle()); } } - - RECURSE(Visit(prop->value())); } NarrowType(expr, Bounds(Type::Object(), isolate_)); @@ -383,33 +303,29 @@ void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) { void AstTyper::VisitAssignment(Assignment* expr) { // TODO(rossberg): Can we clean this up? if (expr->is_compound()) { - // Collect type feedback. + RECURSE(Visit(expr->binary_operation())); + Expression* target = expr->target(); Property* prop = target->AsProperty(); if (prop != NULL) { prop->RecordTypeFeedback(oracle(), zone()); - expr->RecordTypeFeedback(oracle(), zone()); + if (!prop->key()->IsPropertyName()) { // i.e., keyed + expr->RecordTypeFeedback(oracle(), zone()); + } } - RECURSE(Visit(expr->binary_operation())); - NarrowType(expr, expr->binary_operation()->bounds()); } else { - // Collect type feedback. - if (expr->target()->IsProperty()) { - expr->RecordTypeFeedback(oracle(), zone()); - } - RECURSE(Visit(expr->target())); RECURSE(Visit(expr->value())); - NarrowType(expr, expr->value()->bounds()); - } + if (expr->target()->AsProperty()) { + expr->RecordTypeFeedback(oracle(), zone()); + } - VariableProxy* proxy = expr->target()->AsVariableProxy(); - if (proxy != NULL && proxy->var()->IsStackAllocated()) { - store_.Seq(variable_index(proxy->var()), Effect(expr->bounds())); + NarrowType(expr, expr->value()->bounds()); } + // TODO(rossberg): handle target variables } @@ -417,40 +333,28 @@ void AstTyper::VisitYield(Yield* expr) { RECURSE(Visit(expr->generator_object())); RECURSE(Visit(expr->expression())); - // We don't know anything about the result type. + // We don't know anything about the type. } void AstTyper::VisitThrow(Throw* expr) { RECURSE(Visit(expr->exception())); - // TODO(rossberg): is it worth having a non-termination effect? NarrowType(expr, Bounds(Type::None(), isolate_)); } void AstTyper::VisitProperty(Property* expr) { - // Collect type feedback. - expr->RecordTypeFeedback(oracle(), zone()); - RECURSE(Visit(expr->obj())); RECURSE(Visit(expr->key())); - // We don't know anything about the result type. + expr->RecordTypeFeedback(oracle(), zone()); + + // We don't know anything about the type. } void AstTyper::VisitCall(Call* expr) { - // Collect type feedback. - Expression* callee = expr->expression(); - Property* prop = callee->AsProperty(); - if (prop != NULL) { - if (prop->key()->IsPropertyName()) - expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD); - } else { - expr->RecordTypeFeedback(oracle(), CALL_AS_FUNCTION); - } - RECURSE(Visit(expr->expression())); ZoneList<Expression*>* args = expr->arguments(); for (int i = 0; i < args->length(); ++i) { @@ -458,19 +362,20 @@ void AstTyper::VisitCall(Call* expr) { RECURSE(Visit(arg)); } - VariableProxy* proxy = expr->expression()->AsVariableProxy(); - if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { - store_.Forget(); // Eval could do whatever to local variables. + Expression* callee = expr->expression(); + Property* prop = callee->AsProperty(); + if (prop != NULL) { + if (prop->key()->IsPropertyName()) + expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD); + } else { + expr->RecordTypeFeedback(oracle(), CALL_AS_FUNCTION); } - // We don't know anything about the result type. + // We don't know anything about the type. } void AstTyper::VisitCallNew(CallNew* expr) { - // Collect type feedback. - expr->RecordTypeFeedback(oracle()); - RECURSE(Visit(expr->expression())); ZoneList<Expression*>* args = expr->arguments(); for (int i = 0; i < args->length(); ++i) { @@ -478,7 +383,9 @@ void AstTyper::VisitCallNew(CallNew* expr) { RECURSE(Visit(arg)); } - // We don't know anything about the result type. + expr->RecordTypeFeedback(oracle()); + + // We don't know anything about the type. } @@ -489,19 +396,21 @@ void AstTyper::VisitCallRuntime(CallRuntime* expr) { RECURSE(Visit(arg)); } - // We don't know anything about the result type. + // We don't know anything about the type. } void AstTyper::VisitUnaryOperation(UnaryOperation* expr) { + RECURSE(Visit(expr->expression())); + // Collect type feedback. + Handle<Type> op_type = oracle()->UnaryType(expr->UnaryOperationFeedbackId()); + NarrowLowerType(expr->expression(), op_type); if (expr->op() == Token::NOT) { // TODO(rossberg): only do in test or value context. expr->expression()->RecordToBooleanTypeFeedback(oracle()); } - RECURSE(Visit(expr->expression())); - switch (expr->op()) { case Token::NOT: case Token::DELETE: @@ -510,6 +419,16 @@ void AstTyper::VisitUnaryOperation(UnaryOperation* expr) { case Token::VOID: NarrowType(expr, Bounds(Type::Undefined(), isolate_)); break; + case Token::ADD: + case Token::SUB: { + Type* upper = *expr->expression()->bounds().upper; + if (!upper->Is(Type::Number())) upper = Type::Number(); + NarrowType(expr, Bounds(Type::Smi(), upper, isolate_)); + break; + } + case Token::BIT_NOT: + NarrowType(expr, Bounds(Type::Smi(), Type::Signed32(), isolate_)); + break; case Token::TYPEOF: NarrowType(expr, Bounds(Type::InternalizedString(), isolate_)); break; @@ -520,25 +439,22 @@ void AstTyper::VisitUnaryOperation(UnaryOperation* expr) { void AstTyper::VisitCountOperation(CountOperation* expr) { - // Collect type feedback. + RECURSE(Visit(expr->expression())); + expr->RecordTypeFeedback(oracle(), zone()); Property* prop = expr->expression()->AsProperty(); if (prop != NULL) { prop->RecordTypeFeedback(oracle(), zone()); } - RECURSE(Visit(expr->expression())); - NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_)); - - VariableProxy* proxy = expr->expression()->AsVariableProxy(); - if (proxy != NULL && proxy->var()->IsStackAllocated()) { - store_.Seq(variable_index(proxy->var()), Effect(expr->bounds())); - } } void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { + RECURSE(Visit(expr->left())); + RECURSE(Visit(expr->right())); + // Collect type feedback. Handle<Type> type, left_type, right_type; Maybe<int> fixed_right_arg; @@ -554,29 +470,15 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { switch (expr->op()) { case Token::COMMA: - RECURSE(Visit(expr->left())); - RECURSE(Visit(expr->right())); NarrowType(expr, expr->right()->bounds()); break; case Token::OR: - case Token::AND: { - Effects left_effects = EnterEffects(); - RECURSE(Visit(expr->left())); - ExitEffects(); - Effects right_effects = EnterEffects(); - RECURSE(Visit(expr->right())); - ExitEffects(); - left_effects.Alt(right_effects); - store_.Seq(left_effects); - + case Token::AND: NarrowType(expr, Bounds::Either( expr->left()->bounds(), expr->right()->bounds(), isolate_)); break; - } case Token::BIT_OR: case Token::BIT_AND: { - RECURSE(Visit(expr->left())); - RECURSE(Visit(expr->right())); Type* upper = Type::Union( expr->left()->bounds().upper, expr->right()->bounds().upper); if (!upper->Is(Type::Signed32())) upper = Type::Signed32(); @@ -586,18 +488,12 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { case Token::BIT_XOR: case Token::SHL: case Token::SAR: - RECURSE(Visit(expr->left())); - RECURSE(Visit(expr->right())); NarrowType(expr, Bounds(Type::Smi(), Type::Signed32(), isolate_)); break; case Token::SHR: - RECURSE(Visit(expr->left())); - RECURSE(Visit(expr->right())); NarrowType(expr, Bounds(Type::Smi(), Type::Unsigned32(), isolate_)); break; case Token::ADD: { - RECURSE(Visit(expr->left())); - RECURSE(Visit(expr->right())); Bounds l = expr->left()->bounds(); Bounds r = expr->right()->bounds(); Type* lower = @@ -617,8 +513,6 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { case Token::MUL: case Token::DIV: case Token::MOD: - RECURSE(Visit(expr->left())); - RECURSE(Visit(expr->right())); NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_)); break; default: @@ -628,6 +522,9 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { void AstTyper::VisitCompareOperation(CompareOperation* expr) { + RECURSE(Visit(expr->left())); + RECURSE(Visit(expr->right())); + // Collect type feedback. Handle<Type> left_type, right_type, combined_type; oracle()->CompareType(expr->CompareOperationFeedbackId(), @@ -636,9 +533,6 @@ void AstTyper::VisitCompareOperation(CompareOperation* expr) { NarrowLowerType(expr->right(), right_type); expr->set_combined_type(combined_type); - RECURSE(Visit(expr->left())); - RECURSE(Visit(expr->right())); - NarrowType(expr, Bounds(Type::Boolean(), isolate_)); } |