LCOV - code coverage report
Current view: top level - src/crankshaft - typing.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 292 340 85.9 %
Date: 2017-04-26 Functions: 33 57 57.9 %

          Line data    Source code
       1             : // Copyright 2013 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/crankshaft/typing.h"
       6             : 
       7             : #include "src/ast/compile-time-value.h"
       8             : #include "src/ast/scopes.h"
       9             : #include "src/ast/variables.h"
      10             : #include "src/frames-inl.h"
      11             : #include "src/frames.h"
      12             : #include "src/ostreams.h"
      13             : #include "src/splay-tree-inl.h"
      14             : 
      15             : namespace v8 {
      16             : namespace internal {
      17             : 
      18      371311 : AstTyper::AstTyper(Isolate* isolate, Zone* zone, Handle<JSFunction> closure,
      19             :                    DeclarationScope* scope, BailoutId osr_ast_id,
      20             :                    FunctionLiteral* root, AstTypeBounds* bounds)
      21             :     : isolate_(isolate),
      22             :       zone_(zone),
      23             :       closure_(closure),
      24             :       scope_(scope),
      25             :       osr_ast_id_(osr_ast_id),
      26             :       root_(root),
      27             :       oracle_(isolate, zone, handle(closure->shared()->code()),
      28             :               handle(closure->feedback_vector()),
      29             :               handle(closure->context()->native_context())),
      30             :       store_(zone),
      31     1113933 :       bounds_(bounds) {
      32             :   InitializeAstVisitor(isolate);
      33      371311 : }
      34             : 
      35             : 
      36             : #ifdef OBJECT_PRINT
      37             : static void PrintObserved(Variable* var, Object* value, AstType* type) {
      38             :   OFStream os(stdout);
      39             :   os << "  observed " << (var->IsParameter() ? "param" : "local") << "  ";
      40             :   var->name()->Print(os);
      41             :   os << " : " << Brief(value) << " -> ";
      42             :   type->PrintTo(os);
      43             :   os << std::endl;
      44             :   }
      45             : #endif  // OBJECT_PRINT
      46             : 
      47             : 
      48       10897 : Effect AstTyper::ObservedOnStack(Object* value) {
      49       10897 :   AstType* lower = AstType::NowOf(value, zone());
      50           0 :   return Effect(AstBounds(lower, AstType::Any()));
      51             : }
      52             : 
      53             : 
      54       46508 : void AstTyper::ObserveTypesAtOsrEntry(IterationStatement* stmt) {
      55       90577 :   if (stmt->OsrEntryId() != osr_ast_id_) return;
      56             : 
      57             :   DisallowHeapAllocation no_gc;
      58        2439 :   JavaScriptFrameIterator it(isolate_);
      59             :   JavaScriptFrame* frame = it.frame();
      60             : 
      61             :   // Assert that the frame on the stack belongs to the function we want to OSR.
      62             :   DCHECK_EQ(*closure_, frame->function());
      63             : 
      64        2439 :   int params = scope_->num_parameters();
      65        2439 :   int locals = scope_->StackLocalCount();
      66             : 
      67             :   // Use sequential composition to achieve desired narrowing.
      68             :   // The receiver is a parameter with index -1.
      69        4878 :   store_.Seq(parameter_index(-1), ObservedOnStack(frame->receiver()));
      70        3790 :   for (int i = 0; i < params; i++) {
      71        2702 :     store_.Seq(parameter_index(i), ObservedOnStack(frame->GetParameter(i)));
      72             :   }
      73             : 
      74        7107 :   for (int i = 0; i < locals; i++) {
      75       14214 :     store_.Seq(stack_local_index(i), ObservedOnStack(frame->GetExpression(i)));
      76             :   }
      77             : 
      78             : #ifdef OBJECT_PRINT
      79             :   if (FLAG_trace_osr && FLAG_print_scopes) {
      80             :     PrintObserved(scope_->receiver(), frame->receiver(),
      81             :                   store_.LookupBounds(parameter_index(-1)).lower);
      82             : 
      83             :     for (int i = 0; i < params; i++) {
      84             :       PrintObserved(scope_->parameter(i), frame->GetParameter(i),
      85             :                     store_.LookupBounds(parameter_index(i)).lower);
      86             :     }
      87             : 
      88             :     int local_index = 0;
      89             :     for (Variable* var : *scope_->locals()) {
      90             :       if (var->IsStackLocal()) {
      91             :         PrintObserved(
      92             :             var, frame->GetExpression(local_index),
      93             :             store_.LookupBounds(stack_local_index(local_index)).lower);
      94             :         local_index++;
      95             :       }
      96             :     }
      97             :   }
      98             : #endif  // OBJECT_PRINT
      99             : }
     100             : 
     101             : 
     102             : #define RECURSE(call)                \
     103             :   do {                               \
     104             :     DCHECK(!HasStackOverflow());     \
     105             :     call;                            \
     106             :     if (HasStackOverflow()) return;  \
     107             :   } while (false)
     108             : 
     109             : 
     110      742622 : void AstTyper::Run() {
     111      742622 :   RECURSE(VisitDeclarations(scope_->declarations()));
     112      371311 :   RECURSE(VisitStatements(root_->body()));
     113             : }
     114             : 
     115             : 
     116     3162876 : void AstTyper::VisitStatements(ZoneList<Statement*>* stmts) {
     117     5538966 :   for (int i = 0; i < stmts->length(); ++i) {
     118     4841262 :     Statement* stmt = stmts->at(i);
     119     5234655 :     RECURSE(Visit(stmt));
     120     2071778 :     if (stmt->IsJump()) break;
     121             :   }
     122             : }
     123             : 
     124             : 
     125     1380206 : void AstTyper::VisitBlock(Block* stmt) {
     126     2070309 :   RECURSE(VisitStatements(stmt->statements()));
     127      690103 :   if (stmt->labels() != NULL) {
     128          85 :     store_.Forget();  // Control may transfer here via 'break l'.
     129             :   }
     130             : }
     131             : 
     132             : 
     133      916500 : void AstTyper::VisitExpressionStatement(ExpressionStatement* stmt) {
     134      916500 :   RECURSE(Visit(stmt->expression()));
     135             : }
     136             : 
     137             : 
     138           0 : void AstTyper::VisitEmptyStatement(EmptyStatement* stmt) {
     139           0 : }
     140             : 
     141             : 
     142         407 : void AstTyper::VisitSloppyBlockFunctionStatement(
     143         407 :     SloppyBlockFunctionStatement* stmt) {
     144         407 :   Visit(stmt->statement());
     145         407 : }
     146             : 
     147             : 
     148     3748250 : void AstTyper::VisitIfStatement(IfStatement* stmt) {
     149             :   // Collect type feedback.
     150      833021 :   if (!stmt->condition()->ToBooleanIsTrue() &&
     151      416494 :       !stmt->condition()->ToBooleanIsFalse()) {
     152      832134 :     stmt->condition()->RecordToBooleanTypeFeedback(oracle());
     153             :   }
     154             : 
     155      833054 :   RECURSE(Visit(stmt->condition()));
     156      416527 :   Effects then_effects = EnterEffects();
     157      833054 :   RECURSE(Visit(stmt->then_statement()));
     158             :   ExitEffects();
     159      416527 :   Effects else_effects = EnterEffects();
     160      833054 :   RECURSE(Visit(stmt->else_statement()));
     161             :   ExitEffects();
     162      416527 :   then_effects.Alt(else_effects);
     163             :   store_.Seq(then_effects);
     164             : }
     165             : 
     166             : 
     167           0 : void AstTyper::VisitContinueStatement(ContinueStatement* stmt) {
     168             :   // TODO(rossberg): is it worth having a non-termination effect?
     169           0 : }
     170             : 
     171             : 
     172           0 : void AstTyper::VisitBreakStatement(BreakStatement* stmt) {
     173             :   // TODO(rossberg): is it worth having a non-termination effect?
     174           0 : }
     175             : 
     176             : 
     177     1654458 : void AstTyper::VisitReturnStatement(ReturnStatement* stmt) {
     178             :   // Collect type feedback.
     179             :   // TODO(rossberg): we only need this for inlining into test contexts...
     180     1102972 :   stmt->expression()->RecordToBooleanTypeFeedback(oracle());
     181             : 
     182      551486 :   RECURSE(Visit(stmt->expression()));
     183             :   // TODO(rossberg): is it worth having a non-termination effect?
     184             : }
     185             : 
     186             : 
     187           0 : void AstTyper::VisitWithStatement(WithStatement* stmt) {
     188             :   RECURSE(stmt->expression());
     189             :   RECURSE(stmt->statement());
     190             : }
     191             : 
     192             : 
     193      100121 : void AstTyper::VisitSwitchStatement(SwitchStatement* stmt) {
     194        9232 :   RECURSE(Visit(stmt->tag()));
     195             : 
     196             :   ZoneList<CaseClause*>* clauses = stmt->cases();
     197             :   Effects local_effects(zone());
     198             :   bool complex_effects = false;  // True for label effects or fall-through.
     199             : 
     200       68598 :   for (int i = 0; i < clauses->length(); ++i) {
     201      123348 :     CaseClause* clause = clauses->at(i);
     202             : 
     203             :     Effects clause_effects = EnterEffects();
     204             : 
     205       29683 :     if (!clause->is_default()) {
     206       28295 :       Expression* label = clause->label();
     207             :       // Collect type feedback.
     208             :       AstType* tag_type;
     209             :       AstType* label_type;
     210             :       AstType* combined_type;
     211             :       oracle()->CompareType(clause->CompareId(),
     212             :                             clause->CompareOperationFeedbackSlot(), &tag_type,
     213       28295 :                             &label_type, &combined_type);
     214       56590 :       NarrowLowerType(stmt->tag(), tag_type);
     215       28295 :       NarrowLowerType(label, label_type);
     216       28295 :       clause->set_compare_type(combined_type);
     217             : 
     218       56590 :       RECURSE(Visit(label));
     219       28295 :       if (!clause_effects.IsEmpty()) complex_effects = true;
     220             :     }
     221             : 
     222             :     ZoneList<Statement*>* stmts = clause->statements();
     223       59366 :     RECURSE(VisitStatements(stmts));
     224             :     ExitEffects();
     225       52368 :     if (stmts->is_empty() || stmts->last()->IsJump()) {
     226       28820 :       local_effects.Alt(clause_effects);
     227             :     } else {
     228             :       complex_effects = true;
     229             :     }
     230             :   }
     231             : 
     232        4616 :   if (complex_effects) {
     233         607 :     store_.Forget();  // Reached this in unknown state.
     234             :   } else {
     235             :     store_.Seq(local_effects);
     236             :   }
     237             : }
     238             : 
     239             : 
     240           0 : void AstTyper::VisitCaseClause(CaseClause* clause) {
     241           0 :   UNREACHABLE();
     242             : }
     243             : 
     244             : 
     245        3050 : void AstTyper::VisitDoWhileStatement(DoWhileStatement* stmt) {
     246             :   // Collect type feedback.
     247         624 :   if (!stmt->cond()->ToBooleanIsTrue()) {
     248        1108 :     stmt->cond()->RecordToBooleanTypeFeedback(oracle());
     249             :   }
     250             : 
     251             :   // TODO(rossberg): refine the unconditional Forget (here and elsewhere) by
     252             :   // computing the set of variables assigned in only some of the origins of the
     253             :   // control transfer (such as the loop body here).
     254         624 :   store_.Forget();  // Control may transfer here via looping or 'continue'.
     255         624 :   ObserveTypesAtOsrEntry(stmt);
     256        1248 :   RECURSE(Visit(stmt->body()));
     257        1248 :   RECURSE(Visit(stmt->cond()));
     258         624 :   store_.Forget();  // Control may transfer here via 'break'.
     259             : }
     260             : 
     261             : 
     262       19738 : void AstTyper::VisitWhileStatement(WhileStatement* stmt) {
     263             :   // Collect type feedback.
     264        4279 :   if (!stmt->cond()->ToBooleanIsTrue()) {
     265        5244 :     stmt->cond()->RecordToBooleanTypeFeedback(oracle());
     266             :   }
     267             : 
     268        4279 :   store_.Forget();  // Control may transfer here via looping or 'continue'.
     269        8558 :   RECURSE(Visit(stmt->cond()));
     270        4279 :   ObserveTypesAtOsrEntry(stmt);
     271        8558 :   RECURSE(Visit(stmt->body()));
     272        4279 :   store_.Forget();  // Control may transfer here via termination or 'break'.
     273             : }
     274             : 
     275             : 
     276      355543 : void AstTyper::VisitForStatement(ForStatement* stmt) {
     277       40465 :   if (stmt->init() != NULL) {
     278       75482 :     RECURSE(Visit(stmt->init()));
     279             :   }
     280       40465 :   store_.Forget();  // Control may transfer here via looping.
     281       40465 :   if (stmt->cond() != NULL) {
     282             :     // Collect type feedback.
     283       39468 :     stmt->cond()->RecordToBooleanTypeFeedback(oracle());
     284             : 
     285       78936 :     RECURSE(Visit(stmt->cond()));
     286             :   }
     287       40465 :   ObserveTypesAtOsrEntry(stmt);
     288       80930 :   RECURSE(Visit(stmt->body()));
     289       40465 :   if (stmt->next() != NULL) {
     290       38503 :     store_.Forget();  // Control may transfer here via 'continue'.
     291       77006 :     RECURSE(Visit(stmt->next()));
     292             :   }
     293       40465 :   store_.Forget();  // Control may transfer here via termination or 'break'.
     294             : }
     295             : 
     296             : 
     297        3420 : void AstTyper::VisitForInStatement(ForInStatement* stmt) {
     298             :   // Collect type feedback.
     299             :   stmt->set_for_in_type(static_cast<ForInStatement::ForInType>(
     300        1140 :       oracle()->ForInType(stmt->ForInFeedbackSlot())));
     301             : 
     302        2280 :   RECURSE(Visit(stmt->enumerable()));
     303        1140 :   store_.Forget();  // Control may transfer here via looping or 'continue'.
     304        1140 :   ObserveTypesAtOsrEntry(stmt);
     305        2280 :   RECURSE(Visit(stmt->body()));
     306        1140 :   store_.Forget();  // Control may transfer here via 'break'.
     307             : }
     308             : 
     309           0 : void AstTyper::VisitForOfStatement(ForOfStatement* stmt) {}
     310             : 
     311           0 : void AstTyper::VisitTryCatchStatement(TryCatchStatement* stmt) {
     312           0 :   Effects try_effects = EnterEffects();
     313           0 :   RECURSE(Visit(stmt->try_block()));
     314             :   ExitEffects();
     315           0 :   Effects catch_effects = EnterEffects();
     316           0 :   store_.Forget();  // Control may transfer here via 'throw'.
     317           0 :   RECURSE(Visit(stmt->catch_block()));
     318             :   ExitEffects();
     319           0 :   try_effects.Alt(catch_effects);
     320             :   store_.Seq(try_effects);
     321             :   // At this point, only variables that were reassigned in the catch block are
     322             :   // still remembered.
     323             : }
     324             : 
     325             : 
     326           0 : void AstTyper::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
     327           0 :   RECURSE(Visit(stmt->try_block()));
     328           0 :   store_.Forget();  // Control may transfer here via 'throw'.
     329           0 :   RECURSE(Visit(stmt->finally_block()));
     330             : }
     331             : 
     332             : 
     333           0 : void AstTyper::VisitDebuggerStatement(DebuggerStatement* stmt) {
     334           0 :   store_.Forget();  // May do whatever.
     335           0 : }
     336             : 
     337             : 
     338           0 : void AstTyper::VisitFunctionLiteral(FunctionLiteral* expr) {}
     339             : 
     340             : 
     341           0 : void AstTyper::VisitClassLiteral(ClassLiteral* expr) {}
     342             : 
     343             : 
     344           0 : void AstTyper::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
     345           0 : }
     346             : 
     347             : 
     348         310 : void AstTyper::VisitDoExpression(DoExpression* expr) {
     349         124 :   RECURSE(VisitBlock(expr->block()));
     350         124 :   RECURSE(VisitVariableProxy(expr->result()));
     351          62 :   NarrowType(expr, bounds_->get(expr->result()));
     352             : }
     353             : 
     354             : 
     355       94270 : void AstTyper::VisitConditional(Conditional* expr) {
     356             :   // Collect type feedback.
     357       18854 :   expr->condition()->RecordToBooleanTypeFeedback(oracle());
     358             : 
     359       18854 :   RECURSE(Visit(expr->condition()));
     360        9427 :   Effects then_effects = EnterEffects();
     361       18854 :   RECURSE(Visit(expr->then_expression()));
     362             :   ExitEffects();
     363        9427 :   Effects else_effects = EnterEffects();
     364       18854 :   RECURSE(Visit(expr->else_expression()));
     365             :   ExitEffects();
     366        9427 :   then_effects.Alt(else_effects);
     367             :   store_.Seq(then_effects);
     368             : 
     369             :   NarrowType(expr,
     370             :              AstBounds::Either(bounds_->get(expr->then_expression()),
     371       18854 :                                bounds_->get(expr->else_expression()), zone()));
     372             : }
     373             : 
     374             : 
     375     3404978 : void AstTyper::VisitVariableProxy(VariableProxy* expr) {
     376             :   Variable* var = expr->var();
     377     3404978 :   if (var->IsStackAllocated()) {
     378     2589013 :     NarrowType(expr, store_.LookupBounds(variable_index(var)));
     379             :   }
     380     3404978 : }
     381             : 
     382             : 
     383     2779361 : void AstTyper::VisitLiteral(Literal* expr) {
     384             :   AstType* type = AstType::Constant(expr->value(), zone());
     385     2779361 :   NarrowType(expr, AstBounds(type));
     386     2779361 : }
     387             : 
     388             : 
     389           0 : void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) {
     390             :   // TODO(rossberg): Reintroduce RegExp type.
     391        8660 :   NarrowType(expr, AstBounds(AstType::Object()));
     392           0 : }
     393             : 
     394             : 
     395      200200 : void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) {
     396             :   ZoneList<ObjectLiteral::Property*>* properties = expr->properties();
     397      400400 :   for (int i = 0; i < properties->length(); ++i) {
     398      502658 :     ObjectLiteral::Property* prop = properties->at(i);
     399             : 
     400             :     // Collect type feedback.
     401      174533 :     if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL &&
     402      504810 :         !CompileTimeValue::IsCompileTimeValue(prop->value())) ||
     403             :         prop->kind() == ObjectLiteral::Property::COMPUTED) {
     404       50722 :       if (!prop->is_computed_name() &&
     405      101397 :           prop->key()->AsLiteral()->value()->IsInternalizedString() &&
     406       25314 :           prop->emit_store()) {
     407             :         // Record type feed back for the property.
     408       25290 :         FeedbackSlot slot = prop->GetSlot();
     409             :         SmallMapList maps;
     410       25290 :         oracle()->CollectReceiverTypes(slot, &maps);
     411             :         prop->set_receiver_type(maps.length() == 1 ? maps.at(0)
     412       25290 :                                                    : Handle<Map>::null());
     413             :       }
     414             :     }
     415             : 
     416      351830 :     RECURSE(Visit(prop->value()));
     417             :   }
     418             : 
     419       48570 :   NarrowType(expr, AstBounds(AstType::Object()));
     420             : }
     421             : 
     422             : 
     423      985755 : void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) {
     424             :   ZoneList<Expression*>* values = expr->values();
     425     1971510 :   for (int i = 0; i < values->length(); ++i) {
     426     1947124 :     Expression* value = values->at(i);
     427     1947124 :     RECURSE(Visit(value));
     428             :   }
     429             : 
     430       24386 :   NarrowType(expr, AstBounds(AstType::Object()));
     431             : }
     432             : 
     433             : 
     434     2550212 : void AstTyper::VisitAssignment(Assignment* expr) {
     435             :   // Collect type feedback.
     436      662168 :   Property* prop = expr->target()->AsProperty();
     437      630656 :   if (prop != NULL) {
     438       73045 :     FeedbackSlot slot = expr->AssignmentSlot();
     439       73045 :     expr->set_is_uninitialized(oracle()->StoreIsUninitialized(slot));
     440       73045 :     if (!expr->IsUninitialized()) {
     441       18243 :       SmallMapList* receiver_types = expr->GetReceiverTypes();
     442       18243 :       if (prop->key()->IsPropertyName()) {
     443       26538 :         Literal* lit_key = prop->key()->AsLiteral();
     444             :         DCHECK(lit_key != NULL && lit_key->value()->IsString());
     445             :         Handle<String> name = Handle<String>::cast(lit_key->value());
     446       13269 :         oracle()->AssignmentReceiverTypes(slot, name, receiver_types);
     447             :       } else {
     448             :         KeyedAccessStoreMode store_mode;
     449             :         IcCheckType key_type;
     450             :         oracle()->KeyedAssignmentReceiverTypes(slot, receiver_types,
     451        4974 :                                                &store_mode, &key_type);
     452        4974 :         expr->set_store_mode(store_mode);
     453        4974 :         expr->set_key_type(key_type);
     454             :       }
     455             :     }
     456             :   }
     457             : 
     458             :   Expression* rhs =
     459      630656 :       expr->is_compound() ? expr->binary_operation() : expr->value();
     460     1261312 :   RECURSE(Visit(expr->target()));
     461     1261312 :   RECURSE(Visit(rhs));
     462      630656 :   NarrowType(expr, bounds_->get(rhs));
     463             : 
     464     1687202 :   VariableProxy* proxy = expr->target()->AsVariableProxy();
     465     1188267 :   if (proxy != NULL && proxy->var()->IsStackAllocated()) {
     466      997870 :     store_.Seq(variable_index(proxy->var()), Effect(bounds_->get(expr)));
     467             :   }
     468             : }
     469             : 
     470           0 : void AstTyper::VisitSuspend(Suspend* expr) {
     471           0 :   RECURSE(Visit(expr->generator_object()));
     472           0 :   RECURSE(Visit(expr->expression()));
     473             : 
     474             :   // We don't know anything about the result type.
     475             : }
     476             : 
     477             : 
     478       14338 : void AstTyper::VisitThrow(Throw* expr) {
     479       21507 :   RECURSE(Visit(expr->exception()));
     480             :   // TODO(rossberg): is it worth having a non-termination effect?
     481             : 
     482        7169 :   NarrowType(expr, AstBounds(AstType::None()));
     483             : }
     484             : 
     485             : 
     486     3720134 : void AstTyper::VisitProperty(Property* expr) {
     487             :   // Collect type feedback.
     488      604009 :   FeedbackSlot slot = expr->PropertyFeedbackSlot();
     489      604009 :   expr->set_inline_cache_state(oracle()->LoadInlineCacheState(slot));
     490             : 
     491      604009 :   if (!expr->IsUninitialized()) {
     492      370123 :     if (expr->key()->IsPropertyName()) {
     493      659932 :       Literal* lit_key = expr->key()->AsLiteral();
     494             :       DCHECK(lit_key != NULL && lit_key->value()->IsString());
     495             :       Handle<String> name = Handle<String>::cast(lit_key->value());
     496      659932 :       oracle()->PropertyReceiverTypes(slot, name, expr->GetReceiverTypes());
     497             :     } else {
     498             :       bool is_string;
     499             :       IcCheckType key_type;
     500             :       oracle()->KeyedPropertyReceiverTypes(slot, expr->GetReceiverTypes(),
     501       40157 :                                            &is_string, &key_type);
     502       40157 :       expr->set_is_string_access(is_string);
     503       40157 :       expr->set_key_type(key_type);
     504             :     }
     505             :   }
     506             : 
     507     1208018 :   RECURSE(Visit(expr->obj()));
     508     1208018 :   RECURSE(Visit(expr->key()));
     509             : 
     510             :   // We don't know anything about the result type.
     511             : }
     512             : 
     513             : 
     514     4240427 : void AstTyper::VisitCall(Call* expr) {
     515             :   // Collect type feedback.
     516     1312224 :   RECURSE(Visit(expr->expression()));
     517      656112 :   FeedbackSlot slot = expr->CallFeedbackICSlot();
     518      656112 :   bool is_uninitialized = oracle()->CallIsUninitialized(slot);
     519      656112 :   if (!expr->expression()->IsProperty() && oracle()->CallIsMonomorphic(slot)) {
     520       73025 :     expr->set_target(oracle()->GetCallTarget(slot));
     521       73025 :     Handle<AllocationSite> site = oracle()->GetCallAllocationSite(slot);
     522             :     expr->set_allocation_site(site);
     523             :   }
     524             : 
     525             :   expr->set_is_uninitialized(is_uninitialized);
     526             : 
     527             :   ZoneList<Expression*>* args = expr->arguments();
     528     3231958 :   for (int i = 0; i < args->length(); ++i) {
     529     2575846 :     Expression* arg = args->at(i);
     530     1919734 :     RECURSE(Visit(arg));
     531             :   }
     532             : 
     533      656112 :   if (expr->is_possibly_eval()) {
     534           0 :     store_.Forget();  // Eval could do whatever to local variables.
     535             :   }
     536             : 
     537             :   // We don't know anything about the result type.
     538             : }
     539             : 
     540             : 
     541      168585 : void AstTyper::VisitCallNew(CallNew* expr) {
     542             :   // Collect type feedback.
     543       32299 :   FeedbackSlot allocation_site_feedback_slot = expr->CallNewFeedbackSlot();
     544             :   expr->set_allocation_site(
     545       32299 :       oracle()->GetCallNewAllocationSite(allocation_site_feedback_slot));
     546             :   bool monomorphic =
     547       32299 :       oracle()->CallNewIsMonomorphic(expr->CallNewFeedbackSlot());
     548             :   expr->set_is_monomorphic(monomorphic);
     549       32299 :   if (monomorphic) {
     550        5012 :     expr->set_target(oracle()->GetCallNewTarget(expr->CallNewFeedbackSlot()));
     551             :   }
     552             : 
     553       64598 :   RECURSE(Visit(expr->expression()));
     554             :   ZoneList<Expression*>* args = expr->arguments();
     555      143376 :   for (int i = 0; i < args->length(); ++i) {
     556      111077 :     Expression* arg = args->at(i);
     557       78778 :     RECURSE(Visit(arg));
     558             :   }
     559             : 
     560       32299 :   NarrowType(expr, AstBounds(AstType::None(), AstType::Receiver()));
     561             : }
     562             : 
     563             : 
     564      229244 : void AstTyper::VisitCallRuntime(CallRuntime* expr) {
     565             :   ZoneList<Expression*>* args = expr->arguments();
     566      458488 :   for (int i = 0; i < args->length(); ++i) {
     567      377902 :     Expression* arg = args->at(i);
     568      377902 :     RECURSE(Visit(arg));
     569             :   }
     570             : 
     571             :   // We don't know anything about the result type.
     572             : }
     573             : 
     574             : 
     575     1549359 : void AstTyper::VisitUnaryOperation(UnaryOperation* expr) {
     576             :   // Collect type feedback.
     577      333707 :   if (expr->op() == Token::NOT) {
     578             :     // TODO(rossberg): only do in test or value context.
     579      429062 :     expr->expression()->RecordToBooleanTypeFeedback(oracle());
     580             :   }
     581             : 
     582     1001121 :   RECURSE(Visit(expr->expression()));
     583             : 
     584      333707 :   switch (expr->op()) {
     585             :     case Token::NOT:
     586             :     case Token::DELETE:
     587      215880 :       NarrowType(expr, AstBounds(AstType::Boolean()));
     588      215880 :       break;
     589             :     case Token::VOID:
     590       11080 :       NarrowType(expr, AstBounds(AstType::Undefined()));
     591       11080 :       break;
     592             :     case Token::TYPEOF:
     593      106747 :       NarrowType(expr, AstBounds(AstType::InternalizedString()));
     594      106747 :       break;
     595             :     default:
     596           0 :       UNREACHABLE();
     597             :   }
     598             : }
     599             : 
     600             : 
     601      183924 : void AstTyper::VisitCountOperation(CountOperation* expr) {
     602             :   // Collect type feedback.
     603       45981 :   FeedbackSlot slot = expr->CountSlot();
     604             :   KeyedAccessStoreMode store_mode;
     605             :   IcCheckType key_type;
     606       45981 :   oracle()->GetStoreModeAndKeyType(slot, &store_mode, &key_type);
     607       45981 :   oracle()->CountReceiverTypes(slot, expr->GetReceiverTypes());
     608       45981 :   expr->set_store_mode(store_mode);
     609       45981 :   expr->set_key_type(key_type);
     610             :   expr->set_type(oracle()->CountType(expr->CountBinOpFeedbackId(),
     611       45981 :                                      expr->CountBinaryOpFeedbackSlot()));
     612             :   // TODO(rossberg): merge the count type with the generic expression type.
     613             : 
     614       91962 :   RECURSE(Visit(expr->expression()));
     615             : 
     616       45981 :   NarrowType(expr, AstBounds(AstType::SignedSmall(), AstType::Number()));
     617             : 
     618      128822 :   VariableProxy* proxy = expr->expression()->AsVariableProxy();
     619       90363 :   if (proxy != NULL && proxy->var()->IsStackAllocated()) {
     620       76918 :     store_.Seq(variable_index(proxy->var()), Effect(bounds_->get(expr)));
     621             :   }
     622             : }
     623             : 
     624     6006972 : void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
     625             :   // Collect type feedback.
     626             :   AstType* type;
     627             :   AstType* left_type;
     628             :   AstType* right_type;
     629     1023802 :   Maybe<int> fixed_right_arg = Nothing<int>();
     630             :   Handle<AllocationSite> allocation_site;
     631             :   oracle()->BinaryType(expr->BinaryOperationFeedbackId(),
     632             :                        expr->BinaryOperationFeedbackSlot(), &left_type,
     633             :                        &right_type, &type, &fixed_right_arg, &allocation_site,
     634      511901 :                        expr->op());
     635             : 
     636      511901 :   NarrowLowerType(expr, type);
     637     1023802 :   NarrowLowerType(expr->left(), left_type);
     638     1023802 :   NarrowLowerType(expr->right(), right_type);
     639             :   expr->set_allocation_site(allocation_site);
     640             :   expr->set_fixed_right_arg(fixed_right_arg);
     641      511901 :   if (expr->op() == Token::OR || expr->op() == Token::AND) {
     642      122994 :     expr->left()->RecordToBooleanTypeFeedback(oracle());
     643             :   }
     644             : 
     645      511901 :   switch (expr->op()) {
     646             :     case Token::COMMA:
     647       13503 :       RECURSE(Visit(expr->left()));
     648       13002 :       RECURSE(Visit(expr->right()));
     649        6501 :       NarrowType(expr, bounds_->get(expr->right()));
     650        6501 :       break;
     651             :     case Token::OR:
     652             :     case Token::AND: {
     653      122994 :       Effects left_effects = EnterEffects();
     654      245988 :       RECURSE(Visit(expr->left()));
     655             :       ExitEffects();
     656      122994 :       Effects right_effects = EnterEffects();
     657      245988 :       RECURSE(Visit(expr->right()));
     658             :       ExitEffects();
     659      122994 :       left_effects.Alt(right_effects);
     660             :       store_.Seq(left_effects);
     661             : 
     662             :       NarrowType(expr, AstBounds::Either(bounds_->get(expr->left()),
     663      245988 :                                          bounds_->get(expr->right()), zone()));
     664      122994 :       break;
     665             :     }
     666             :     case Token::BIT_OR:
     667             :     case Token::BIT_AND: {
     668       79862 :       RECURSE(Visit(expr->left()));
     669       79862 :       RECURSE(Visit(expr->right()));
     670             :       AstType* upper =
     671       39931 :           AstType::Union(bounds_->get(expr->left()).upper,
     672       79862 :                          bounds_->get(expr->right()).upper, zone());
     673       39931 :       if (!upper->Is(AstType::Signed32())) upper = AstType::Signed32();
     674             :       AstType* lower =
     675       39931 :           AstType::Intersect(AstType::SignedSmall(), upper, zone());
     676       39931 :       NarrowType(expr, AstBounds(lower, upper));
     677       39931 :       break;
     678             :     }
     679             :     case Token::BIT_XOR:
     680             :     case Token::SHL:
     681             :     case Token::SAR:
     682       50952 :       RECURSE(Visit(expr->left()));
     683       50952 :       RECURSE(Visit(expr->right()));
     684       25476 :       NarrowType(expr, AstBounds(AstType::SignedSmall(), AstType::Signed32()));
     685       25476 :       break;
     686             :     case Token::SHR:
     687       15824 :       RECURSE(Visit(expr->left()));
     688       15824 :       RECURSE(Visit(expr->right()));
     689             :       // TODO(rossberg): The upper bound would be Unsigned32, but since there
     690             :       // is no 'positive Smi' type for the lower bound, we use the smallest
     691             :       // union of Smi and Unsigned32 as upper bound instead.
     692        7912 :       NarrowType(expr, AstBounds(AstType::SignedSmall(), AstType::Number()));
     693        7912 :       break;
     694             :     case Token::ADD: {
     695      394690 :       RECURSE(Visit(expr->left()));
     696      393688 :       RECURSE(Visit(expr->right()));
     697      196844 :       AstBounds l = bounds_->get(expr->left());
     698      196844 :       AstBounds r = bounds_->get(expr->right());
     699             :       AstType* lower =
     700      370222 :           !l.lower->IsInhabited() || !r.lower->IsInhabited()
     701             :               ? AstType::None()
     702      141629 :               : l.lower->Is(AstType::String()) || r.lower->Is(AstType::String())
     703             :                     ? AstType::String()
     704      140655 :                     : l.lower->Is(AstType::Number()) &&
     705             :                               r.lower->Is(AstType::Number())
     706             :                           ? AstType::SignedSmall()
     707      643657 :                           : AstType::None();
     708             :       AstType* upper =
     709      157594 :           l.upper->Is(AstType::String()) || r.upper->Is(AstType::String())
     710             :               ? AstType::String()
     711       31789 :               : l.upper->Is(AstType::Number()) && r.upper->Is(AstType::Number())
     712             :                     ? AstType::Number()
     713      349979 :                     : AstType::NumberOrString();
     714      196844 :       NarrowType(expr, AstBounds(lower, upper));
     715             :       break;
     716             :     }
     717             :     case Token::SUB:
     718             :     case Token::MUL:
     719             :     case Token::DIV:
     720             :     case Token::MOD:
     721      223484 :       RECURSE(Visit(expr->left()));
     722      223484 :       RECURSE(Visit(expr->right()));
     723      111742 :       NarrowType(expr, AstBounds(AstType::SignedSmall(), AstType::Number()));
     724      111742 :       break;
     725             :     default:
     726           0 :       UNREACHABLE();
     727             :   }
     728             : }
     729             : 
     730             : 
     731     3547019 : void AstTyper::VisitCompareOperation(CompareOperation* expr) {
     732             :   // Collect type feedback.
     733             :   AstType* left_type;
     734             :   AstType* right_type;
     735             :   AstType* combined_type;
     736             :   oracle()->CompareType(expr->CompareOperationFeedbackId(),
     737             :                         expr->CompareOperationFeedbackSlot(), &left_type,
     738      506717 :                         &right_type, &combined_type);
     739     1013434 :   NarrowLowerType(expr->left(), left_type);
     740     1013434 :   NarrowLowerType(expr->right(), right_type);
     741      506717 :   expr->set_combined_type(combined_type);
     742             : 
     743     1013434 :   RECURSE(Visit(expr->left()));
     744     1013434 :   RECURSE(Visit(expr->right()));
     745             : 
     746      506717 :   NarrowType(expr, AstBounds(AstType::Boolean()));
     747             : }
     748             : 
     749             : 
     750           0 : void AstTyper::VisitSpread(Spread* expr) { UNREACHABLE(); }
     751             : 
     752             : 
     753           0 : void AstTyper::VisitEmptyParentheses(EmptyParentheses* expr) {
     754           0 :   UNREACHABLE();
     755             : }
     756             : 
     757           0 : void AstTyper::VisitGetIterator(GetIterator* expr) { UNREACHABLE(); }
     758             : 
     759           0 : void AstTyper::VisitImportCallExpression(ImportCallExpression* expr) {
     760           0 :   UNREACHABLE();
     761             : }
     762             : 
     763           0 : void AstTyper::VisitThisFunction(ThisFunction* expr) {}
     764             : 
     765             : 
     766           0 : void AstTyper::VisitSuperPropertyReference(SuperPropertyReference* expr) {}
     767             : 
     768             : 
     769           0 : void AstTyper::VisitSuperCallReference(SuperCallReference* expr) {}
     770             : 
     771             : 
     772           8 : void AstTyper::VisitRewritableExpression(RewritableExpression* expr) {
     773           8 :   Visit(expr->expression());
     774           8 : }
     775             : 
     776     3126407 : int AstTyper::variable_index(Variable* var) {
     777             :   // Stack locals have the range [0 .. l]
     778             :   // Parameters have the range [-1 .. p]
     779             :   // We map this to [-p-2 .. -1, 0 .. l]
     780             :   return var->IsStackLocal()
     781             :              ? stack_local_index(var->index())
     782     4414604 :              : var->IsParameter() ? parameter_index(var->index()) : kNoVar;
     783             : }
     784             : 
     785      828339 : void AstTyper::VisitDeclarations(Declaration::List* decls) {
     786     1199650 :   for (Declaration* decl : *decls) {
     787     1285367 :     RECURSE(Visit(decl));
     788             :   }
     789             : }
     790             : 
     791             : 
     792           0 : void AstTyper::VisitVariableDeclaration(VariableDeclaration* declaration) {
     793           0 : }
     794             : 
     795             : 
     796       33827 : void AstTyper::VisitFunctionDeclaration(FunctionDeclaration* declaration) {
     797       33827 :   RECURSE(Visit(declaration->fun()));
     798             : }
     799             : 
     800             : 
     801             : }  // namespace internal
     802             : }  // namespace v8

Generated by: LCOV version 1.10