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 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 | 337 |
338 void AstTyper::VisitVariableProxy(VariableProxy* expr) { | 338 void AstTyper::VisitVariableProxy(VariableProxy* expr) { |
339 Variable* var = expr->var(); | 339 Variable* var = expr->var(); |
340 if (var->IsStackAllocated()) { | 340 if (var->IsStackAllocated()) { |
341 NarrowType(expr, store_.LookupBounds(variable_index(var))); | 341 NarrowType(expr, store_.LookupBounds(variable_index(var))); |
342 } | 342 } |
343 } | 343 } |
344 | 344 |
345 | 345 |
346 void AstTyper::VisitLiteral(Literal* expr) { | 346 void AstTyper::VisitLiteral(Literal* expr) { |
347 Type* type = Type::Constant(expr->value(), isolate_); | 347 Handle<Type> type = Type::Constant(expr->value(), isolate_); |
348 NarrowType(expr, Bounds(type, isolate_)); | 348 NarrowType(expr, Bounds(type)); |
349 } | 349 } |
350 | 350 |
351 | 351 |
352 void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) { | 352 void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) { |
353 NarrowType(expr, Bounds(Type::RegExp(), isolate_)); | 353 NarrowType(expr, Bounds(Type::RegExp(isolate_))); |
354 } | 354 } |
355 | 355 |
356 | 356 |
357 void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) { | 357 void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) { |
358 ZoneList<ObjectLiteral::Property*>* properties = expr->properties(); | 358 ZoneList<ObjectLiteral::Property*>* properties = expr->properties(); |
359 for (int i = 0; i < properties->length(); ++i) { | 359 for (int i = 0; i < properties->length(); ++i) { |
360 ObjectLiteral::Property* prop = properties->at(i); | 360 ObjectLiteral::Property* prop = properties->at(i); |
361 | 361 |
362 // Collect type feedback. | 362 // Collect type feedback. |
363 if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL && | 363 if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL && |
364 !CompileTimeValue::IsCompileTimeValue(prop->value())) || | 364 !CompileTimeValue::IsCompileTimeValue(prop->value())) || |
365 prop->kind() == ObjectLiteral::Property::COMPUTED) { | 365 prop->kind() == ObjectLiteral::Property::COMPUTED) { |
366 if (prop->key()->value()->IsInternalizedString() && prop->emit_store()) { | 366 if (prop->key()->value()->IsInternalizedString() && prop->emit_store()) { |
367 prop->RecordTypeFeedback(oracle()); | 367 prop->RecordTypeFeedback(oracle()); |
368 } | 368 } |
369 } | 369 } |
370 | 370 |
371 RECURSE(Visit(prop->value())); | 371 RECURSE(Visit(prop->value())); |
372 } | 372 } |
373 | 373 |
374 NarrowType(expr, Bounds(Type::Object(), isolate_)); | 374 NarrowType(expr, Bounds(Type::Object(isolate_))); |
375 } | 375 } |
376 | 376 |
377 | 377 |
378 void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) { | 378 void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) { |
379 ZoneList<Expression*>* values = expr->values(); | 379 ZoneList<Expression*>* values = expr->values(); |
380 for (int i = 0; i < values->length(); ++i) { | 380 for (int i = 0; i < values->length(); ++i) { |
381 Expression* value = values->at(i); | 381 Expression* value = values->at(i); |
382 RECURSE(Visit(value)); | 382 RECURSE(Visit(value)); |
383 } | 383 } |
384 | 384 |
385 NarrowType(expr, Bounds(Type::Array(), isolate_)); | 385 NarrowType(expr, Bounds(Type::Array(isolate_))); |
386 } | 386 } |
387 | 387 |
388 | 388 |
389 void AstTyper::VisitAssignment(Assignment* expr) { | 389 void AstTyper::VisitAssignment(Assignment* expr) { |
390 // Collect type feedback. | 390 // Collect type feedback. |
391 Property* prop = expr->target()->AsProperty(); | 391 Property* prop = expr->target()->AsProperty(); |
392 if (prop != NULL) { | 392 if (prop != NULL) { |
393 TypeFeedbackId id = expr->AssignmentFeedbackId(); | 393 TypeFeedbackId id = expr->AssignmentFeedbackId(); |
394 expr->set_is_uninitialized(oracle()->StoreIsUninitialized(id)); | 394 expr->set_is_uninitialized(oracle()->StoreIsUninitialized(id)); |
395 if (!expr->IsUninitialized()) { | 395 if (!expr->IsUninitialized()) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 RECURSE(Visit(expr->expression())); | 428 RECURSE(Visit(expr->expression())); |
429 | 429 |
430 // We don't know anything about the result type. | 430 // We don't know anything about the result type. |
431 } | 431 } |
432 | 432 |
433 | 433 |
434 void AstTyper::VisitThrow(Throw* expr) { | 434 void AstTyper::VisitThrow(Throw* expr) { |
435 RECURSE(Visit(expr->exception())); | 435 RECURSE(Visit(expr->exception())); |
436 // TODO(rossberg): is it worth having a non-termination effect? | 436 // TODO(rossberg): is it worth having a non-termination effect? |
437 | 437 |
438 NarrowType(expr, Bounds(Type::None(), isolate_)); | 438 NarrowType(expr, Bounds(Type::None(isolate_))); |
439 } | 439 } |
440 | 440 |
441 | 441 |
442 void AstTyper::VisitProperty(Property* expr) { | 442 void AstTyper::VisitProperty(Property* expr) { |
443 // Collect type feedback. | 443 // Collect type feedback. |
444 TypeFeedbackId id = expr->PropertyFeedbackId(); | 444 TypeFeedbackId id = expr->PropertyFeedbackId(); |
445 expr->set_is_uninitialized(oracle()->LoadIsUninitialized(id)); | 445 expr->set_is_uninitialized(oracle()->LoadIsUninitialized(id)); |
446 if (!expr->IsUninitialized()) { | 446 if (!expr->IsUninitialized()) { |
447 expr->set_is_pre_monomorphic(oracle()->LoadIsPreMonomorphic(id)); | 447 expr->set_is_pre_monomorphic(oracle()->LoadIsPreMonomorphic(id)); |
448 expr->set_is_monomorphic(oracle()->LoadIsMonomorphicNormal(id)); | 448 expr->set_is_monomorphic(oracle()->LoadIsMonomorphicNormal(id)); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 if (expr->op() == Token::NOT) { | 527 if (expr->op() == Token::NOT) { |
528 // TODO(rossberg): only do in test or value context. | 528 // TODO(rossberg): only do in test or value context. |
529 expr->expression()->RecordToBooleanTypeFeedback(oracle()); | 529 expr->expression()->RecordToBooleanTypeFeedback(oracle()); |
530 } | 530 } |
531 | 531 |
532 RECURSE(Visit(expr->expression())); | 532 RECURSE(Visit(expr->expression())); |
533 | 533 |
534 switch (expr->op()) { | 534 switch (expr->op()) { |
535 case Token::NOT: | 535 case Token::NOT: |
536 case Token::DELETE: | 536 case Token::DELETE: |
537 NarrowType(expr, Bounds(Type::Boolean(), isolate_)); | 537 NarrowType(expr, Bounds(Type::Boolean(isolate_))); |
538 break; | 538 break; |
539 case Token::VOID: | 539 case Token::VOID: |
540 NarrowType(expr, Bounds(Type::Undefined(), isolate_)); | 540 NarrowType(expr, Bounds(Type::Undefined(isolate_))); |
541 break; | 541 break; |
542 case Token::TYPEOF: | 542 case Token::TYPEOF: |
543 NarrowType(expr, Bounds(Type::InternalizedString(), isolate_)); | 543 NarrowType(expr, Bounds(Type::InternalizedString(isolate_))); |
544 break; | 544 break; |
545 default: | 545 default: |
546 UNREACHABLE(); | 546 UNREACHABLE(); |
547 } | 547 } |
548 } | 548 } |
549 | 549 |
550 | 550 |
551 void AstTyper::VisitCountOperation(CountOperation* expr) { | 551 void AstTyper::VisitCountOperation(CountOperation* expr) { |
552 // Collect type feedback. | 552 // Collect type feedback. |
553 TypeFeedbackId store_id = expr->CountStoreFeedbackId(); | 553 TypeFeedbackId store_id = expr->CountStoreFeedbackId(); |
554 expr->set_is_monomorphic(oracle()->StoreIsMonomorphicNormal(store_id)); | 554 expr->set_is_monomorphic(oracle()->StoreIsMonomorphicNormal(store_id)); |
555 expr->set_store_mode(oracle()->GetStoreMode(store_id)); | 555 expr->set_store_mode(oracle()->GetStoreMode(store_id)); |
556 oracle()->CountReceiverTypes(store_id, expr->GetReceiverTypes()); | 556 oracle()->CountReceiverTypes(store_id, expr->GetReceiverTypes()); |
557 expr->set_type(oracle()->CountType(expr->CountBinOpFeedbackId())); | 557 expr->set_type(oracle()->CountType(expr->CountBinOpFeedbackId())); |
558 // TODO(rossberg): merge the count type with the generic expression type. | 558 // TODO(rossberg): merge the count type with the generic expression type. |
559 | 559 |
560 RECURSE(Visit(expr->expression())); | 560 RECURSE(Visit(expr->expression())); |
561 | 561 |
562 NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_)); | 562 NarrowType(expr, Bounds(Type::Smi(isolate_), Type::Number(isolate_))); |
563 | 563 |
564 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 564 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
565 if (proxy != NULL && proxy->var()->IsStackAllocated()) { | 565 if (proxy != NULL && proxy->var()->IsStackAllocated()) { |
566 store_.Seq(variable_index(proxy->var()), Effect(expr->bounds())); | 566 store_.Seq(variable_index(proxy->var()), Effect(expr->bounds())); |
567 } | 567 } |
568 } | 568 } |
569 | 569 |
570 | 570 |
571 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { | 571 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { |
572 // Collect type feedback. | 572 // Collect type feedback. |
(...skipping 27 matching lines...) Expand all Loading... |
600 store_.Seq(left_effects); | 600 store_.Seq(left_effects); |
601 | 601 |
602 NarrowType(expr, Bounds::Either( | 602 NarrowType(expr, Bounds::Either( |
603 expr->left()->bounds(), expr->right()->bounds(), isolate_)); | 603 expr->left()->bounds(), expr->right()->bounds(), isolate_)); |
604 break; | 604 break; |
605 } | 605 } |
606 case Token::BIT_OR: | 606 case Token::BIT_OR: |
607 case Token::BIT_AND: { | 607 case Token::BIT_AND: { |
608 RECURSE(Visit(expr->left())); | 608 RECURSE(Visit(expr->left())); |
609 RECURSE(Visit(expr->right())); | 609 RECURSE(Visit(expr->right())); |
610 Handle<Type> upper( | 610 Handle<Type> upper = Type::Union( |
611 Type::Union( | 611 expr->left()->bounds().upper, expr->right()->bounds().upper, |
612 expr->left()->bounds().upper, expr->right()->bounds().upper), | |
613 isolate_); | 612 isolate_); |
614 if (!upper->Is(Type::Signed32())) | 613 if (!upper->Is(Type::Signed32())) |
615 upper = handle(Type::Signed32(), isolate_); | 614 upper = Type::Signed32(isolate_); |
616 Handle<Type> lower(Type::Intersect( | 615 Handle<Type> lower = |
617 handle(Type::Smi(), isolate_), upper), isolate_); | 616 Type::Intersect(Type::Smi(isolate_), upper, isolate_); |
618 NarrowType(expr, Bounds(lower, upper)); | 617 NarrowType(expr, Bounds(lower, upper)); |
619 break; | 618 break; |
620 } | 619 } |
621 case Token::BIT_XOR: | 620 case Token::BIT_XOR: |
622 case Token::SHL: | 621 case Token::SHL: |
623 case Token::SAR: | 622 case Token::SAR: |
624 RECURSE(Visit(expr->left())); | 623 RECURSE(Visit(expr->left())); |
625 RECURSE(Visit(expr->right())); | 624 RECURSE(Visit(expr->right())); |
626 NarrowType(expr, Bounds(Type::Smi(), Type::Signed32(), isolate_)); | 625 NarrowType(expr, Bounds(Type::Smi(isolate_), Type::Signed32(isolate_))); |
627 break; | 626 break; |
628 case Token::SHR: | 627 case Token::SHR: |
629 RECURSE(Visit(expr->left())); | 628 RECURSE(Visit(expr->left())); |
630 RECURSE(Visit(expr->right())); | 629 RECURSE(Visit(expr->right())); |
631 // TODO(rossberg): The upper bound would be Unsigned32, but since there | 630 // TODO(rossberg): The upper bound would be Unsigned32, but since there |
632 // is no 'positive Smi' type for the lower bound, we use the smallest | 631 // is no 'positive Smi' type for the lower bound, we use the smallest |
633 // union of Smi and Unsigned32 as upper bound instead. | 632 // union of Smi and Unsigned32 as upper bound instead. |
634 NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_)); | 633 NarrowType(expr, Bounds(Type::Smi(isolate_), Type::Number(isolate_))); |
635 break; | 634 break; |
636 case Token::ADD: { | 635 case Token::ADD: { |
637 RECURSE(Visit(expr->left())); | 636 RECURSE(Visit(expr->left())); |
638 RECURSE(Visit(expr->right())); | 637 RECURSE(Visit(expr->right())); |
639 Bounds l = expr->left()->bounds(); | 638 Bounds l = expr->left()->bounds(); |
640 Bounds r = expr->right()->bounds(); | 639 Bounds r = expr->right()->bounds(); |
641 Type* lower = | 640 Handle<Type> lower = |
642 l.lower->Is(Type::None()) || r.lower->Is(Type::None()) ? | 641 l.lower->Is(Type::None()) || r.lower->Is(Type::None()) ? |
643 Type::None() : | 642 Type::None(isolate_) : |
644 l.lower->Is(Type::String()) || r.lower->Is(Type::String()) ? | 643 l.lower->Is(Type::String()) || r.lower->Is(Type::String()) ? |
645 Type::String() : | 644 Type::String(isolate_) : |
646 l.lower->Is(Type::Number()) && r.lower->Is(Type::Number()) ? | 645 l.lower->Is(Type::Number()) && r.lower->Is(Type::Number()) ? |
647 Type::Smi() : Type::None(); | 646 Type::Smi(isolate_) : Type::None(isolate_); |
648 Type* upper = | 647 Handle<Type> upper = |
649 l.upper->Is(Type::String()) || r.upper->Is(Type::String()) ? | 648 l.upper->Is(Type::String()) || r.upper->Is(Type::String()) ? |
650 Type::String() : | 649 Type::String(isolate_) : |
651 l.upper->Is(Type::Number()) && r.upper->Is(Type::Number()) ? | 650 l.upper->Is(Type::Number()) && r.upper->Is(Type::Number()) ? |
652 Type::Number() : Type::NumberOrString(); | 651 Type::Number(isolate_) : Type::NumberOrString(isolate_); |
653 NarrowType(expr, Bounds(lower, upper, isolate_)); | 652 NarrowType(expr, Bounds(lower, upper)); |
654 break; | 653 break; |
655 } | 654 } |
656 case Token::SUB: | 655 case Token::SUB: |
657 case Token::MUL: | 656 case Token::MUL: |
658 case Token::DIV: | 657 case Token::DIV: |
659 case Token::MOD: | 658 case Token::MOD: |
660 RECURSE(Visit(expr->left())); | 659 RECURSE(Visit(expr->left())); |
661 RECURSE(Visit(expr->right())); | 660 RECURSE(Visit(expr->right())); |
662 NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_)); | 661 NarrowType(expr, Bounds(Type::Smi(isolate_), Type::Number(isolate_))); |
663 break; | 662 break; |
664 default: | 663 default: |
665 UNREACHABLE(); | 664 UNREACHABLE(); |
666 } | 665 } |
667 } | 666 } |
668 | 667 |
669 | 668 |
670 void AstTyper::VisitCompareOperation(CompareOperation* expr) { | 669 void AstTyper::VisitCompareOperation(CompareOperation* expr) { |
671 // Collect type feedback. | 670 // Collect type feedback. |
672 Handle<Type> left_type, right_type, combined_type; | 671 Handle<Type> left_type, right_type, combined_type; |
673 oracle()->CompareType(expr->CompareOperationFeedbackId(), | 672 oracle()->CompareType(expr->CompareOperationFeedbackId(), |
674 &left_type, &right_type, &combined_type); | 673 &left_type, &right_type, &combined_type); |
675 NarrowLowerType(expr->left(), left_type); | 674 NarrowLowerType(expr->left(), left_type); |
676 NarrowLowerType(expr->right(), right_type); | 675 NarrowLowerType(expr->right(), right_type); |
677 expr->set_combined_type(combined_type); | 676 expr->set_combined_type(combined_type); |
678 | 677 |
679 RECURSE(Visit(expr->left())); | 678 RECURSE(Visit(expr->left())); |
680 RECURSE(Visit(expr->right())); | 679 RECURSE(Visit(expr->right())); |
681 | 680 |
682 NarrowType(expr, Bounds(Type::Boolean(), isolate_)); | 681 NarrowType(expr, Bounds(Type::Boolean(isolate_))); |
683 } | 682 } |
684 | 683 |
685 | 684 |
686 void AstTyper::VisitThisFunction(ThisFunction* expr) { | 685 void AstTyper::VisitThisFunction(ThisFunction* expr) { |
687 } | 686 } |
688 | 687 |
689 | 688 |
690 void AstTyper::VisitDeclarations(ZoneList<Declaration*>* decls) { | 689 void AstTyper::VisitDeclarations(ZoneList<Declaration*>* decls) { |
691 for (int i = 0; i < decls->length(); ++i) { | 690 for (int i = 0; i < decls->length(); ++i) { |
692 Declaration* decl = decls->at(i); | 691 Declaration* decl = decls->at(i); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 void AstTyper::VisitModuleUrl(ModuleUrl* module) { | 734 void AstTyper::VisitModuleUrl(ModuleUrl* module) { |
736 } | 735 } |
737 | 736 |
738 | 737 |
739 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) { | 738 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) { |
740 RECURSE(Visit(stmt->body())); | 739 RECURSE(Visit(stmt->body())); |
741 } | 740 } |
742 | 741 |
743 | 742 |
744 } } // namespace v8::internal | 743 } } // namespace v8::internal |
OLD | NEW |