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

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: 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 if (FLAG_track_fields && representation.IsSmi()) {
825 __ JumpIfNotSmi(value_reg, miss_restore_name);
826 } else if (FLAG_track_double_fields && representation.IsDouble()) {
827 // If we allocate a new double holder, store it in name_reg.
828 // Label do_store, heap_number;
829 Label do_store, heap_number;
830 __ JumpIfNotSmi(value_reg, &heap_number);
831
832 if (CpuFeatures::IsSupported(SSE2)) {
833 CpuFeatureScope use_sse2(masm, SSE2);
834 __ AllocateHeapNumber(name_reg, scratch1, scratch2, slow);
835 __ SmiUntag(value_reg);
836 __ cvtsi2sd(xmm0, value_reg);
837 __ SmiTag(value_reg);
838 } else {
839 UNREACHABLE();
840 }
841 __ jmp(&do_store);
842
843 __ bind(&heap_number);
844 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(),
845 miss_restore_name, DONT_DO_SMI_CHECK, REQUIRE_EXACT_MAP);
846 if (CpuFeatures::IsSupported(SSE2)) {
847 CpuFeatureScope use_sse2(masm, SSE2);
848 __ AllocateHeapNumber(name_reg, scratch1, scratch2, slow);
849 __ movdbl(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
850 } else {
851 UNREACHABLE();
852 }
853
854 __ bind(&do_store);
855 if (CpuFeatures::IsSupported(SSE2)) {
856 CpuFeatureScope use_sse2(masm, SSE2);
857 __ movdbl(FieldOperand(name_reg, HeapNumber::kValueOffset), xmm0);
858 } else {
859 UNREACHABLE();
860 }
861 }
862
831 // Stub never generated for non-global objects that require access 863 // Stub never generated for non-global objects that require access
832 // checks. 864 // checks.
833 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 865 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
834 866
835 // Perform map transition for the receiver if necessary. 867 // Perform map transition for the receiver if necessary.
836 if (object->map()->unused_property_fields() == 0) { 868 if (object->map()->unused_property_fields() == 0) {
837 // The properties must be extended before we can store the value. 869 // The properties must be extended before we can store the value.
838 // We jump to a runtime call that extends the properties array. 870 // We jump to a runtime call that extends the properties array.
839 __ pop(scratch1); // Return address. 871 __ pop(scratch1); // Return address.
840 __ push(receiver_reg); 872 __ push(receiver_reg);
841 __ push(Immediate(transition)); 873 __ push(Immediate(transition));
842 __ push(eax); 874 __ push(value_reg);
843 __ push(scratch1); 875 __ push(scratch1);
844 __ TailCallExternalReference( 876 __ TailCallExternalReference(
845 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 877 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
846 masm->isolate()), 878 masm->isolate()),
847 3, 879 3,
848 1); 880 1);
849 return; 881 return;
850 } 882 }
851 883
852 // Update the map of the object. 884 // Update the map of the object.
853 __ mov(scratch1, Immediate(transition)); 885 __ mov(scratch1, Immediate(transition));
854 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); 886 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1);
855 887
856 // Update the write barrier for the map field and pass the now unused 888 // Update the write barrier for the map field.
857 // name_reg as scratch register.
858 __ RecordWriteField(receiver_reg, 889 __ RecordWriteField(receiver_reg,
859 HeapObject::kMapOffset, 890 HeapObject::kMapOffset,
860 scratch1, 891 scratch1,
861 name_reg, 892 scratch2,
862 kDontSaveFPRegs, 893 kDontSaveFPRegs,
863 OMIT_REMEMBERED_SET, 894 OMIT_REMEMBERED_SET,
864 OMIT_SMI_CHECK); 895 OMIT_SMI_CHECK);
865 896
866 int index = transition->instance_descriptors()->GetFieldIndex( 897 int index = transition->instance_descriptors()->GetFieldIndex(
867 transition->LastAdded()); 898 transition->LastAdded());
868 899
869 // Adjust for the number of properties stored in the object. Even in the 900 // 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 901 // 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. 902 // object and the number of in-object properties is not going to change.
872 index -= object->map()->inobject_properties(); 903 index -= object->map()->inobject_properties();
873 904
874 // TODO(verwaest): Share this code as a code stub. 905 // TODO(verwaest): Share this code as a code stub.
875 if (index < 0) { 906 if (index < 0) {
876 // Set the property straight into the object. 907 // Set the property straight into the object.
877 int offset = object->map()->instance_size() + (index * kPointerSize); 908 int offset = object->map()->instance_size() + (index * kPointerSize);
878 __ mov(FieldOperand(receiver_reg, offset), value_reg); 909 if (FLAG_track_double_fields && representation.IsDouble()) {
910 __ mov(FieldOperand(receiver_reg, offset), name_reg);
danno 2013/05/07 13:04:47 Give this name_reg guy another name?
Toon Verwaest 2013/05/07 15:08:52 Done.
911 } else {
912 __ mov(FieldOperand(receiver_reg, offset), value_reg);
913 }
879 914
880 if (!FLAG_track_fields || !representation.IsSmi()) { 915 if (!FLAG_track_fields || !representation.IsSmi()) {
881 // Update the write barrier for the array address. 916 // Update the write barrier for the array address.
882 // Pass the value being stored in the now unused name_reg. 917 // Pass the value being stored in the now unused name_reg.
883 __ mov(name_reg, value_reg); 918 if (!FLAG_track_double_fields || !representation.IsDouble()) {
919 __ mov(name_reg, value_reg);
920 }
884 __ RecordWriteField(receiver_reg, 921 __ RecordWriteField(receiver_reg,
885 offset, 922 offset,
886 name_reg, 923 name_reg,
887 scratch1, 924 scratch1,
888 kDontSaveFPRegs); 925 kDontSaveFPRegs);
889 } 926 }
890 } else { 927 } else {
891 // Write to the properties array. 928 // Write to the properties array.
892 int offset = index * kPointerSize + FixedArray::kHeaderSize; 929 int offset = index * kPointerSize + FixedArray::kHeaderSize;
893 // Get the properties array (optimistically). 930 // Get the properties array (optimistically).
894 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 931 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
895 __ mov(FieldOperand(scratch1, offset), eax); 932 if (FLAG_track_double_fields && representation.IsDouble()) {
933 __ mov(FieldOperand(scratch1, offset), name_reg);
934 } else {
935 __ mov(FieldOperand(scratch1, offset), value_reg);
936 }
896 937
897 if (!FLAG_track_fields || !representation.IsSmi()) { 938 if (!FLAG_track_fields || !representation.IsSmi()) {
898 // Update the write barrier for the array address. 939 // Update the write barrier for the array address.
899 // Pass the value being stored in the now unused name_reg. 940 // Pass the value being stored in the now unused name_reg.
900 __ mov(name_reg, value_reg); 941 if (!FLAG_track_double_fields || !representation.IsDouble()) {
942 __ mov(name_reg, value_reg);
943 }
901 __ RecordWriteField(scratch1, 944 __ RecordWriteField(scratch1,
902 offset, 945 offset,
903 name_reg, 946 name_reg,
904 receiver_reg, 947 receiver_reg,
905 kDontSaveFPRegs); 948 kDontSaveFPRegs);
906 } 949 }
907 } 950 }
908 951
909 // Return the value (register eax). 952 // Return the value (register eax).
910 ASSERT(value_reg.is(eax)); 953 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 984 // 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 985 // 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. 986 // object and the number of in-object properties is not going to change.
944 index -= object->map()->inobject_properties(); 987 index -= object->map()->inobject_properties();
945 988
946 Representation representation = lookup->representation(); 989 Representation representation = lookup->representation();
947 ASSERT(!representation.IsNone()); 990 ASSERT(!representation.IsNone());
948 if (FLAG_track_fields && representation.IsSmi()) { 991 if (FLAG_track_fields && representation.IsSmi()) {
949 __ JumpIfNotSmi(value_reg, miss_label); 992 __ JumpIfNotSmi(value_reg, miss_label);
950 } else if (FLAG_track_double_fields && representation.IsDouble()) { 993 } else if (FLAG_track_double_fields && representation.IsDouble()) {
951 Label do_store; 994 // Load the double storage.
952 __ JumpIfSmi(value_reg, &do_store); 995 if (index < 0) {
996 int offset = object->map()->instance_size() + (index * kPointerSize);
997 __ mov(scratch1, FieldOperand(receiver_reg, offset));
998 } else {
999 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
1000 int offset = index * kPointerSize + FixedArray::kHeaderSize;
1001 __ mov(scratch1, FieldOperand(scratch1, offset));
1002 }
1003
1004 // If we allocate a new double holder, store it in name_reg.
1005 // Label do_store, heap_number;
1006 Label do_store, heap_number;
1007 __ JumpIfNotSmi(value_reg, &heap_number);
1008 if (CpuFeatures::IsSupported(SSE2)) {
1009 CpuFeatureScope use_sse2(masm, SSE2);
1010 __ SmiUntag(value_reg);
1011 __ cvtsi2sd(xmm0, value_reg);
1012 __ SmiTag(value_reg);
1013 } else {
1014 UNREACHABLE();
1015 }
1016 __ jmp(&do_store);
1017 __ bind(&heap_number);
953 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), 1018 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(),
954 miss_label, DONT_DO_SMI_CHECK, REQUIRE_EXACT_MAP); 1019 miss_label, DONT_DO_SMI_CHECK, REQUIRE_EXACT_MAP);
1020 if (CpuFeatures::IsSupported(SSE2)) {
1021 CpuFeatureScope use_sse2(masm, SSE2);
1022 __ movdbl(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
1023 } else {
1024 UNREACHABLE();
1025 }
955 __ bind(&do_store); 1026 __ bind(&do_store);
1027 if (CpuFeatures::IsSupported(SSE2)) {
1028 CpuFeatureScope use_sse2(masm, SSE2);
1029 __ movdbl(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0);
1030 } else {
1031 UNREACHABLE();
1032 }
1033 // Return the value (register eax).
1034 ASSERT(value_reg.is(eax));
1035 __ ret(0);
1036 return;
956 } 1037 }
957 1038
958 // TODO(verwaest): Share this code as a code stub. 1039 // TODO(verwaest): Share this code as a code stub.
959 if (index < 0) { 1040 if (index < 0) {
960 // Set the property straight into the object. 1041 // Set the property straight into the object.
961 int offset = object->map()->instance_size() + (index * kPointerSize); 1042 int offset = object->map()->instance_size() + (index * kPointerSize);
962 __ mov(FieldOperand(receiver_reg, offset), value_reg); 1043 if (FLAG_track_double_fields && representation.IsDouble()) {
1044 __ mov(FieldOperand(receiver_reg, offset), name_reg);
1045 } else {
1046 __ mov(FieldOperand(receiver_reg, offset), value_reg);
1047 }
963 1048
964 if (!FLAG_track_fields || !representation.IsSmi()) { 1049 if (!FLAG_track_fields || !representation.IsSmi()) {
965 // Update the write barrier for the array address. 1050 // Update the write barrier for the array address.
966 // Pass the value being stored in the now unused name_reg. 1051 // Pass the value being stored in the now unused name_reg.
967 __ mov(name_reg, value_reg); 1052 if (!FLAG_track_double_fields || !representation.IsDouble()) {
1053 __ mov(name_reg, value_reg);
1054 }
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 if (FLAG_track_double_fields && representation.IsDouble()) {
1067 __ mov(FieldOperand(scratch1, offset), name_reg);
1068 } else {
1069 __ mov(FieldOperand(scratch1, offset), value_reg);
1070 }
980 1071
981 if (!FLAG_track_fields || !representation.IsSmi()) { 1072 if (!FLAG_track_fields || !representation.IsSmi()) {
982 // Update the write barrier for the array address. 1073 // Update the write barrier for the array address.
983 // Pass the value being stored in the now unused name_reg. 1074 // Pass the value being stored in the now unused name_reg.
984 __ mov(name_reg, value_reg); 1075 if (!FLAG_track_double_fields || !representation.IsDouble()) {
1076 __ mov(name_reg, value_reg);
1077 }
985 __ RecordWriteField(scratch1, 1078 __ RecordWriteField(scratch1,
danno 2013/05/07 13:04:47 Remove the write barrier in the double case
Toon Verwaest 2013/05/07 15:08:52 Done. This was already done by returning in case o
986 offset, 1079 offset,
987 name_reg, 1080 name_reg,
988 receiver_reg, 1081 receiver_reg,
989 kDontSaveFPRegs); 1082 kDontSaveFPRegs);
990 } 1083 }
991 } 1084 }
992 1085
993 // Return the value (register eax). 1086 // Return the value (register eax).
994 ASSERT(value_reg.is(eax)); 1087 ASSERT(value_reg.is(eax));
995 __ ret(0); 1088 __ ret(0);
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1229 if (!global.is_null()) { 1322 if (!global.is_null()) {
1230 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); 1323 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
1231 } 1324 }
1232 1325
1233 HandlerFrontendFooter(success, &miss); 1326 HandlerFrontendFooter(success, &miss);
1234 } 1327 }
1235 1328
1236 1329
1237 void BaseLoadStubCompiler::GenerateLoadField(Register reg, 1330 void BaseLoadStubCompiler::GenerateLoadField(Register reg,
1238 Handle<JSObject> holder, 1331 Handle<JSObject> holder,
1239 PropertyIndex field) { 1332 PropertyIndex field,
1333 Representation representation) {
1240 if (!reg.is(receiver())) __ mov(receiver(), reg); 1334 if (!reg.is(receiver())) __ mov(receiver(), reg);
1241 if (kind() == Code::LOAD_IC) { 1335 if (kind() == Code::LOAD_IC) {
1242 LoadFieldStub stub(field.is_inobject(holder), 1336 LoadFieldStub stub(field.is_inobject(holder),
1243 field.translate(holder)); 1337 field.translate(holder),
1338 representation);
1244 GenerateTailCall(masm(), stub.GetCode(isolate())); 1339 GenerateTailCall(masm(), stub.GetCode(isolate()));
1245 } else { 1340 } else {
1246 KeyedLoadFieldStub stub(field.is_inobject(holder), 1341 KeyedLoadFieldStub stub(field.is_inobject(holder),
1247 field.translate(holder)); 1342 field.translate(holder),
1343 representation);
1248 GenerateTailCall(masm(), stub.GetCode(isolate())); 1344 GenerateTailCall(masm(), stub.GetCode(isolate()));
1249 } 1345 }
1250 } 1346 }
1251 1347
1252 1348
1253 void BaseLoadStubCompiler::GenerateLoadCallback( 1349 void BaseLoadStubCompiler::GenerateLoadCallback(
1254 Register reg, 1350 Register reg,
1255 Handle<ExecutableAccessorInfo> callback) { 1351 Handle<ExecutableAccessorInfo> callback) {
1256 // Insert additional parameters into the stack frame above return address. 1352 // Insert additional parameters into the stack frame above return address.
1257 ASSERT(!scratch3().is(reg)); 1353 ASSERT(!scratch3().is(reg));
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1494 const int argc = arguments().immediate(); 1590 const int argc = arguments().immediate();
1495 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1591 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1496 1592
1497 // Check that the receiver isn't a smi. 1593 // Check that the receiver isn't a smi.
1498 __ JumpIfSmi(edx, &miss); 1594 __ JumpIfSmi(edx, &miss);
1499 1595
1500 // Do the right check and compute the holder register. 1596 // Do the right check and compute the holder register.
1501 Register reg = CheckPrototypes(object, edx, holder, ebx, eax, edi, 1597 Register reg = CheckPrototypes(object, edx, holder, ebx, eax, edi,
1502 name, &miss); 1598 name, &miss);
1503 1599
1504 GenerateFastPropertyLoad(masm(), edi, reg, holder, index); 1600 GenerateFastPropertyLoad(
1601 masm(), edi, reg, index.is_inobject(holder),
1602 index.translate(holder), Representation::Tagged());
1505 1603
1506 // Check that the function really is a function. 1604 // Check that the function really is a function.
1507 __ JumpIfSmi(edi, &miss); 1605 __ JumpIfSmi(edi, &miss);
1508 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); 1606 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
1509 __ j(not_equal, &miss); 1607 __ j(not_equal, &miss);
1510 1608
1511 // Patch the receiver on the stack with the global proxy if 1609 // Patch the receiver on the stack with the global proxy if
1512 // necessary. 1610 // necessary.
1513 if (object->IsGlobalObject()) { 1611 if (object->IsGlobalObject()) {
1514 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 1612 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
(...skipping 2235 matching lines...) Expand 10 before | Expand all | Expand 10 after
3750 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); 3848 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3751 } 3849 }
3752 } 3850 }
3753 3851
3754 3852
3755 #undef __ 3853 #undef __
3756 3854
3757 } } // namespace v8::internal 3855 } } // namespace v8::internal
3758 3856
3759 #endif // V8_TARGET_ARCH_IA32 3857 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698