OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 TestAndBranch(rax, &discard, false_label_); | 593 TestAndBranch(rax, &discard, false_label_); |
594 __ bind(&discard); | 594 __ bind(&discard); |
595 __ addq(rsp, Immediate(kPointerSize)); | 595 __ addq(rsp, Immediate(kPointerSize)); |
596 __ jmp(true_label_); | 596 __ jmp(true_label_); |
597 break; | 597 break; |
598 } | 598 } |
599 } | 599 } |
600 } | 600 } |
601 | 601 |
602 | 602 |
603 void FastCodeGenerator::EmitVariableAssignment(Expression::Context context, | 603 void FastCodeGenerator::EmitVariableAssignment(Assignment* expr) { |
604 Variable* var) { | 604 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
| 605 ASSERT(var != NULL); |
| 606 |
605 if (var->is_global()) { | 607 if (var->is_global()) { |
606 // Assignment to a global variable, use inline caching. Right-hand-side | 608 // Assignment to a global variable. Use inline caching for the |
607 // value is passed in rax, variable name in rcx, and the global object | 609 // assignment. Right-hand-side value is passed in rax, variable name in |
608 // on the stack. | 610 // rcx, and the global object on the stack. |
609 __ pop(rax); | 611 __ pop(rax); |
610 __ Move(rcx, var->name()); | 612 __ Move(rcx, var->name()); |
611 __ push(CodeGenerator::GlobalObject()); | 613 __ push(CodeGenerator::GlobalObject()); |
612 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 614 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
613 __ Call(ic, RelocInfo::CODE_TARGET); | 615 __ Call(ic, RelocInfo::CODE_TARGET); |
614 // Overwrite the global object on the stack with the result if needed. | 616 // Overwrite the global object on the stack with the result if needed. |
615 DropAndMove(context, rax); | 617 DropAndMove(expr->context(), rax); |
| 618 |
616 } else { | 619 } else { |
617 switch (context) { | 620 switch (expr->context()) { |
618 case Expression::kUninitialized: | 621 case Expression::kUninitialized: |
619 UNREACHABLE(); | 622 UNREACHABLE(); |
620 case Expression::kEffect: | 623 case Expression::kEffect: |
621 // Perform assignment and discard value. | 624 // Perform assignment and discard value. |
622 __ pop(Operand(rbp, SlotOffset(var->slot()))); | 625 __ pop(Operand(rbp, SlotOffset(var->slot()))); |
623 break; | 626 break; |
624 case Expression::kValue: | 627 case Expression::kValue: |
625 // Perform assignment and preserve value. | 628 // Perform assignment and preserve value. |
626 __ movq(rax, Operand(rsp, 0)); | 629 __ movq(rax, Operand(rsp, 0)); |
627 __ movq(Operand(rbp, SlotOffset(var->slot())), rax); | 630 __ movq(Operand(rbp, SlotOffset(var->slot())), rax); |
(...skipping 22 matching lines...) Expand all Loading... |
650 __ bind(&discard); | 653 __ bind(&discard); |
651 __ addq(rsp, Immediate(kPointerSize)); | 654 __ addq(rsp, Immediate(kPointerSize)); |
652 __ jmp(true_label_); | 655 __ jmp(true_label_); |
653 break; | 656 break; |
654 } | 657 } |
655 } | 658 } |
656 } | 659 } |
657 } | 660 } |
658 | 661 |
659 | 662 |
660 void FastCodeGenerator::EmitNamedPropertyAssignment( | 663 void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
661 Expression::Context context, | 664 // Assignment to a property, using a named store IC. |
662 Handle<Object> name) { | 665 Property* prop = expr->target()->AsProperty(); |
| 666 ASSERT(prop != NULL); |
| 667 ASSERT(prop->key()->AsLiteral() != NULL); |
| 668 |
| 669 // If the assignment starts a block of assignments to the same object, |
| 670 // change to slow case to avoid the quadratic behavior of repeatedly |
| 671 // adding fast properties. |
| 672 if (expr->starts_initialization_block()) { |
| 673 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. |
| 674 __ CallRuntime(Runtime::kToSlowProperties, 1); |
| 675 } |
| 676 |
663 __ pop(rax); | 677 __ pop(rax); |
664 __ Move(rcx, name); | 678 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
665 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 679 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
666 __ Call(ic, RelocInfo::CODE_TARGET); | 680 __ Call(ic, RelocInfo::CODE_TARGET); |
667 DropAndMove(context, rax); | 681 |
| 682 // If the assignment ends an initialization block, revert to fast case. |
| 683 if (expr->ends_initialization_block()) { |
| 684 __ push(rax); // Result of assignment, saved even if not needed. |
| 685 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. |
| 686 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 687 __ pop(rax); |
| 688 } |
| 689 |
| 690 DropAndMove(expr->context(), rax); |
668 } | 691 } |
669 | 692 |
670 | 693 |
671 void FastCodeGenerator::EmitKeyedPropertyAssignment( | 694 void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
672 Expression::Context context) { | 695 // Assignment to a property, using a keyed store IC. |
| 696 |
| 697 // If the assignment starts a block of assignments to the same object, |
| 698 // change to slow case to avoid the quadratic behavior of repeatedly |
| 699 // adding fast properties. |
| 700 if (expr->starts_initialization_block()) { |
| 701 // Reciever is under the key and value. |
| 702 __ push(Operand(rsp, 2 * kPointerSize)); |
| 703 __ CallRuntime(Runtime::kToSlowProperties, 1); |
| 704 } |
| 705 |
673 __ pop(rax); | 706 __ pop(rax); |
674 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 707 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
675 __ Call(ic, RelocInfo::CODE_TARGET); | 708 __ Call(ic, RelocInfo::CODE_TARGET); |
676 // This nop signals to the IC that there is no inlined code at the call | 709 // This nop signals to the IC that there is no inlined code at the call |
677 // site for it to patch. | 710 // site for it to patch. |
678 __ nop(); | 711 __ nop(); |
| 712 |
| 713 // If the assignment ends an initialization block, revert to fast case. |
| 714 if (expr->ends_initialization_block()) { |
| 715 __ push(rax); // Result of assignment, saved even if not needed. |
| 716 // Reciever is under the key and value. |
| 717 __ push(Operand(rsp, 2 * kPointerSize)); |
| 718 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 719 __ pop(rax); |
| 720 } |
| 721 |
679 // Receiver and key are still on stack. | 722 // Receiver and key are still on stack. |
680 __ addq(rsp, Immediate(2 * kPointerSize)); | 723 __ addq(rsp, Immediate(2 * kPointerSize)); |
681 Move(context, rax); | 724 Move(expr->context(), rax); |
682 } | 725 } |
683 | 726 |
684 | 727 |
685 void FastCodeGenerator::VisitProperty(Property* expr) { | 728 void FastCodeGenerator::VisitProperty(Property* expr) { |
686 Comment cmnt(masm_, "[ Property"); | 729 Comment cmnt(masm_, "[ Property"); |
687 Expression* key = expr->key(); | 730 Expression* key = expr->key(); |
688 uint32_t dummy; | 731 uint32_t dummy; |
689 | 732 |
690 // Record the source position for the property load. | 733 // Record the source position for the property load. |
691 SetSourcePosition(expr->position()); | 734 SetSourcePosition(expr->position()); |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1077 | 1120 |
1078 break; | 1121 break; |
1079 } | 1122 } |
1080 default: | 1123 default: |
1081 UNREACHABLE(); | 1124 UNREACHABLE(); |
1082 } | 1125 } |
1083 } | 1126 } |
1084 | 1127 |
1085 | 1128 |
1086 } } // namespace v8::internal | 1129 } } // namespace v8::internal |
OLD | NEW |