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 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 TestAndBranch(eax, &discard, false_label_); | 579 TestAndBranch(eax, &discard, false_label_); |
580 __ bind(&discard); | 580 __ bind(&discard); |
581 __ add(Operand(esp), Immediate(kPointerSize)); | 581 __ add(Operand(esp), Immediate(kPointerSize)); |
582 __ jmp(true_label_); | 582 __ jmp(true_label_); |
583 break; | 583 break; |
584 } | 584 } |
585 } | 585 } |
586 } | 586 } |
587 | 587 |
588 | 588 |
589 void FastCodeGenerator::EmitVariableAssignment(Expression::Context context, | 589 void FastCodeGenerator::EmitVariableAssignment(Assignment* expr) { |
590 Variable* var) { | 590 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
| 591 ASSERT(var != NULL); |
| 592 |
591 if (var->is_global()) { | 593 if (var->is_global()) { |
592 // Assignment to a global variable, use inline caching. Right-hand-side | 594 // Assignment to a global variable. Use inline caching for the |
593 // value is passed in eax, variable name in ecx, and the global object | 595 // assignment. Right-hand-side value is passed in eax, variable name in |
594 // on the stack. | 596 // ecx, and the global object on the stack. |
595 __ pop(eax); | 597 __ pop(eax); |
596 __ mov(ecx, var->name()); | 598 __ mov(ecx, var->name()); |
597 __ push(CodeGenerator::GlobalObject()); | 599 __ push(CodeGenerator::GlobalObject()); |
598 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 600 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
599 __ call(ic, RelocInfo::CODE_TARGET); | 601 __ call(ic, RelocInfo::CODE_TARGET); |
600 // Overwrite the global object on the stack with the result if needed. | 602 // Overwrite the receiver on the stack with the result if needed. |
601 DropAndMove(context, eax); | 603 DropAndMove(expr->context(), eax); |
| 604 |
602 } else { | 605 } else { |
603 switch (context) { | 606 switch (expr->context()) { |
604 case Expression::kUninitialized: | 607 case Expression::kUninitialized: |
605 UNREACHABLE(); | 608 UNREACHABLE(); |
606 case Expression::kEffect: | 609 case Expression::kEffect: |
607 // Perform assignment and discard value. | 610 // Perform assignment and discard value. |
608 __ pop(Operand(ebp, SlotOffset(var->slot()))); | 611 __ pop(Operand(ebp, SlotOffset(var->slot()))); |
609 break; | 612 break; |
610 case Expression::kValue: | 613 case Expression::kValue: |
611 // Perform assignment and preserve value. | 614 // Perform assignment and preserve value. |
612 __ mov(eax, Operand(esp, 0)); | 615 __ mov(eax, Operand(esp, 0)); |
613 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); | 616 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); |
(...skipping 22 matching lines...) Expand all Loading... |
636 __ bind(&discard); | 639 __ bind(&discard); |
637 __ add(Operand(esp), Immediate(kPointerSize)); | 640 __ add(Operand(esp), Immediate(kPointerSize)); |
638 __ jmp(true_label_); | 641 __ jmp(true_label_); |
639 break; | 642 break; |
640 } | 643 } |
641 } | 644 } |
642 } | 645 } |
643 } | 646 } |
644 | 647 |
645 | 648 |
646 void FastCodeGenerator::EmitNamedPropertyAssignment( | 649 void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
647 Expression::Context context, | 650 // Assignment to a property, using a named store IC. |
648 Handle<Object> name) { | 651 Property* prop = expr->target()->AsProperty(); |
| 652 ASSERT(prop != NULL); |
| 653 ASSERT(prop->key()->AsLiteral() != NULL); |
| 654 |
| 655 // If the assignment starts a block of assignments to the same object, |
| 656 // change to slow case to avoid the quadratic behavior of repeatedly |
| 657 // adding fast properties. |
| 658 if (expr->starts_initialization_block()) { |
| 659 __ push(Operand(esp, kPointerSize)); // Receiver is under value. |
| 660 __ CallRuntime(Runtime::kToSlowProperties, 1); |
| 661 } |
| 662 |
649 __ pop(eax); | 663 __ pop(eax); |
650 __ mov(ecx, name); | 664 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
651 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 665 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
652 __ call(ic, RelocInfo::CODE_TARGET); | 666 __ call(ic, RelocInfo::CODE_TARGET); |
653 DropAndMove(context, eax); | 667 |
| 668 // If the assignment ends an initialization block, revert to fast case. |
| 669 if (expr->ends_initialization_block()) { |
| 670 __ push(eax); // Result of assignment, saved even if not needed. |
| 671 __ push(Operand(esp, kPointerSize)); // Receiver is under value. |
| 672 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 673 __ pop(eax); |
| 674 } |
| 675 |
| 676 DropAndMove(expr->context(), eax); |
654 } | 677 } |
655 | 678 |
656 | 679 |
657 void FastCodeGenerator::EmitKeyedPropertyAssignment( | 680 void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
658 Expression::Context context) { | 681 // Assignment to a property, using a keyed store IC. |
| 682 |
| 683 // If the assignment starts a block of assignments to the same object, |
| 684 // change to slow case to avoid the quadratic behavior of repeatedly |
| 685 // adding fast properties. |
| 686 if (expr->starts_initialization_block()) { |
| 687 // Reciever is under the key and value. |
| 688 __ push(Operand(esp, 2 * kPointerSize)); |
| 689 __ CallRuntime(Runtime::kToSlowProperties, 1); |
| 690 } |
| 691 |
659 __ pop(eax); | 692 __ pop(eax); |
660 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 693 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
661 __ call(ic, RelocInfo::CODE_TARGET); | 694 __ call(ic, RelocInfo::CODE_TARGET); |
662 // This nop signals to the IC that there is no inlined code at the call | 695 // This nop signals to the IC that there is no inlined code at the call |
663 // site for it to patch. | 696 // site for it to patch. |
664 __ nop(); | 697 __ nop(); |
| 698 |
| 699 // If the assignment ends an initialization block, revert to fast case. |
| 700 if (expr->ends_initialization_block()) { |
| 701 __ push(eax); // Result of assignment, saved even if not needed. |
| 702 // Reciever is under the key and value. |
| 703 __ push(Operand(esp, 2 * kPointerSize)); |
| 704 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 705 __ pop(eax); |
| 706 } |
| 707 |
665 // Receiver and key are still on stack. | 708 // Receiver and key are still on stack. |
666 __ add(Operand(esp), Immediate(2 * kPointerSize)); | 709 __ add(Operand(esp), Immediate(2 * kPointerSize)); |
667 Move(context, eax); | 710 Move(expr->context(), eax); |
668 } | 711 } |
669 | 712 |
670 | 713 |
671 void FastCodeGenerator::VisitProperty(Property* expr) { | 714 void FastCodeGenerator::VisitProperty(Property* expr) { |
672 Comment cmnt(masm_, "[ Property"); | 715 Comment cmnt(masm_, "[ Property"); |
673 Expression* key = expr->key(); | 716 Expression* key = expr->key(); |
674 uint32_t dummy; | 717 uint32_t dummy; |
675 | 718 |
676 // Record the source position for the property load. | 719 // Record the source position for the property load. |
677 SetSourcePosition(expr->position()); | 720 SetSourcePosition(expr->position()); |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1064 default: | 1107 default: |
1065 UNREACHABLE(); | 1108 UNREACHABLE(); |
1066 } | 1109 } |
1067 } | 1110 } |
1068 | 1111 |
1069 | 1112 |
1070 #undef __ | 1113 #undef __ |
1071 | 1114 |
1072 | 1115 |
1073 } } // namespace v8::internal | 1116 } } // namespace v8::internal |
OLD | NEW |