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

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

Powered by Google App Engine
This is Rietveld 408576698