OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, | 705 void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, |
706 Label* label, | 706 Label* label, |
707 Handle<Name> name) { | 707 Handle<Name> name) { |
708 if (!label->is_unused()) { | 708 if (!label->is_unused()) { |
709 __ bind(label); | 709 __ bind(label); |
710 __ Move(this->name(), name); | 710 __ Move(this->name(), name); |
711 } | 711 } |
712 } | 712 } |
713 | 713 |
714 | 714 |
| 715 // Generate code to check that a global property cell is empty. Create |
| 716 // the property cell at compilation time if no cell exists for the |
| 717 // property. |
| 718 static void GenerateCheckPropertyCell(MacroAssembler* masm, |
| 719 Handle<GlobalObject> global, |
| 720 Handle<Name> name, |
| 721 Register scratch, |
| 722 Label* miss) { |
| 723 Handle<JSGlobalPropertyCell> cell = |
| 724 GlobalObject::EnsurePropertyCell(global, name); |
| 725 ASSERT(cell->value()->IsTheHole()); |
| 726 __ Move(scratch, cell); |
| 727 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), |
| 728 masm->isolate()->factory()->the_hole_value()); |
| 729 __ j(not_equal, miss); |
| 730 } |
| 731 |
| 732 |
715 // Both name_reg and receiver_reg are preserved on jumps to miss_label, | 733 // Both name_reg and receiver_reg are preserved on jumps to miss_label, |
716 // but may be destroyed if store is successful. | 734 // but may be destroyed if store is successful. |
717 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 735 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
718 Handle<JSObject> object, | 736 Handle<JSObject> object, |
719 LookupResult* lookup, | 737 LookupResult* lookup, |
720 Handle<Map> transition, | 738 Handle<Map> transition, |
721 Handle<Name> name, | 739 Handle<Name> name, |
722 Register receiver_reg, | 740 Register receiver_reg, |
723 Register name_reg, | 741 Register name_reg, |
724 Register value_reg, | 742 Register value_reg, |
(...skipping 24 matching lines...) Expand all Loading... |
749 do { | 767 do { |
750 holder = JSObject::cast(holder->GetPrototype()); | 768 holder = JSObject::cast(holder->GetPrototype()); |
751 } while (holder->GetPrototype()->IsJSObject()); | 769 } while (holder->GetPrototype()->IsJSObject()); |
752 } | 770 } |
753 Register holder_reg = CheckPrototypes( | 771 Register holder_reg = CheckPrototypes( |
754 object, receiver_reg, Handle<JSObject>(holder), name_reg, | 772 object, receiver_reg, Handle<JSObject>(holder), name_reg, |
755 scratch1, scratch2, name, miss_restore_name); | 773 scratch1, scratch2, name, miss_restore_name); |
756 // If no property was found, and the holder (the last object in the | 774 // If no property was found, and the holder (the last object in the |
757 // prototype chain) is in slow mode, we need to do a negative lookup on the | 775 // prototype chain) is in slow mode, we need to do a negative lookup on the |
758 // holder. | 776 // holder. |
759 if (lookup->holder() == *object && | 777 if (lookup->holder() == *object) { |
760 !holder->HasFastProperties() && | 778 if (holder->IsJSGlobalObject()) { |
761 !holder->IsJSGlobalProxy() && | 779 GenerateCheckPropertyCell( |
762 !holder->IsJSGlobalObject()) { | 780 masm, |
763 GenerateDictionaryNegativeLookup( | 781 Handle<GlobalObject>(GlobalObject::cast(holder)), |
764 masm, miss_restore_name, holder_reg, name, scratch1, scratch2); | 782 name, |
| 783 scratch1, |
| 784 miss_restore_name); |
| 785 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { |
| 786 GenerateDictionaryNegativeLookup( |
| 787 masm, miss_restore_name, holder_reg, name, scratch1, scratch2); |
| 788 } |
765 } | 789 } |
766 } | 790 } |
767 | 791 |
768 // Stub never generated for non-global objects that require access | 792 // Stub never generated for non-global objects that require access |
769 // checks. | 793 // checks. |
770 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 794 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
771 | 795 |
772 // Perform map transition for the receiver if necessary. | 796 // Perform map transition for the receiver if necessary. |
773 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) { | 797 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) { |
774 // The properties must be extended before we can store the value. | 798 // The properties must be extended before we can store the value. |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 __ RecordWriteField( | 859 __ RecordWriteField( |
836 scratch1, offset, name_reg, receiver_reg, kDontSaveFPRegs); | 860 scratch1, offset, name_reg, receiver_reg, kDontSaveFPRegs); |
837 } | 861 } |
838 | 862 |
839 // Return the value (register rax). | 863 // Return the value (register rax). |
840 ASSERT(value_reg.is(rax)); | 864 ASSERT(value_reg.is(rax)); |
841 __ ret(0); | 865 __ ret(0); |
842 } | 866 } |
843 | 867 |
844 | 868 |
845 // Generate code to check that a global property cell is empty. Create | |
846 // the property cell at compilation time if no cell exists for the | |
847 // property. | |
848 static void GenerateCheckPropertyCell(MacroAssembler* masm, | |
849 Handle<GlobalObject> global, | |
850 Handle<Name> name, | |
851 Register scratch, | |
852 Label* miss) { | |
853 Handle<JSGlobalPropertyCell> cell = | |
854 GlobalObject::EnsurePropertyCell(global, name); | |
855 ASSERT(cell->value()->IsTheHole()); | |
856 __ Move(scratch, cell); | |
857 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), | |
858 masm->isolate()->factory()->the_hole_value()); | |
859 __ j(not_equal, miss); | |
860 } | |
861 | |
862 | |
863 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 869 // Calls GenerateCheckPropertyCell for each global object in the prototype chain |
864 // from object to (but not including) holder. | 870 // from object to (but not including) holder. |
865 static void GenerateCheckPropertyCells(MacroAssembler* masm, | 871 static void GenerateCheckPropertyCells(MacroAssembler* masm, |
866 Handle<JSObject> object, | 872 Handle<JSObject> object, |
867 Handle<JSObject> holder, | 873 Handle<JSObject> holder, |
868 Handle<Name> name, | 874 Handle<Name> name, |
869 Register scratch, | 875 Register scratch, |
870 Label* miss) { | 876 Label* miss) { |
871 Handle<JSObject> current = object; | 877 Handle<JSObject> current = object; |
872 while (!current.is_identical_to(holder)) { | 878 while (!current.is_identical_to(holder)) { |
(...skipping 2534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3407 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); | 3413 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); |
3408 } | 3414 } |
3409 } | 3415 } |
3410 | 3416 |
3411 | 3417 |
3412 #undef __ | 3418 #undef __ |
3413 | 3419 |
3414 } } // namespace v8::internal | 3420 } } // namespace v8::internal |
3415 | 3421 |
3416 #endif // V8_TARGET_ARCH_X64 | 3422 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |