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

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

Issue 14850006: Use mutable heapnumbers to store doubles in fields. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: More tests Created 7 years, 7 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
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 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 Register receiver, 362 Register receiver,
363 Register scratch1, 363 Register scratch1,
364 Register scratch2, 364 Register scratch2,
365 Label* miss_label) { 365 Label* miss_label) {
366 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 366 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
367 __ mov(eax, scratch1); 367 __ mov(eax, scratch1);
368 __ ret(0); 368 __ ret(0);
369 } 369 }
370 370
371 371
372 void StubCompiler::DoGenerateFastPropertyLoad(MacroAssembler* masm, 372 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
373 Register dst, 373 Register dst,
374 Register src, 374 Register src,
375 bool inobject, 375 bool inobject,
376 int index) { 376 int index,
377 Representation representation) {
378 ASSERT(!FLAG_track_double_fields || !representation.IsDouble());
377 int offset = index * kPointerSize; 379 int offset = index * kPointerSize;
378 if (!inobject) { 380 if (!inobject) {
379 // Calculate the offset into the properties array. 381 // Calculate the offset into the properties array.
380 offset = offset + FixedArray::kHeaderSize; 382 offset = offset + FixedArray::kHeaderSize;
381 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset)); 383 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset));
382 src = dst; 384 src = dst;
383 } 385 }
384 __ mov(dst, FieldOperand(src, offset)); 386 __ mov(dst, FieldOperand(src, offset));
385 } 387 }
386 388
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 Handle<JSObject> object, 759 Handle<JSObject> object,
758 LookupResult* lookup, 760 LookupResult* lookup,
759 Handle<Map> transition, 761 Handle<Map> transition,
760 Handle<Name> name, 762 Handle<Name> name,
761 Register receiver_reg, 763 Register receiver_reg,
762 Register name_reg, 764 Register name_reg,
763 Register value_reg, 765 Register value_reg,
764 Register scratch1, 766 Register scratch1,
765 Register scratch2, 767 Register scratch2,
766 Label* miss_label, 768 Label* miss_label,
767 Label* miss_restore_name) { 769 Label* miss_restore_name,
770 Label* slow) {
768 // Check that the map of the object hasn't changed. 771 // Check that the map of the object hasn't changed.
769 __ CheckMap(receiver_reg, Handle<Map>(object->map()), 772 __ CheckMap(receiver_reg, Handle<Map>(object->map()),
770 miss_label, DO_SMI_CHECK, REQUIRE_EXACT_MAP); 773 miss_label, DO_SMI_CHECK, REQUIRE_EXACT_MAP);
771 774
772 // Perform global security token check if needed. 775 // Perform global security token check if needed.
773 if (object->IsJSGlobalProxy()) { 776 if (object->IsJSGlobalProxy()) {
774 __ CheckAccessGlobalProxy(receiver_reg, scratch1, scratch2, miss_label); 777 __ CheckAccessGlobalProxy(receiver_reg, scratch1, scratch2, miss_label);
775 } 778 }
776 779
777 int descriptor = transition->LastAdded(); 780 int descriptor = transition->LastAdded();
778 DescriptorArray* descriptors = transition->instance_descriptors(); 781 DescriptorArray* descriptors = transition->instance_descriptors();
779 PropertyDetails details = descriptors->GetDetails(descriptor); 782 PropertyDetails details = descriptors->GetDetails(descriptor);
780 Representation representation = details.representation(); 783 Representation representation = details.representation();
781 ASSERT(!representation.IsNone()); 784 ASSERT(!representation.IsNone());
782 785
783 // Ensure no transitions to deprecated maps are followed. 786 // Ensure no transitions to deprecated maps are followed.
784 __ CheckMapDeprecated(transition, scratch1, miss_label); 787 __ CheckMapDeprecated(transition, scratch1, miss_label);
785 788
786 if (FLAG_track_fields && representation.IsSmi()) {
787 __ JumpIfNotSmi(value_reg, miss_label);
788 } else if (FLAG_track_double_fields && representation.IsDouble()) {
789 Label do_store;
790 __ JumpIfSmi(value_reg, &do_store);
791 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(),
792 miss_label, DONT_DO_SMI_CHECK, REQUIRE_EXACT_MAP);
793 __ bind(&do_store);
794 }
795
796 // Check that we are allowed to write this. 789 // Check that we are allowed to write this.
797 if (object->GetPrototype()->IsJSObject()) { 790 if (object->GetPrototype()->IsJSObject()) {
798 JSObject* holder; 791 JSObject* holder;
799 // holder == object indicates that no property was found. 792 // holder == object indicates that no property was found.
800 if (lookup->holder() != *object) { 793 if (lookup->holder() != *object) {
801 holder = lookup->holder(); 794 holder = lookup->holder();
802 } else { 795 } else {
803 // Find the top object. 796 // Find the top object.
804 holder = *object; 797 holder = *object;
805 do { 798 do {
806 holder = JSObject::cast(holder->GetPrototype()); 799 holder = JSObject::cast(holder->GetPrototype());
807 } while (holder->GetPrototype()->IsJSObject()); 800 } while (holder->GetPrototype()->IsJSObject());
808 } 801 }
809 // We need an extra register, push 802 // We need an extra register, push
810 Register holder_reg = CheckPrototypes( 803 Register holder_reg = CheckPrototypes(
811 object, receiver_reg, Handle<JSObject>(holder), name_reg, 804 object, receiver_reg, Handle<JSObject>(holder), name_reg,
812 scratch1, scratch2, name, miss_restore_name); 805 scratch1, scratch2, name, miss_restore_name, SKIP_RECEIVER);
813 // If no property was found, and the holder (the last object in the 806 // If no property was found, and the holder (the last object in the
814 // prototype chain) is in slow mode, we need to do a negative lookup on the 807 // prototype chain) is in slow mode, we need to do a negative lookup on the
815 // holder. 808 // holder.
816 if (lookup->holder() == *object) { 809 if (lookup->holder() == *object) {
817 if (holder->IsJSGlobalObject()) { 810 if (holder->IsJSGlobalObject()) {
818 GenerateCheckPropertyCell( 811 GenerateCheckPropertyCell(
819 masm, 812 masm,
820 Handle<GlobalObject>(GlobalObject::cast(holder)), 813 Handle<GlobalObject>(GlobalObject::cast(holder)),
821 name, 814 name,
822 scratch1, 815 scratch1,
823 miss_restore_name); 816 miss_restore_name);
824 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { 817 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
825 GenerateDictionaryNegativeLookup( 818 GenerateDictionaryNegativeLookup(
826 masm, miss_restore_name, holder_reg, name, scratch1, scratch2); 819 masm, miss_restore_name, holder_reg, name, scratch1, scratch2);
827 } 820 }
828 } 821 }
829 } 822 }
830 823
824 Register storage_reg = name_reg;
825
826 if (FLAG_track_fields && representation.IsSmi()) {
827 __ JumpIfNotSmi(value_reg, miss_restore_name);
828 } else if (FLAG_track_double_fields && representation.IsDouble()) {
829 // If we allocate a new double holder, store it in name_reg.
830 // Label do_store, heap_number;
831 Label do_store, heap_number;
832 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow);
833
834 __ JumpIfNotSmi(value_reg, &heap_number);
835 if (CpuFeatures::IsSupported(SSE2)) {
836 CpuFeatureScope use_sse2(masm, SSE2);
837 __ SmiUntag(value_reg);
838 __ cvtsi2sd(xmm0, value_reg);
839 __ SmiTag(value_reg);
840 } else {
841 UNREACHABLE();
842 }
843 __ jmp(&do_store);
844
845 __ bind(&heap_number);
846 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(),
847 miss_restore_name, DONT_DO_SMI_CHECK, REQUIRE_EXACT_MAP);
848 if (CpuFeatures::IsSupported(SSE2)) {
849 CpuFeatureScope use_sse2(masm, SSE2);
850 __ movdbl(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
851 } else {
852 UNREACHABLE();
853 }
854
855 __ bind(&do_store);
856 if (CpuFeatures::IsSupported(SSE2)) {
857 CpuFeatureScope use_sse2(masm, SSE2);
858 __ movdbl(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0);
859 } else {
860 UNREACHABLE();
861 }
862 }
863
831 // Stub never generated for non-global objects that require access 864 // Stub never generated for non-global objects that require access
832 // checks. 865 // checks.
833 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 866 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
834 867
835 // Perform map transition for the receiver if necessary. 868 // Perform map transition for the receiver if necessary.
836 if (object->map()->unused_property_fields() == 0) { 869 if (object->map()->unused_property_fields() == 0) {
837 // The properties must be extended before we can store the value. 870 // The properties must be extended before we can store the value.
838 // We jump to a runtime call that extends the properties array. 871 // We jump to a runtime call that extends the properties array.
839 __ pop(scratch1); // Return address. 872 __ pop(scratch1); // Return address.
840 __ push(receiver_reg); 873 __ push(receiver_reg);
841 __ push(Immediate(transition)); 874 __ push(Immediate(transition));
842 __ push(eax); 875 __ push(value_reg);
843 __ push(scratch1); 876 __ push(scratch1);
844 __ TailCallExternalReference( 877 __ TailCallExternalReference(
845 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 878 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
846 masm->isolate()), 879 masm->isolate()),
847 3, 880 3,
848 1); 881 1);
849 return; 882 return;
850 } 883 }
851 884
852 // Update the map of the object. 885 // Update the map of the object.
853 __ mov(scratch1, Immediate(transition)); 886 __ mov(scratch1, Immediate(transition));
854 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); 887 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1);
855 888
856 // Update the write barrier for the map field and pass the now unused 889 // Update the write barrier for the map field.
857 // name_reg as scratch register.
858 __ RecordWriteField(receiver_reg, 890 __ RecordWriteField(receiver_reg,
859 HeapObject::kMapOffset, 891 HeapObject::kMapOffset,
860 scratch1, 892 scratch1,
861 name_reg, 893 scratch2,
862 kDontSaveFPRegs, 894 kDontSaveFPRegs,
863 OMIT_REMEMBERED_SET, 895 OMIT_REMEMBERED_SET,
864 OMIT_SMI_CHECK); 896 OMIT_SMI_CHECK);
865 897
866 int index = transition->instance_descriptors()->GetFieldIndex( 898 int index = transition->instance_descriptors()->GetFieldIndex(
867 transition->LastAdded()); 899 transition->LastAdded());
868 900
869 // Adjust for the number of properties stored in the object. Even in the 901 // Adjust for the number of properties stored in the object. Even in the
870 // face of a transition we can use the old map here because the size of the 902 // face of a transition we can use the old map here because the size of the
871 // object and the number of in-object properties is not going to change. 903 // object and the number of in-object properties is not going to change.
872 index -= object->map()->inobject_properties(); 904 index -= object->map()->inobject_properties();
873 905
874 // TODO(verwaest): Share this code as a code stub. 906 // TODO(verwaest): Share this code as a code stub.
875 if (index < 0) { 907 if (index < 0) {
876 // Set the property straight into the object. 908 // Set the property straight into the object.
877 int offset = object->map()->instance_size() + (index * kPointerSize); 909 int offset = object->map()->instance_size() + (index * kPointerSize);
878 __ mov(FieldOperand(receiver_reg, offset), value_reg); 910 if (FLAG_track_double_fields && representation.IsDouble()) {
911 __ mov(FieldOperand(receiver_reg, offset), storage_reg);
912 } else {
913 __ mov(FieldOperand(receiver_reg, offset), value_reg);
914 }
879 915
880 if (!FLAG_track_fields || !representation.IsSmi()) { 916 if (!FLAG_track_fields || !representation.IsSmi()) {
881 // Update the write barrier for the array address. 917 // Update the write barrier for the array address.
882 // Pass the value being stored in the now unused name_reg. 918 // Pass the value being stored in the now unused name_reg.
883 __ mov(name_reg, value_reg); 919 if (!FLAG_track_double_fields || !representation.IsDouble()) {
920 __ mov(name_reg, value_reg);
921 } else {
922 ASSERT(storage_reg.is(name_reg));
923 }
884 __ RecordWriteField(receiver_reg, 924 __ RecordWriteField(receiver_reg,
885 offset, 925 offset,
886 name_reg, 926 name_reg,
887 scratch1, 927 scratch1,
888 kDontSaveFPRegs); 928 kDontSaveFPRegs);
889 } 929 }
890 } else { 930 } else {
891 // Write to the properties array. 931 // Write to the properties array.
892 int offset = index * kPointerSize + FixedArray::kHeaderSize; 932 int offset = index * kPointerSize + FixedArray::kHeaderSize;
893 // Get the properties array (optimistically). 933 // Get the properties array (optimistically).
894 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 934 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
895 __ mov(FieldOperand(scratch1, offset), eax); 935 if (FLAG_track_double_fields && representation.IsDouble()) {
936 __ mov(FieldOperand(scratch1, offset), storage_reg);
937 } else {
938 __ mov(FieldOperand(scratch1, offset), value_reg);
939 }
896 940
897 if (!FLAG_track_fields || !representation.IsSmi()) { 941 if (!FLAG_track_fields || !representation.IsSmi()) {
898 // Update the write barrier for the array address. 942 // Update the write barrier for the array address.
899 // Pass the value being stored in the now unused name_reg. 943 // Pass the value being stored in the now unused name_reg.
900 __ mov(name_reg, value_reg); 944 if (!FLAG_track_double_fields || !representation.IsDouble()) {
945 __ mov(name_reg, value_reg);
946 } else {
947 ASSERT(storage_reg.is(name_reg));
948 }
901 __ RecordWriteField(scratch1, 949 __ RecordWriteField(scratch1,
902 offset, 950 offset,
903 name_reg, 951 name_reg,
904 receiver_reg, 952 receiver_reg,
905 kDontSaveFPRegs); 953 kDontSaveFPRegs);
906 } 954 }
907 } 955 }
908 956
909 // Return the value (register eax). 957 // Return the value (register eax).
910 ASSERT(value_reg.is(eax)); 958 ASSERT(value_reg.is(eax));
(...skipping 30 matching lines...) Expand all
941 // Adjust for the number of properties stored in the object. Even in the 989 // Adjust for the number of properties stored in the object. Even in the
942 // face of a transition we can use the old map here because the size of the 990 // face of a transition we can use the old map here because the size of the
943 // object and the number of in-object properties is not going to change. 991 // object and the number of in-object properties is not going to change.
944 index -= object->map()->inobject_properties(); 992 index -= object->map()->inobject_properties();
945 993
946 Representation representation = lookup->representation(); 994 Representation representation = lookup->representation();
947 ASSERT(!representation.IsNone()); 995 ASSERT(!representation.IsNone());
948 if (FLAG_track_fields && representation.IsSmi()) { 996 if (FLAG_track_fields && representation.IsSmi()) {
949 __ JumpIfNotSmi(value_reg, miss_label); 997 __ JumpIfNotSmi(value_reg, miss_label);
950 } else if (FLAG_track_double_fields && representation.IsDouble()) { 998 } else if (FLAG_track_double_fields && representation.IsDouble()) {
951 Label do_store; 999 // Load the double storage.
952 __ JumpIfSmi(value_reg, &do_store); 1000 if (index < 0) {
1001 int offset = object->map()->instance_size() + (index * kPointerSize);
1002 __ mov(scratch1, FieldOperand(receiver_reg, offset));
1003 } else {
1004 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
1005 int offset = index * kPointerSize + FixedArray::kHeaderSize;
1006 __ mov(scratch1, FieldOperand(scratch1, offset));
1007 }
1008
1009 // If we allocate a new double holder, store it in name_reg.
1010 // Label do_store, heap_number;
1011 Label do_store, heap_number;
1012 __ JumpIfNotSmi(value_reg, &heap_number);
1013 if (CpuFeatures::IsSupported(SSE2)) {
1014 CpuFeatureScope use_sse2(masm, SSE2);
1015 __ SmiUntag(value_reg);
1016 __ cvtsi2sd(xmm0, value_reg);
1017 __ SmiTag(value_reg);
1018 } else {
1019 UNREACHABLE();
1020 }
1021 __ jmp(&do_store);
1022 __ bind(&heap_number);
953 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), 1023 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(),
954 miss_label, DONT_DO_SMI_CHECK, REQUIRE_EXACT_MAP); 1024 miss_label, DONT_DO_SMI_CHECK, REQUIRE_EXACT_MAP);
1025 if (CpuFeatures::IsSupported(SSE2)) {
1026 CpuFeatureScope use_sse2(masm, SSE2);
1027 __ movdbl(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
1028 } else {
1029 UNREACHABLE();
1030 }
955 __ bind(&do_store); 1031 __ bind(&do_store);
1032 if (CpuFeatures::IsSupported(SSE2)) {
1033 CpuFeatureScope use_sse2(masm, SSE2);
1034 __ movdbl(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0);
1035 } else {
1036 UNREACHABLE();
1037 }
1038 // Return the value (register eax).
1039 ASSERT(value_reg.is(eax));
1040 __ ret(0);
1041 return;
956 } 1042 }
957 1043
1044 ASSERT(!FLAG_track_double_fields || !representation.IsDouble());
958 // TODO(verwaest): Share this code as a code stub. 1045 // TODO(verwaest): Share this code as a code stub.
959 if (index < 0) { 1046 if (index < 0) {
960 // Set the property straight into the object. 1047 // Set the property straight into the object.
961 int offset = object->map()->instance_size() + (index * kPointerSize); 1048 int offset = object->map()->instance_size() + (index * kPointerSize);
962 __ mov(FieldOperand(receiver_reg, offset), value_reg); 1049 __ mov(FieldOperand(receiver_reg, offset), value_reg);
963 1050
964 if (!FLAG_track_fields || !representation.IsSmi()) { 1051 if (!FLAG_track_fields || !representation.IsSmi()) {
965 // Update the write barrier for the array address. 1052 // Update the write barrier for the array address.
966 // Pass the value being stored in the now unused name_reg. 1053 // Pass the value being stored in the now unused name_reg.
967 __ mov(name_reg, value_reg); 1054 __ mov(name_reg, value_reg);
968 __ RecordWriteField(receiver_reg, 1055 __ RecordWriteField(receiver_reg,
969 offset, 1056 offset,
970 name_reg, 1057 name_reg,
971 scratch1, 1058 scratch1,
972 kDontSaveFPRegs); 1059 kDontSaveFPRegs);
973 } 1060 }
974 } else { 1061 } else {
975 // Write to the properties array. 1062 // Write to the properties array.
976 int offset = index * kPointerSize + FixedArray::kHeaderSize; 1063 int offset = index * kPointerSize + FixedArray::kHeaderSize;
977 // Get the properties array (optimistically). 1064 // Get the properties array (optimistically).
978 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 1065 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
979 __ mov(FieldOperand(scratch1, offset), eax); 1066 __ mov(FieldOperand(scratch1, offset), value_reg);
980 1067
981 if (!FLAG_track_fields || !representation.IsSmi()) { 1068 if (!FLAG_track_fields || !representation.IsSmi()) {
982 // Update the write barrier for the array address. 1069 // Update the write barrier for the array address.
983 // Pass the value being stored in the now unused name_reg. 1070 // Pass the value being stored in the now unused name_reg.
984 __ mov(name_reg, value_reg); 1071 __ mov(name_reg, value_reg);
985 __ RecordWriteField(scratch1, 1072 __ RecordWriteField(scratch1,
986 offset, 1073 offset,
987 name_reg, 1074 name_reg,
988 receiver_reg, 1075 receiver_reg,
989 kDontSaveFPRegs); 1076 kDontSaveFPRegs);
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1229 if (!global.is_null()) { 1316 if (!global.is_null()) {
1230 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); 1317 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
1231 } 1318 }
1232 1319
1233 HandlerFrontendFooter(success, &miss); 1320 HandlerFrontendFooter(success, &miss);
1234 } 1321 }
1235 1322
1236 1323
1237 void BaseLoadStubCompiler::GenerateLoadField(Register reg, 1324 void BaseLoadStubCompiler::GenerateLoadField(Register reg,
1238 Handle<JSObject> holder, 1325 Handle<JSObject> holder,
1239 PropertyIndex field) { 1326 PropertyIndex field,
1327 Representation representation) {
1240 if (!reg.is(receiver())) __ mov(receiver(), reg); 1328 if (!reg.is(receiver())) __ mov(receiver(), reg);
1241 if (kind() == Code::LOAD_IC) { 1329 if (kind() == Code::LOAD_IC) {
1242 LoadFieldStub stub(field.is_inobject(holder), 1330 LoadFieldStub stub(field.is_inobject(holder),
1243 field.translate(holder)); 1331 field.translate(holder),
1332 representation);
1244 GenerateTailCall(masm(), stub.GetCode(isolate())); 1333 GenerateTailCall(masm(), stub.GetCode(isolate()));
1245 } else { 1334 } else {
1246 KeyedLoadFieldStub stub(field.is_inobject(holder), 1335 KeyedLoadFieldStub stub(field.is_inobject(holder),
1247 field.translate(holder)); 1336 field.translate(holder),
1337 representation);
1248 GenerateTailCall(masm(), stub.GetCode(isolate())); 1338 GenerateTailCall(masm(), stub.GetCode(isolate()));
1249 } 1339 }
1250 } 1340 }
1251 1341
1252 1342
1253 void BaseLoadStubCompiler::GenerateLoadCallback( 1343 void BaseLoadStubCompiler::GenerateLoadCallback(
1254 Register reg, 1344 Register reg,
1255 Handle<ExecutableAccessorInfo> callback) { 1345 Handle<ExecutableAccessorInfo> callback) {
1256 // Insert additional parameters into the stack frame above return address. 1346 // Insert additional parameters into the stack frame above return address.
1257 ASSERT(!scratch3().is(reg)); 1347 ASSERT(!scratch3().is(reg));
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1494 const int argc = arguments().immediate(); 1584 const int argc = arguments().immediate();
1495 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1585 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1496 1586
1497 // Check that the receiver isn't a smi. 1587 // Check that the receiver isn't a smi.
1498 __ JumpIfSmi(edx, &miss); 1588 __ JumpIfSmi(edx, &miss);
1499 1589
1500 // Do the right check and compute the holder register. 1590 // Do the right check and compute the holder register.
1501 Register reg = CheckPrototypes(object, edx, holder, ebx, eax, edi, 1591 Register reg = CheckPrototypes(object, edx, holder, ebx, eax, edi,
1502 name, &miss); 1592 name, &miss);
1503 1593
1504 GenerateFastPropertyLoad(masm(), edi, reg, holder, index); 1594 GenerateFastPropertyLoad(
1595 masm(), edi, reg, index.is_inobject(holder),
1596 index.translate(holder), Representation::Tagged());
1505 1597
1506 // Check that the function really is a function. 1598 // Check that the function really is a function.
1507 __ JumpIfSmi(edi, &miss); 1599 __ JumpIfSmi(edi, &miss);
1508 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); 1600 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
1509 __ j(not_equal, &miss); 1601 __ j(not_equal, &miss);
1510 1602
1511 // Patch the receiver on the stack with the global proxy if 1603 // Patch the receiver on the stack with the global proxy if
1512 // necessary. 1604 // necessary.
1513 if (object->IsGlobalObject()) { 1605 if (object->IsGlobalObject()) {
1514 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 1606 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
(...skipping 2235 matching lines...) Expand 10 before | Expand all | Expand 10 after
3750 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); 3842 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3751 } 3843 }
3752 } 3844 }
3753 3845
3754 3846
3755 #undef __ 3847 #undef __
3756 3848
3757 } } // namespace v8::internal 3849 } } // namespace v8::internal
3758 3850
3759 #endif // V8_TARGET_ARCH_IA32 3851 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« src/ia32/ic-ia32.cc ('K') | « src/ia32/lithium-ia32.cc ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698