| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 if (switch_type == SwitchStatement::UNKNOWN_SWITCH) | 193 if (switch_type == SwitchStatement::UNKNOWN_SWITCH) |
| 194 switch_type = SwitchStatement::GENERIC_SWITCH; | 194 switch_type = SwitchStatement::GENERIC_SWITCH; |
| 195 stmt->set_switch_type(switch_type); | 195 stmt->set_switch_type(switch_type); |
| 196 | 196 |
| 197 // Collect type feedback. | 197 // Collect type feedback. |
| 198 // TODO(rossberg): can we eliminate this special case and extra loop? | 198 // TODO(rossberg): can we eliminate this special case and extra loop? |
| 199 if (switch_type == SwitchStatement::SMI_SWITCH) { | 199 if (switch_type == SwitchStatement::SMI_SWITCH) { |
| 200 for (int i = 0; i < clauses->length(); ++i) { | 200 for (int i = 0; i < clauses->length(); ++i) { |
| 201 CaseClause* clause = clauses->at(i); | 201 CaseClause* clause = clauses->at(i); |
| 202 if (!clause->is_default()) | 202 if (!clause->is_default()) |
| 203 clause->RecordTypeFeedback(oracle()); | 203 clause->set_compare_type(oracle()->ClauseType(clause->CompareId())); |
| 204 } | 204 } |
| 205 } | 205 } |
| 206 } | 206 } |
| 207 | 207 |
| 208 | 208 |
| 209 void AstTyper::VisitCaseClause(CaseClause* clause) { | 209 void AstTyper::VisitCaseClause(CaseClause* clause) { |
| 210 UNREACHABLE(); | 210 UNREACHABLE(); |
| 211 } | 211 } |
| 212 | 212 |
| 213 | 213 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 if (stmt->next() != NULL) { | 255 if (stmt->next() != NULL) { |
| 256 store_.Forget(); // Control may transfer here via 'continue'. | 256 store_.Forget(); // Control may transfer here via 'continue'. |
| 257 RECURSE(Visit(stmt->next())); | 257 RECURSE(Visit(stmt->next())); |
| 258 } | 258 } |
| 259 store_.Forget(); // Control may transfer here via termination or 'break'. | 259 store_.Forget(); // Control may transfer here via termination or 'break'. |
| 260 } | 260 } |
| 261 | 261 |
| 262 | 262 |
| 263 void AstTyper::VisitForInStatement(ForInStatement* stmt) { | 263 void AstTyper::VisitForInStatement(ForInStatement* stmt) { |
| 264 // Collect type feedback. | 264 // Collect type feedback. |
| 265 stmt->RecordTypeFeedback(oracle()); | 265 stmt->set_for_in_type(static_cast<ForInStatement::ForInType>( |
| 266 oracle()->ForInType(stmt->ForInFeedbackId()))); |
| 266 | 267 |
| 267 RECURSE(Visit(stmt->enumerable())); | 268 RECURSE(Visit(stmt->enumerable())); |
| 268 store_.Forget(); // Control may transfer here via looping or 'continue'. | 269 store_.Forget(); // Control may transfer here via looping or 'continue'. |
| 269 RECURSE(Visit(stmt->body())); | 270 RECURSE(Visit(stmt->body())); |
| 270 store_.Forget(); // Control may transfer here via 'break'. | 271 store_.Forget(); // Control may transfer here via 'break'. |
| 271 } | 272 } |
| 272 | 273 |
| 273 | 274 |
| 274 void AstTyper::VisitForOfStatement(ForOfStatement* stmt) { | 275 void AstTyper::VisitForOfStatement(ForOfStatement* stmt) { |
| 275 RECURSE(Visit(stmt->iterable())); | 276 RECURSE(Visit(stmt->iterable())); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 for (int i = 0; i < values->length(); ++i) { | 380 for (int i = 0; i < values->length(); ++i) { |
| 380 Expression* value = values->at(i); | 381 Expression* value = values->at(i); |
| 381 RECURSE(Visit(value)); | 382 RECURSE(Visit(value)); |
| 382 } | 383 } |
| 383 | 384 |
| 384 NarrowType(expr, Bounds(Type::Array(), isolate_)); | 385 NarrowType(expr, Bounds(Type::Array(), isolate_)); |
| 385 } | 386 } |
| 386 | 387 |
| 387 | 388 |
| 388 void AstTyper::VisitAssignment(Assignment* expr) { | 389 void AstTyper::VisitAssignment(Assignment* expr) { |
| 389 // TODO(rossberg): Can we clean this up? | 390 // Collect type feedback. |
| 390 if (expr->is_compound()) { | 391 Property* prop = expr->target()->AsProperty(); |
| 391 // Collect type feedback. | 392 if (prop != NULL) { |
| 392 Expression* target = expr->target(); | 393 TypeFeedbackId id = expr->AssignmentFeedbackId(); |
| 393 Property* prop = target->AsProperty(); | 394 expr->set_is_uninitialized(oracle()->StoreIsUninitialized(id)); |
| 394 if (prop != NULL) { | 395 if (!expr->IsUninitialized()) { |
| 395 prop->RecordTypeFeedback(oracle(), zone()); | 396 expr->set_is_pre_monomorphic(oracle()->StoreIsPreMonomorphic(id)); |
| 396 expr->RecordTypeFeedback(oracle(), zone()); | 397 expr->set_is_monomorphic(oracle()->StoreIsMonomorphicNormal(id)); |
| 398 ASSERT(!expr->IsPreMonomorphic() || !expr->IsMonomorphic()); |
| 399 if (prop->key()->IsPropertyName()) { |
| 400 Literal* lit_key = prop->key()->AsLiteral(); |
| 401 ASSERT(lit_key != NULL && lit_key->value()->IsString()); |
| 402 Handle<String> name = Handle<String>::cast(lit_key->value()); |
| 403 oracle()->AssignmentReceiverTypes(id, name, expr->GetReceiverTypes()); |
| 404 } else { |
| 405 KeyedAccessStoreMode store_mode; |
| 406 oracle()->KeyedAssignmentReceiverTypes( |
| 407 id, expr->GetReceiverTypes(), &store_mode); |
| 408 expr->set_store_mode(store_mode); |
| 409 } |
| 397 } | 410 } |
| 411 } |
| 398 | 412 |
| 399 RECURSE(Visit(expr->binary_operation())); | 413 Expression* rhs = |
| 400 | 414 expr->is_compound() ? expr->binary_operation() : expr->value(); |
| 401 NarrowType(expr, expr->binary_operation()->bounds()); | 415 RECURSE(Visit(expr->target())); |
| 402 } else { | 416 RECURSE(Visit(rhs)); |
| 403 // Collect type feedback. | 417 NarrowType(expr, rhs->bounds()); |
| 404 if (expr->target()->IsProperty()) { | |
| 405 expr->RecordTypeFeedback(oracle(), zone()); | |
| 406 } | |
| 407 | |
| 408 RECURSE(Visit(expr->target())); | |
| 409 RECURSE(Visit(expr->value())); | |
| 410 | |
| 411 NarrowType(expr, expr->value()->bounds()); | |
| 412 } | |
| 413 | 418 |
| 414 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 419 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
| 415 if (proxy != NULL && proxy->var()->IsStackAllocated()) { | 420 if (proxy != NULL && proxy->var()->IsStackAllocated()) { |
| 416 store_.Seq(variable_index(proxy->var()), Effect(expr->bounds())); | 421 store_.Seq(variable_index(proxy->var()), Effect(expr->bounds())); |
| 417 } | 422 } |
| 418 } | 423 } |
| 419 | 424 |
| 420 | 425 |
| 421 void AstTyper::VisitYield(Yield* expr) { | 426 void AstTyper::VisitYield(Yield* expr) { |
| 422 RECURSE(Visit(expr->generator_object())); | 427 RECURSE(Visit(expr->generator_object())); |
| 423 RECURSE(Visit(expr->expression())); | 428 RECURSE(Visit(expr->expression())); |
| 424 | 429 |
| 425 // We don't know anything about the result type. | 430 // We don't know anything about the result type. |
| 426 } | 431 } |
| 427 | 432 |
| 428 | 433 |
| 429 void AstTyper::VisitThrow(Throw* expr) { | 434 void AstTyper::VisitThrow(Throw* expr) { |
| 430 RECURSE(Visit(expr->exception())); | 435 RECURSE(Visit(expr->exception())); |
| 431 // TODO(rossberg): is it worth having a non-termination effect? | 436 // TODO(rossberg): is it worth having a non-termination effect? |
| 432 | 437 |
| 433 NarrowType(expr, Bounds(Type::None(), isolate_)); | 438 NarrowType(expr, Bounds(Type::None(), isolate_)); |
| 434 } | 439 } |
| 435 | 440 |
| 436 | 441 |
| 437 void AstTyper::VisitProperty(Property* expr) { | 442 void AstTyper::VisitProperty(Property* expr) { |
| 438 // Collect type feedback. | 443 // Collect type feedback. |
| 439 expr->RecordTypeFeedback(oracle(), zone()); | 444 TypeFeedbackId id = expr->PropertyFeedbackId(); |
| 445 expr->set_is_uninitialized(oracle()->LoadIsUninitialized(id)); |
| 446 if (!expr->IsUninitialized()) { |
| 447 expr->set_is_pre_monomorphic(oracle()->LoadIsPreMonomorphic(id)); |
| 448 expr->set_is_monomorphic(oracle()->LoadIsMonomorphicNormal(id)); |
| 449 ASSERT(!expr->IsPreMonomorphic() || !expr->IsMonomorphic()); |
| 450 if (expr->key()->IsPropertyName()) { |
| 451 Literal* lit_key = expr->key()->AsLiteral(); |
| 452 ASSERT(lit_key != NULL && lit_key->value()->IsString()); |
| 453 Handle<String> name = Handle<String>::cast(lit_key->value()); |
| 454 bool is_prototype; |
| 455 oracle()->PropertyReceiverTypes( |
| 456 id, name, expr->GetReceiverTypes(), &is_prototype); |
| 457 expr->set_is_function_prototype(is_prototype); |
| 458 } else { |
| 459 bool is_string; |
| 460 oracle()->KeyedPropertyReceiverTypes( |
| 461 id, expr->GetReceiverTypes(), &is_string); |
| 462 expr->set_is_string_access(is_string); |
| 463 } |
| 464 } |
| 440 | 465 |
| 441 RECURSE(Visit(expr->obj())); | 466 RECURSE(Visit(expr->obj())); |
| 442 RECURSE(Visit(expr->key())); | 467 RECURSE(Visit(expr->key())); |
| 443 | 468 |
| 444 // We don't know anything about the result type. | 469 // We don't know anything about the result type. |
| 445 } | 470 } |
| 446 | 471 |
| 447 | 472 |
| 448 void AstTyper::VisitCall(Call* expr) { | 473 void AstTyper::VisitCall(Call* expr) { |
| 449 // Collect type feedback. | 474 // Collect type feedback. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 NarrowType(expr, Bounds(Type::InternalizedString(), isolate_)); | 543 NarrowType(expr, Bounds(Type::InternalizedString(), isolate_)); |
| 519 break; | 544 break; |
| 520 default: | 545 default: |
| 521 UNREACHABLE(); | 546 UNREACHABLE(); |
| 522 } | 547 } |
| 523 } | 548 } |
| 524 | 549 |
| 525 | 550 |
| 526 void AstTyper::VisitCountOperation(CountOperation* expr) { | 551 void AstTyper::VisitCountOperation(CountOperation* expr) { |
| 527 // Collect type feedback. | 552 // Collect type feedback. |
| 528 expr->RecordTypeFeedback(oracle(), zone()); | 553 TypeFeedbackId store_id = expr->CountStoreFeedbackId(); |
| 529 Property* prop = expr->expression()->AsProperty(); | 554 expr->set_is_monomorphic(oracle()->StoreIsMonomorphicNormal(store_id)); |
| 530 if (prop != NULL) { | 555 expr->set_store_mode(oracle()->GetStoreMode(store_id)); |
| 531 prop->RecordTypeFeedback(oracle(), zone()); | 556 oracle()->CountReceiverTypes(store_id, expr->GetReceiverTypes()); |
| 532 } | 557 expr->set_type(oracle()->CountType(expr->CountBinOpFeedbackId())); |
| 558 // TODO(rossberg): merge the count type with the generic expression type. |
| 533 | 559 |
| 534 RECURSE(Visit(expr->expression())); | 560 RECURSE(Visit(expr->expression())); |
| 535 | 561 |
| 536 NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_)); | 562 NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_)); |
| 537 | 563 |
| 538 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 564 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 539 if (proxy != NULL && proxy->var()->IsStackAllocated()) { | 565 if (proxy != NULL && proxy->var()->IsStackAllocated()) { |
| 540 store_.Seq(variable_index(proxy->var()), Effect(expr->bounds())); | 566 store_.Seq(variable_index(proxy->var()), Effect(expr->bounds())); |
| 541 } | 567 } |
| 542 } | 568 } |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 709 void AstTyper::VisitModuleUrl(ModuleUrl* module) { | 735 void AstTyper::VisitModuleUrl(ModuleUrl* module) { |
| 710 } | 736 } |
| 711 | 737 |
| 712 | 738 |
| 713 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) { | 739 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) { |
| 714 RECURSE(Visit(stmt->body())); | 740 RECURSE(Visit(stmt->body())); |
| 715 } | 741 } |
| 716 | 742 |
| 717 | 743 |
| 718 } } // namespace v8::internal | 744 } } // namespace v8::internal |
| OLD | NEW |