| 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 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 746 Label* miss_restore_name) { | 746 Label* miss_restore_name) { |
| 747 // Check that the map of the object hasn't changed. | 747 // Check that the map of the object hasn't changed. |
| 748 __ CheckMap(receiver_reg, Handle<Map>(object->map()), | 748 __ CheckMap(receiver_reg, Handle<Map>(object->map()), |
| 749 miss_label, DO_SMI_CHECK, REQUIRE_EXACT_MAP); | 749 miss_label, DO_SMI_CHECK, REQUIRE_EXACT_MAP); |
| 750 | 750 |
| 751 // Perform global security token check if needed. | 751 // Perform global security token check if needed. |
| 752 if (object->IsJSGlobalProxy()) { | 752 if (object->IsJSGlobalProxy()) { |
| 753 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label); | 753 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label); |
| 754 } | 754 } |
| 755 | 755 |
| 756 int descriptor = transition->LastAdded(); |
| 757 DescriptorArray* descriptors = transition->instance_descriptors(); |
| 758 PropertyDetails details = descriptors->GetDetails(descriptor); |
| 759 Representation representation = details.representation(); |
| 760 ASSERT(!representation.IsNone()); |
| 761 |
| 762 // Ensure no transitions to deprecated maps are followed. |
| 763 __ CheckMapDeprecated(transition, scratch1, miss_label); |
| 764 |
| 765 if (FLAG_track_fields && representation.IsSmi()) { |
| 766 __ JumpIfNotSmi(value_reg, miss_label); |
| 767 } else if (FLAG_track_double_fields && representation.IsDouble()) { |
| 768 Label do_store; |
| 769 __ JumpIfSmi(value_reg, &do_store); |
| 770 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), |
| 771 miss_label, DONT_DO_SMI_CHECK, REQUIRE_EXACT_MAP); |
| 772 __ bind(&do_store); |
| 773 } |
| 774 |
| 756 // Check that we are allowed to write this. | 775 // Check that we are allowed to write this. |
| 757 if (object->GetPrototype()->IsJSObject()) { | 776 if (object->GetPrototype()->IsJSObject()) { |
| 758 JSObject* holder; | 777 JSObject* holder; |
| 759 // holder == object indicates that no property was found. | 778 // holder == object indicates that no property was found. |
| 760 if (lookup->holder() != *object) { | 779 if (lookup->holder() != *object) { |
| 761 holder = lookup->holder(); | 780 holder = lookup->holder(); |
| 762 } else { | 781 } else { |
| 763 // Find the top object. | 782 // Find the top object. |
| 764 holder = *object; | 783 holder = *object; |
| 765 do { | 784 do { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 // face of a transition we can use the old map here because the size of the | 848 // face of a transition we can use the old map here because the size of the |
| 830 // object and the number of in-object properties is not going to change. | 849 // object and the number of in-object properties is not going to change. |
| 831 index -= object->map()->inobject_properties(); | 850 index -= object->map()->inobject_properties(); |
| 832 | 851 |
| 833 // TODO(verwaest): Share this code as a code stub. | 852 // TODO(verwaest): Share this code as a code stub. |
| 834 if (index < 0) { | 853 if (index < 0) { |
| 835 // Set the property straight into the object. | 854 // Set the property straight into the object. |
| 836 int offset = object->map()->instance_size() + (index * kPointerSize); | 855 int offset = object->map()->instance_size() + (index * kPointerSize); |
| 837 __ movq(FieldOperand(receiver_reg, offset), value_reg); | 856 __ movq(FieldOperand(receiver_reg, offset), value_reg); |
| 838 | 857 |
| 839 // Update the write barrier for the array address. | 858 if (!FLAG_track_fields || !representation.IsSmi()) { |
| 840 // Pass the value being stored in the now unused name_reg. | 859 // Update the write barrier for the array address. |
| 841 __ movq(name_reg, value_reg); | 860 // Pass the value being stored in the now unused name_reg. |
| 842 __ RecordWriteField( | 861 __ movq(name_reg, value_reg); |
| 843 receiver_reg, offset, name_reg, scratch1, kDontSaveFPRegs); | 862 __ RecordWriteField( |
| 863 receiver_reg, offset, name_reg, scratch1, kDontSaveFPRegs); |
| 864 } |
| 844 } else { | 865 } else { |
| 845 // Write to the properties array. | 866 // Write to the properties array. |
| 846 int offset = index * kPointerSize + FixedArray::kHeaderSize; | 867 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
| 847 // Get the properties array (optimistically). | 868 // Get the properties array (optimistically). |
| 848 __ movq(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); | 869 __ movq(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
| 849 __ movq(FieldOperand(scratch1, offset), value_reg); | 870 __ movq(FieldOperand(scratch1, offset), value_reg); |
| 850 | 871 |
| 851 // Update the write barrier for the array address. | 872 if (!FLAG_track_fields || !representation.IsSmi()) { |
| 852 // Pass the value being stored in the now unused name_reg. | 873 // Update the write barrier for the array address. |
| 853 __ movq(name_reg, value_reg); | 874 // Pass the value being stored in the now unused name_reg. |
| 854 __ RecordWriteField( | 875 __ movq(name_reg, value_reg); |
| 855 scratch1, offset, name_reg, receiver_reg, kDontSaveFPRegs); | 876 __ RecordWriteField( |
| 877 scratch1, offset, name_reg, receiver_reg, kDontSaveFPRegs); |
| 878 } |
| 856 } | 879 } |
| 857 | 880 |
| 858 // Return the value (register rax). | 881 // Return the value (register rax). |
| 859 ASSERT(value_reg.is(rax)); | 882 ASSERT(value_reg.is(rax)); |
| 860 __ ret(0); | 883 __ ret(0); |
| 861 } | 884 } |
| 862 | 885 |
| 863 | 886 |
| 864 // Both name_reg and receiver_reg are preserved on jumps to miss_label, | 887 // Both name_reg and receiver_reg are preserved on jumps to miss_label, |
| 865 // but may be destroyed if store is successful. | 888 // but may be destroyed if store is successful. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 885 // checks. | 908 // checks. |
| 886 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 909 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
| 887 | 910 |
| 888 int index = lookup->GetFieldIndex().field_index(); | 911 int index = lookup->GetFieldIndex().field_index(); |
| 889 | 912 |
| 890 // Adjust for the number of properties stored in the object. Even in the | 913 // Adjust for the number of properties stored in the object. Even in the |
| 891 // face of a transition we can use the old map here because the size of the | 914 // face of a transition we can use the old map here because the size of the |
| 892 // object and the number of in-object properties is not going to change. | 915 // object and the number of in-object properties is not going to change. |
| 893 index -= object->map()->inobject_properties(); | 916 index -= object->map()->inobject_properties(); |
| 894 | 917 |
| 918 Representation representation = lookup->representation(); |
| 919 ASSERT(!representation.IsNone()); |
| 920 if (FLAG_track_fields && representation.IsSmi()) { |
| 921 __ JumpIfNotSmi(value_reg, miss_label); |
| 922 } else if (FLAG_track_double_fields && representation.IsDouble()) { |
| 923 Label do_store; |
| 924 __ JumpIfSmi(value_reg, &do_store); |
| 925 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), |
| 926 miss_label, DONT_DO_SMI_CHECK, REQUIRE_EXACT_MAP); |
| 927 __ bind(&do_store); |
| 928 } |
| 929 |
| 895 // TODO(verwaest): Share this code as a code stub. | 930 // TODO(verwaest): Share this code as a code stub. |
| 896 if (index < 0) { | 931 if (index < 0) { |
| 897 // Set the property straight into the object. | 932 // Set the property straight into the object. |
| 898 int offset = object->map()->instance_size() + (index * kPointerSize); | 933 int offset = object->map()->instance_size() + (index * kPointerSize); |
| 899 __ movq(FieldOperand(receiver_reg, offset), value_reg); | 934 __ movq(FieldOperand(receiver_reg, offset), value_reg); |
| 900 | 935 |
| 901 // Update the write barrier for the array address. | 936 if (!FLAG_track_fields || !representation.IsSmi()) { |
| 902 // Pass the value being stored in the now unused name_reg. | 937 // Update the write barrier for the array address. |
| 903 __ movq(name_reg, value_reg); | 938 // Pass the value being stored in the now unused name_reg. |
| 904 __ RecordWriteField( | 939 __ movq(name_reg, value_reg); |
| 905 receiver_reg, offset, name_reg, scratch1, kDontSaveFPRegs); | 940 __ RecordWriteField( |
| 941 receiver_reg, offset, name_reg, scratch1, kDontSaveFPRegs); |
| 942 } |
| 906 } else { | 943 } else { |
| 907 // Write to the properties array. | 944 // Write to the properties array. |
| 908 int offset = index * kPointerSize + FixedArray::kHeaderSize; | 945 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
| 909 // Get the properties array (optimistically). | 946 // Get the properties array (optimistically). |
| 910 __ movq(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); | 947 __ movq(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
| 911 __ movq(FieldOperand(scratch1, offset), value_reg); | 948 __ movq(FieldOperand(scratch1, offset), value_reg); |
| 912 | 949 |
| 913 // Update the write barrier for the array address. | 950 if (!FLAG_track_fields || !representation.IsSmi()) { |
| 914 // Pass the value being stored in the now unused name_reg. | 951 // Update the write barrier for the array address. |
| 915 __ movq(name_reg, value_reg); | 952 // Pass the value being stored in the now unused name_reg. |
| 916 __ RecordWriteField( | 953 __ movq(name_reg, value_reg); |
| 917 scratch1, offset, name_reg, receiver_reg, kDontSaveFPRegs); | 954 __ RecordWriteField( |
| 955 scratch1, offset, name_reg, receiver_reg, kDontSaveFPRegs); |
| 956 } |
| 918 } | 957 } |
| 919 | 958 |
| 920 // Return the value (register rax). | 959 // Return the value (register rax). |
| 921 ASSERT(value_reg.is(rax)); | 960 ASSERT(value_reg.is(rax)); |
| 922 __ ret(0); | 961 __ ret(0); |
| 923 } | 962 } |
| 924 | 963 |
| 925 | 964 |
| 926 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 965 // Calls GenerateCheckPropertyCell for each global object in the prototype chain |
| 927 // from object to (but not including) holder. | 966 // from object to (but not including) holder. |
| (...skipping 1864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2792 Label miss; | 2831 Label miss; |
| 2793 | 2832 |
| 2794 if (check == PROPERTY) { | 2833 if (check == PROPERTY) { |
| 2795 GenerateNameCheck(name, this->name(), &miss); | 2834 GenerateNameCheck(name, this->name(), &miss); |
| 2796 } | 2835 } |
| 2797 | 2836 |
| 2798 __ JumpIfSmi(receiver(), &miss); | 2837 __ JumpIfSmi(receiver(), &miss); |
| 2799 Register map_reg = scratch1(); | 2838 Register map_reg = scratch1(); |
| 2800 __ movq(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); | 2839 __ movq(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); |
| 2801 int receiver_count = receiver_maps->length(); | 2840 int receiver_count = receiver_maps->length(); |
| 2841 int number_of_handled_maps = 0; |
| 2802 for (int current = 0; current < receiver_count; ++current) { | 2842 for (int current = 0; current < receiver_count; ++current) { |
| 2803 // Check map and tail call if there's a match | 2843 Handle<Map> map = receiver_maps->at(current); |
| 2804 __ Cmp(map_reg, receiver_maps->at(current)); | 2844 if (!map->is_deprecated()) { |
| 2805 __ j(equal, handlers->at(current), RelocInfo::CODE_TARGET); | 2845 number_of_handled_maps++; |
| 2846 // Check map and tail call if there's a match |
| 2847 __ Cmp(map_reg, receiver_maps->at(current)); |
| 2848 __ j(equal, handlers->at(current), RelocInfo::CODE_TARGET); |
| 2849 } |
| 2806 } | 2850 } |
| 2851 ASSERT(number_of_handled_maps > 0); |
| 2807 | 2852 |
| 2808 __ bind(&miss); | 2853 __ bind(&miss); |
| 2809 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2854 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 2810 | 2855 |
| 2811 // Return the generated code. | 2856 // Return the generated code. |
| 2812 InlineCacheState state = | 2857 InlineCacheState state = |
| 2813 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; | 2858 number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; |
| 2814 return GetICCode(kind(), type, name, state); | 2859 return GetICCode(kind(), type, name, state); |
| 2815 } | 2860 } |
| 2816 | 2861 |
| 2817 | 2862 |
| 2818 // Specialized stub for constructing objects from functions which only have only | 2863 // Specialized stub for constructing objects from functions which only have only |
| 2819 // simple assignments of the form this.x = ...; in their body. | 2864 // simple assignments of the form this.x = ...; in their body. |
| 2820 Handle<Code> ConstructStubCompiler::CompileConstructStub( | 2865 Handle<Code> ConstructStubCompiler::CompileConstructStub( |
| 2821 Handle<JSFunction> function) { | 2866 Handle<JSFunction> function) { |
| 2822 // ----------- S t a t e ------------- | 2867 // ----------- S t a t e ------------- |
| 2823 // -- rax : argc | 2868 // -- rax : argc |
| (...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3470 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); | 3515 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); |
| 3471 } | 3516 } |
| 3472 } | 3517 } |
| 3473 | 3518 |
| 3474 | 3519 |
| 3475 #undef __ | 3520 #undef __ |
| 3476 | 3521 |
| 3477 } } // namespace v8::internal | 3522 } } // namespace v8::internal |
| 3478 | 3523 |
| 3479 #endif // V8_TARGET_ARCH_X64 | 3524 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |