Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(988)

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 14142005: Implement Polymorphic Store ICs (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/arm/stub-cache-arm.cc ('K') | « src/x64/ic-x64.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 739 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 Handle<PropertyCell> cell = 750 Handle<PropertyCell> cell =
751 GlobalObject::EnsurePropertyCell(global, name); 751 GlobalObject::EnsurePropertyCell(global, name);
752 ASSERT(cell->value()->IsTheHole()); 752 ASSERT(cell->value()->IsTheHole());
753 __ Move(scratch, cell); 753 __ Move(scratch, cell);
754 __ Cmp(FieldOperand(scratch, Cell::kValueOffset), 754 __ Cmp(FieldOperand(scratch, Cell::kValueOffset),
755 masm->isolate()->factory()->the_hole_value()); 755 masm->isolate()->factory()->the_hole_value());
756 __ j(not_equal, miss); 756 __ j(not_equal, miss);
757 } 757 }
758 758
759 759
760 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 760 void BaseStoreStubCompiler::GenerateNegativeHolderLookup(
761 // but may be destroyed if store is successful. 761 MacroAssembler* masm,
762 void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, 762 Handle<JSObject> holder,
763 Handle<JSObject> object, 763 Register holder_reg,
764 LookupResult* lookup, 764 Handle<Name> name,
765 Handle<Map> transition, 765 Label* miss) {
766 Handle<Name> name, 766 if (holder->IsJSGlobalObject()) {
767 Register receiver_reg, 767 GenerateCheckPropertyCell(
768 Register name_reg, 768 masm,
769 Register value_reg, 769 Handle<GlobalObject>::cast(holder),
770 Register scratch1, 770 name,
771 Register scratch2, 771 scratch1(),
772 Register unused, 772 miss);
773 Label* miss_label, 773 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
774 Label* miss_restore_name, 774 GenerateDictionaryNegativeLookup(
775 Label* slow) { 775 masm, miss, holder_reg, name, scratch1(), scratch2());
776 // Check that the map of the object hasn't changed. 776 }
777 __ CheckMap(receiver_reg, Handle<Map>(object->map()), 777 }
778 miss_label, DO_SMI_CHECK);
779 778
780 // Perform global security token check if needed.
781 if (object->IsJSGlobalProxy()) {
782 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label);
783 }
784 779
780 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if
781 // store is successful.
782 void BaseStoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
783 Handle<JSObject> object,
784 LookupResult* lookup,
785 Handle<Map> transition,
786 Handle<Name> name,
787 Register receiver_reg,
788 Register storage_reg,
789 Register value_reg,
790 Register scratch1,
791 Register scratch2,
792 Register unused,
793 Label* miss_label,
794 Label* slow) {
785 int descriptor = transition->LastAdded(); 795 int descriptor = transition->LastAdded();
786 DescriptorArray* descriptors = transition->instance_descriptors(); 796 DescriptorArray* descriptors = transition->instance_descriptors();
787 PropertyDetails details = descriptors->GetDetails(descriptor); 797 PropertyDetails details = descriptors->GetDetails(descriptor);
788 Representation representation = details.representation(); 798 Representation representation = details.representation();
789 ASSERT(!representation.IsNone()); 799 ASSERT(!representation.IsNone());
790 800
791 // Ensure no transitions to deprecated maps are followed.
792 __ CheckMapDeprecated(transition, scratch1, miss_label);
793
794 // Check that we are allowed to write this.
795 if (object->GetPrototype()->IsJSObject()) {
796 JSObject* holder;
797 // holder == object indicates that no property was found.
798 if (lookup->holder() != *object) {
799 holder = lookup->holder();
800 } else {
801 // Find the top object.
802 holder = *object;
803 do {
804 holder = JSObject::cast(holder->GetPrototype());
805 } while (holder->GetPrototype()->IsJSObject());
806 }
807 Register holder_reg = CheckPrototypes(
808 object, receiver_reg, Handle<JSObject>(holder), name_reg,
809 scratch1, scratch2, name, miss_restore_name, SKIP_RECEIVER);
810 // If no property was found, and the holder (the last object in the
811 // prototype chain) is in slow mode, we need to do a negative lookup on the
812 // holder.
813 if (lookup->holder() == *object) {
814 if (holder->IsJSGlobalObject()) {
815 GenerateCheckPropertyCell(
816 masm,
817 Handle<GlobalObject>(GlobalObject::cast(holder)),
818 name,
819 scratch1,
820 miss_restore_name);
821 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
822 GenerateDictionaryNegativeLookup(
823 masm, miss_restore_name, holder_reg, name, scratch1, scratch2);
824 }
825 }
826 }
827
828 Register storage_reg = name_reg;
829
830 if (details.type() == CONSTANT_FUNCTION) { 801 if (details.type() == CONSTANT_FUNCTION) {
831 Handle<HeapObject> constant( 802 Handle<HeapObject> constant(
832 HeapObject::cast(descriptors->GetValue(descriptor))); 803 HeapObject::cast(descriptors->GetValue(descriptor)));
833 __ LoadHeapObject(scratch1, constant); 804 __ LoadHeapObject(scratch1, constant);
834 __ cmpq(value_reg, scratch1); 805 __ cmpq(value_reg, scratch1);
835 __ j(not_equal, miss_restore_name); 806 __ j(not_equal, miss_label);
836 } else if (FLAG_track_fields && representation.IsSmi()) { 807 } else if (FLAG_track_fields && representation.IsSmi()) {
837 __ JumpIfNotSmi(value_reg, miss_restore_name); 808 __ JumpIfNotSmi(value_reg, miss_label);
838 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 809 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
839 __ JumpIfSmi(value_reg, miss_restore_name); 810 __ JumpIfSmi(value_reg, miss_label);
840 } else if (FLAG_track_double_fields && representation.IsDouble()) { 811 } else if (FLAG_track_double_fields && representation.IsDouble()) {
841 Label do_store, heap_number; 812 Label do_store, heap_number;
842 __ AllocateHeapNumber(storage_reg, scratch1, slow); 813 __ AllocateHeapNumber(storage_reg, scratch1, slow);
843 814
844 __ JumpIfNotSmi(value_reg, &heap_number); 815 __ JumpIfNotSmi(value_reg, &heap_number);
845 __ SmiToInteger32(scratch1, value_reg); 816 __ SmiToInteger32(scratch1, value_reg);
846 __ cvtlsi2sd(xmm0, scratch1); 817 __ cvtlsi2sd(xmm0, scratch1);
847 __ jmp(&do_store); 818 __ jmp(&do_store);
848 819
849 __ bind(&heap_number); 820 __ bind(&heap_number);
850 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), 821 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(),
851 miss_restore_name, DONT_DO_SMI_CHECK); 822 miss_label, DONT_DO_SMI_CHECK);
852 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); 823 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
853 824
854 __ bind(&do_store); 825 __ bind(&do_store);
855 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); 826 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0);
856 } 827 }
857 828
858 // Stub never generated for non-global objects that require access 829 // Stub never generated for non-global objects that require access
859 // checks. 830 // checks.
860 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 831 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
861 832
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
911 // Set the property straight into the object. 882 // Set the property straight into the object.
912 int offset = object->map()->instance_size() + (index * kPointerSize); 883 int offset = object->map()->instance_size() + (index * kPointerSize);
913 if (FLAG_track_double_fields && representation.IsDouble()) { 884 if (FLAG_track_double_fields && representation.IsDouble()) {
914 __ movq(FieldOperand(receiver_reg, offset), storage_reg); 885 __ movq(FieldOperand(receiver_reg, offset), storage_reg);
915 } else { 886 } else {
916 __ movq(FieldOperand(receiver_reg, offset), value_reg); 887 __ movq(FieldOperand(receiver_reg, offset), value_reg);
917 } 888 }
918 889
919 if (!FLAG_track_fields || !representation.IsSmi()) { 890 if (!FLAG_track_fields || !representation.IsSmi()) {
920 // Update the write barrier for the array address. 891 // Update the write barrier for the array address.
921 // Pass the value being stored in the now unused name_reg.
922 if (!FLAG_track_double_fields || !representation.IsDouble()) { 892 if (!FLAG_track_double_fields || !representation.IsDouble()) {
923 __ movq(name_reg, value_reg); 893 __ movq(storage_reg, value_reg);
924 } else {
925 ASSERT(storage_reg.is(name_reg));
926 } 894 }
927 __ RecordWriteField( 895 __ RecordWriteField(
928 receiver_reg, offset, name_reg, scratch1, kDontSaveFPRegs, 896 receiver_reg, offset, storage_reg, scratch1, kDontSaveFPRegs,
929 EMIT_REMEMBERED_SET, smi_check); 897 EMIT_REMEMBERED_SET, smi_check);
930 } 898 }
931 } else { 899 } else {
932 // Write to the properties array. 900 // Write to the properties array.
933 int offset = index * kPointerSize + FixedArray::kHeaderSize; 901 int offset = index * kPointerSize + FixedArray::kHeaderSize;
934 // Get the properties array (optimistically). 902 // Get the properties array (optimistically).
935 __ movq(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 903 __ movq(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
936 if (FLAG_track_double_fields && representation.IsDouble()) { 904 if (FLAG_track_double_fields && representation.IsDouble()) {
937 __ movq(FieldOperand(scratch1, offset), storage_reg); 905 __ movq(FieldOperand(scratch1, offset), storage_reg);
938 } else { 906 } else {
939 __ movq(FieldOperand(scratch1, offset), value_reg); 907 __ movq(FieldOperand(scratch1, offset), value_reg);
940 } 908 }
941 909
942 if (!FLAG_track_fields || !representation.IsSmi()) { 910 if (!FLAG_track_fields || !representation.IsSmi()) {
943 // Update the write barrier for the array address. 911 // Update the write barrier for the array address.
944 // Pass the value being stored in the now unused name_reg.
945 if (!FLAG_track_double_fields || !representation.IsDouble()) { 912 if (!FLAG_track_double_fields || !representation.IsDouble()) {
946 __ movq(name_reg, value_reg); 913 __ movq(storage_reg, value_reg);
947 } else {
948 ASSERT(storage_reg.is(name_reg));
949 } 914 }
950 __ RecordWriteField( 915 __ RecordWriteField(
951 scratch1, offset, name_reg, receiver_reg, kDontSaveFPRegs, 916 scratch1, offset, storage_reg, receiver_reg, kDontSaveFPRegs,
952 EMIT_REMEMBERED_SET, smi_check); 917 EMIT_REMEMBERED_SET, smi_check);
953 } 918 }
954 } 919 }
955 920
956 // Return the value (register rax). 921 // Return the value (register rax).
957 ASSERT(value_reg.is(rax)); 922 ASSERT(value_reg.is(rax));
958 __ ret(0); 923 __ ret(0);
959 } 924 }
960 925
961 926
962 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 927 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
963 // but may be destroyed if store is successful. 928 // but may be destroyed if store is successful.
964 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 929 void BaseStoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
965 Handle<JSObject> object, 930 Handle<JSObject> object,
966 LookupResult* lookup, 931 LookupResult* lookup,
967 Register receiver_reg, 932 Register receiver_reg,
968 Register name_reg, 933 Register name_reg,
969 Register value_reg, 934 Register value_reg,
970 Register scratch1, 935 Register scratch1,
971 Register scratch2, 936 Register scratch2,
972 Label* miss_label) { 937 Label* miss_label) {
973 // Check that the map of the object hasn't changed.
974 __ CheckMap(receiver_reg, Handle<Map>(object->map()),
975 miss_label, DO_SMI_CHECK);
976
977 // Perform global security token check if needed.
978 if (object->IsJSGlobalProxy()) {
979 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label);
980 }
981
982 // Stub never generated for non-global objects that require access 938 // Stub never generated for non-global objects that require access
983 // checks. 939 // checks.
984 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 940 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
985 941
986 int index = lookup->GetFieldIndex().field_index(); 942 int index = lookup->GetFieldIndex().field_index();
987 943
988 // Adjust for the number of properties stored in the object. Even in the 944 // Adjust for the number of properties stored in the object. Even in the
989 // face of a transition we can use the old map here because the size of the 945 // face of a transition we can use the old map here because the size of the
990 // object and the number of in-object properties is not going to change. 946 // object and the number of in-object properties is not going to change.
991 index -= object->map()->inobject_properties(); 947 index -= object->map()->inobject_properties();
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1205 // If we've skipped any global objects, it's not enough to verify that 1161 // If we've skipped any global objects, it's not enough to verify that
1206 // their maps haven't changed. We also need to check that the property 1162 // their maps haven't changed. We also need to check that the property
1207 // cell for the property is still empty. 1163 // cell for the property is still empty.
1208 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); 1164 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1209 1165
1210 // Return the register containing the holder. 1166 // Return the register containing the holder.
1211 return reg; 1167 return reg;
1212 } 1168 }
1213 1169
1214 1170
1215 void BaseLoadStubCompiler::HandlerFrontendFooter(Label* success, 1171 void BaseLoadStubCompiler::HandlerFrontendFooter(Handle<Name> name,
1172 Label* success,
1216 Label* miss) { 1173 Label* miss) {
1217 if (!miss->is_unused()) { 1174 if (!miss->is_unused()) {
1218 __ jmp(success); 1175 __ jmp(success);
1219 __ bind(miss); 1176 __ bind(miss);
1220 TailCallBuiltin(masm(), MissBuiltin(kind())); 1177 TailCallBuiltin(masm(), MissBuiltin(kind()));
1221 } 1178 }
1222 } 1179 }
1223 1180
1224 1181
1182 void BaseStoreStubCompiler::HandlerFrontendFooter(Handle<Name> name,
1183 Label* success,
1184 Label* miss) {
1185 if (!miss->is_unused()) {
1186 __ jmp(success);
1187 __ bind(miss);
1188 __ LoadHeapObject(this->name(), name);
1189 TailCallBuiltin(masm(), MissBuiltin(kind()));
1190 }
1191 }
1192
1193
1225 Register BaseLoadStubCompiler::CallbackHandlerFrontend( 1194 Register BaseLoadStubCompiler::CallbackHandlerFrontend(
1226 Handle<JSObject> object, 1195 Handle<JSObject> object,
1227 Register object_reg, 1196 Register object_reg,
1228 Handle<JSObject> holder, 1197 Handle<JSObject> holder,
1229 Handle<Name> name, 1198 Handle<Name> name,
1230 Label* success, 1199 Label* success,
1231 Handle<ExecutableAccessorInfo> callback) { 1200 Handle<ExecutableAccessorInfo> callback) {
1232 Label miss; 1201 Label miss;
1233 1202
1234 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); 1203 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss);
(...skipping 26 matching lines...) Expand all
1261 NameDictionary::kElementsStartIndex * kPointerSize; 1230 NameDictionary::kElementsStartIndex * kPointerSize;
1262 const int kValueOffset = kElementsStartOffset + kPointerSize; 1231 const int kValueOffset = kElementsStartOffset + kPointerSize;
1263 __ movq(scratch2(), 1232 __ movq(scratch2(),
1264 Operand(dictionary, index, times_pointer_size, 1233 Operand(dictionary, index, times_pointer_size,
1265 kValueOffset - kHeapObjectTag)); 1234 kValueOffset - kHeapObjectTag));
1266 __ movq(scratch3(), callback, RelocInfo::EMBEDDED_OBJECT); 1235 __ movq(scratch3(), callback, RelocInfo::EMBEDDED_OBJECT);
1267 __ cmpq(scratch2(), scratch3()); 1236 __ cmpq(scratch2(), scratch3());
1268 __ j(not_equal, &miss); 1237 __ j(not_equal, &miss);
1269 } 1238 }
1270 1239
1271 HandlerFrontendFooter(success, &miss); 1240 HandlerFrontendFooter(name, success, &miss);
1272 return reg; 1241 return reg;
1273 } 1242 }
1274 1243
1275 1244
1276 void BaseLoadStubCompiler::NonexistentHandlerFrontend( 1245 void BaseLoadStubCompiler::NonexistentHandlerFrontend(
1277 Handle<JSObject> object, 1246 Handle<JSObject> object,
1278 Handle<JSObject> last, 1247 Handle<JSObject> last,
1279 Handle<Name> name, 1248 Handle<Name> name,
1280 Label* success, 1249 Label* success,
1281 Handle<GlobalObject> global) { 1250 Handle<GlobalObject> global) {
1282 Label miss; 1251 Label miss;
1283 1252
1284 HandlerFrontendHeader(object, receiver(), last, name, &miss); 1253 HandlerFrontendHeader(object, receiver(), last, name, &miss);
1285 1254
1286 // If the last object in the prototype chain is a global object, 1255 // If the last object in the prototype chain is a global object,
1287 // check that the global property cell is empty. 1256 // check that the global property cell is empty.
1288 if (!global.is_null()) { 1257 if (!global.is_null()) {
1289 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); 1258 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
1290 } 1259 }
1291 1260
1292 HandlerFrontendFooter(success, &miss); 1261 HandlerFrontendFooter(name, success, &miss);
1293 } 1262 }
1294 1263
1295 1264
1296 void BaseLoadStubCompiler::GenerateLoadField(Register reg, 1265 void BaseLoadStubCompiler::GenerateLoadField(Register reg,
1297 Handle<JSObject> holder, 1266 Handle<JSObject> holder,
1298 PropertyIndex field, 1267 PropertyIndex field,
1299 Representation representation) { 1268 Representation representation) {
1300 if (!reg.is(receiver())) __ movq(receiver(), reg); 1269 if (!reg.is(receiver())) __ movq(receiver(), reg);
1301 if (kind() == Code::LOAD_IC) { 1270 if (kind() == Code::LOAD_IC) {
1302 LoadFieldStub stub(field.is_inobject(holder), 1271 LoadFieldStub stub(field.is_inobject(holder),
(...skipping 1364 matching lines...) Expand 10 before | Expand all | Expand 10 after
2667 __ bind(&miss); 2636 __ bind(&miss);
2668 __ IncrementCounter(counters->call_global_inline_miss(), 1); 2637 __ IncrementCounter(counters->call_global_inline_miss(), 1);
2669 GenerateMissBranch(); 2638 GenerateMissBranch();
2670 2639
2671 // Return the generated code. 2640 // Return the generated code.
2672 return GetCode(Code::NORMAL, name); 2641 return GetCode(Code::NORMAL, name);
2673 } 2642 }
2674 2643
2675 2644
2676 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2645 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2677 Handle<Name> name,
2678 Handle<JSObject> object, 2646 Handle<JSObject> object,
2679 Handle<JSObject> holder, 2647 Handle<JSObject> holder,
2648 Handle<Name> name,
2680 Handle<ExecutableAccessorInfo> callback) { 2649 Handle<ExecutableAccessorInfo> callback) {
2681 Label miss; 2650 Label success;
2682 // Check that the maps haven't changed. 2651 HandlerFrontend(object, receiver(), holder, name, &success);
2683 __ JumpIfSmi(receiver(), &miss); 2652 __ bind(&success);
2684 CheckPrototypes(object, receiver(), holder,
2685 scratch1(), scratch2(), scratch3(), name, &miss);
2686
2687 // Stub never generated for non-global objects that require access checks.
2688 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
2689 2653
2690 __ pop(scratch1()); // remove the return address 2654 __ pop(scratch1()); // remove the return address
2691 __ push(receiver()); 2655 __ push(receiver());
2692 __ Push(callback); // callback info 2656 __ Push(callback); // callback info
2693 __ push(this->name()); 2657 __ Push(name);
2694 __ push(value()); 2658 __ push(value());
2695 __ push(scratch1()); // restore return address 2659 __ push(scratch1()); // restore return address
2696 2660
2697 // Do tail-call to the runtime system. 2661 // Do tail-call to the runtime system.
2698 ExternalReference store_callback_property = 2662 ExternalReference store_callback_property =
2699 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 2663 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
2700 __ TailCallExternalReference(store_callback_property, 4, 1); 2664 __ TailCallExternalReference(store_callback_property, 4, 1);
2701 2665
2702 // Handle store cache miss.
2703 __ bind(&miss);
2704 TailCallBuiltin(masm(), MissBuiltin(kind()));
2705
2706 // Return the generated code. 2666 // Return the generated code.
2707 return GetICCode(kind(), Code::CALLBACKS, name); 2667 return GetCode(kind(), Code::CALLBACKS, name);
2708 } 2668 }
2709 2669
2710 2670
2711 #undef __ 2671 #undef __
2712 #define __ ACCESS_MASM(masm) 2672 #define __ ACCESS_MASM(masm)
2713 2673
2714 2674
2715 void StoreStubCompiler::GenerateStoreViaSetter( 2675 void StoreStubCompiler::GenerateStoreViaSetter(
2716 MacroAssembler* masm, 2676 MacroAssembler* masm,
2717 Handle<JSFunction> setter) { 2677 Handle<JSFunction> setter) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2751 } 2711 }
2752 2712
2753 2713
2754 #undef __ 2714 #undef __
2755 #define __ ACCESS_MASM(masm()) 2715 #define __ ACCESS_MASM(masm())
2756 2716
2757 2717
2758 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( 2718 Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
2759 Handle<JSObject> object, 2719 Handle<JSObject> object,
2760 Handle<Name> name) { 2720 Handle<Name> name) {
2761 Label miss;
2762
2763 // Check that the map of the object hasn't changed.
2764 __ CheckMap(receiver(), Handle<Map>(object->map()), &miss, DO_SMI_CHECK);
2765
2766 // Perform global security token check if needed.
2767 if (object->IsJSGlobalProxy()) {
2768 __ CheckAccessGlobalProxy(receiver(), scratch1(), &miss);
2769 }
2770
2771 // Stub never generated for non-global objects that require access
2772 // checks.
2773 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
2774
2775 __ pop(scratch1()); // remove the return address 2721 __ pop(scratch1()); // remove the return address
2776 __ push(receiver()); 2722 __ push(receiver());
2777 __ push(this->name()); 2723 __ push(this->name());
2778 __ push(value()); 2724 __ push(value());
2779 __ Push(Smi::FromInt(strict_mode())); 2725 __ Push(Smi::FromInt(strict_mode()));
2780 __ push(scratch1()); // restore return address 2726 __ push(scratch1()); // restore return address
2781 2727
2782 // Do tail-call to the runtime system. 2728 // Do tail-call to the runtime system.
2783 ExternalReference store_ic_property = 2729 ExternalReference store_ic_property =
2784 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); 2730 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
2785 __ TailCallExternalReference(store_ic_property, 4, 1); 2731 __ TailCallExternalReference(store_ic_property, 4, 1);
2786 2732
2787 // Handle store cache miss.
2788 __ bind(&miss);
2789 TailCallBuiltin(masm(), MissBuiltin(kind()));
2790
2791 // Return the generated code. 2733 // Return the generated code.
2792 return GetICCode(kind(), Code::INTERCEPTOR, name); 2734 return GetCode(kind(), Code::INTERCEPTOR, name);
2793 } 2735 }
2794 2736
2795 2737
2796 Handle<Code> StoreStubCompiler::CompileStoreGlobal( 2738 Handle<Code> StoreStubCompiler::CompileStoreGlobal(
2797 Handle<GlobalObject> object, 2739 Handle<GlobalObject> object,
2798 Handle<PropertyCell> cell, 2740 Handle<PropertyCell> cell,
2799 Handle<Name> name) { 2741 Handle<Name> name) {
2800 Label miss; 2742 Label miss;
2801 2743
2802 // Check that the map of the global has not changed. 2744 // Check that the map of the global has not changed.
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
2993 2935
2994 // Check for deleted property if property can actually be deleted. 2936 // Check for deleted property if property can actually be deleted.
2995 if (!is_dont_delete) { 2937 if (!is_dont_delete) {
2996 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); 2938 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex);
2997 __ j(equal, &miss); 2939 __ j(equal, &miss);
2998 } else if (FLAG_debug_code) { 2940 } else if (FLAG_debug_code) {
2999 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); 2941 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex);
3000 __ Check(not_equal, "DontDelete cells can't contain the hole"); 2942 __ Check(not_equal, "DontDelete cells can't contain the hole");
3001 } 2943 }
3002 2944
3003 HandlerFrontendFooter(&success, &miss); 2945 HandlerFrontendFooter(name, &success, &miss);
3004 __ bind(&success); 2946 __ bind(&success);
3005 2947
3006 Counters* counters = isolate()->counters(); 2948 Counters* counters = isolate()->counters();
3007 __ IncrementCounter(counters->named_load_global_stub(), 1); 2949 __ IncrementCounter(counters->named_load_global_stub(), 1);
3008 __ movq(rax, rbx); 2950 __ movq(rax, rbx);
3009 __ ret(0); 2951 __ ret(0);
3010 2952
3011 // Return the generated code. 2953 // Return the generated code.
3012 return GetICCode(kind(), Code::NORMAL, name); 2954 return GetICCode(kind(), Code::NORMAL, name);
3013 } 2955 }
3014 2956
3015 2957
3016 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( 2958 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
3017 MapHandleList* receiver_maps, 2959 MapHandleList* receiver_maps,
3018 CodeHandleList* handlers, 2960 CodeHandleList* handlers,
3019 Handle<Name> name, 2961 Handle<Name> name,
3020 Code::StubType type, 2962 Code::StubType type,
3021 IcCheckType check) { 2963 IcCheckType check) {
3022 Label miss; 2964 Label miss;
3023 2965
3024 if (check == PROPERTY) { 2966 if (check == PROPERTY) {
3025 GenerateNameCheck(name, this->name(), &miss); 2967 GenerateNameCheck(name, this->name(), &miss);
3026 } 2968 }
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
3573 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); 3515 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3574 } 3516 }
3575 } 3517 }
3576 3518
3577 3519
3578 #undef __ 3520 #undef __
3579 3521
3580 } } // namespace v8::internal 3522 } } // namespace v8::internal
3581 3523
3582 #endif // V8_TARGET_ARCH_X64 3524 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/arm/stub-cache-arm.cc ('K') | « src/x64/ic-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698