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

Side by Side Diff: src/arm/ic-arm.cc

Issue 7060010: Merge bleeding edge into the GC branch up to 7948. The asserts (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 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/arm/full-codegen-arm.cc ('k') | src/arm/lithium-arm.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 __ b(ne, miss); 98 __ b(ne, miss);
99 99
100 __ ldr(elements, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 100 __ ldr(elements, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
101 __ ldr(t1, FieldMemOperand(elements, HeapObject::kMapOffset)); 101 __ ldr(t1, FieldMemOperand(elements, HeapObject::kMapOffset));
102 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); 102 __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
103 __ cmp(t1, ip); 103 __ cmp(t1, ip);
104 __ b(ne, miss); 104 __ b(ne, miss);
105 } 105 }
106 106
107 107
108 // Probe the string dictionary in the |elements| register. Jump to the
109 // |done| label if a property with the given name is found. Jump to
110 // the |miss| label otherwise.
111 static void GenerateStringDictionaryProbes(MacroAssembler* masm,
112 Label* miss,
113 Label* done,
114 Register elements,
115 Register name,
116 Register scratch1,
117 Register scratch2) {
118 // Assert that name contains a string.
119 if (FLAG_debug_code) __ AbortIfNotString(name);
120
121 // Compute the capacity mask.
122 const int kCapacityOffset = StringDictionary::kHeaderSize +
123 StringDictionary::kCapacityIndex * kPointerSize;
124 __ ldr(scratch1, FieldMemOperand(elements, kCapacityOffset));
125 __ mov(scratch1, Operand(scratch1, ASR, kSmiTagSize)); // convert smi to int
126 __ sub(scratch1, scratch1, Operand(1));
127
128 const int kElementsStartOffset = StringDictionary::kHeaderSize +
129 StringDictionary::kElementsStartIndex * kPointerSize;
130
131 // Generate an unrolled loop that performs a few probes before
132 // giving up. Measurements done on Gmail indicate that 2 probes
133 // cover ~93% of loads from dictionaries.
134 static const int kProbes = 4;
135 for (int i = 0; i < kProbes; i++) {
136 // Compute the masked index: (hash + i + i * i) & mask.
137 __ ldr(scratch2, FieldMemOperand(name, String::kHashFieldOffset));
138 if (i > 0) {
139 // Add the probe offset (i + i * i) left shifted to avoid right shifting
140 // the hash in a separate instruction. The value hash + i + i * i is right
141 // shifted in the following and instruction.
142 ASSERT(StringDictionary::GetProbeOffset(i) <
143 1 << (32 - String::kHashFieldOffset));
144 __ add(scratch2, scratch2, Operand(
145 StringDictionary::GetProbeOffset(i) << String::kHashShift));
146 }
147 __ and_(scratch2, scratch1, Operand(scratch2, LSR, String::kHashShift));
148
149 // Scale the index by multiplying by the element size.
150 ASSERT(StringDictionary::kEntrySize == 3);
151 // scratch2 = scratch2 * 3.
152 __ add(scratch2, scratch2, Operand(scratch2, LSL, 1));
153
154 // Check if the key is identical to the name.
155 __ add(scratch2, elements, Operand(scratch2, LSL, 2));
156 __ ldr(ip, FieldMemOperand(scratch2, kElementsStartOffset));
157 __ cmp(name, Operand(ip));
158 if (i != kProbes - 1) {
159 __ b(eq, done);
160 } else {
161 __ b(ne, miss);
162 }
163 }
164 }
165
166
167 // Helper function used from LoadIC/CallIC GenerateNormal. 108 // Helper function used from LoadIC/CallIC GenerateNormal.
168 // 109 //
169 // elements: Property dictionary. It is not clobbered if a jump to the miss 110 // elements: Property dictionary. It is not clobbered if a jump to the miss
170 // label is done. 111 // label is done.
171 // name: Property name. It is not clobbered if a jump to the miss label is 112 // name: Property name. It is not clobbered if a jump to the miss label is
172 // done 113 // done
173 // result: Register for the result. It is only updated if a jump to the miss 114 // result: Register for the result. It is only updated if a jump to the miss
174 // label is not done. Can be the same as elements or name clobbering 115 // label is not done. Can be the same as elements or name clobbering
175 // one of these in the case of not jumping to the miss label. 116 // one of these in the case of not jumping to the miss label.
176 // The two scratch registers need to be different from elements, name and 117 // The two scratch registers need to be different from elements, name and
177 // result. 118 // result.
178 // The generated code assumes that the receiver has slow properties, 119 // The generated code assumes that the receiver has slow properties,
179 // is not a global object and does not have interceptors. 120 // is not a global object and does not have interceptors.
180 static void GenerateDictionaryLoad(MacroAssembler* masm, 121 static void GenerateDictionaryLoad(MacroAssembler* masm,
181 Label* miss, 122 Label* miss,
182 Register elements, 123 Register elements,
183 Register name, 124 Register name,
184 Register result, 125 Register result,
185 Register scratch1, 126 Register scratch1,
186 Register scratch2) { 127 Register scratch2) {
187 // Main use of the scratch registers. 128 // Main use of the scratch registers.
188 // scratch1: Used as temporary and to hold the capacity of the property 129 // scratch1: Used as temporary and to hold the capacity of the property
189 // dictionary. 130 // dictionary.
190 // scratch2: Used as temporary. 131 // scratch2: Used as temporary.
191 Label done; 132 Label done;
192 133
193 // Probe the dictionary. 134 // Probe the dictionary.
194 GenerateStringDictionaryProbes(masm, 135 StringDictionaryLookupStub::GeneratePositiveLookup(masm,
195 miss, 136 miss,
196 &done, 137 &done,
197 elements, 138 elements,
198 name, 139 name,
199 scratch1, 140 scratch1,
200 scratch2); 141 scratch2);
201 142
202 // If probing finds an entry check that the value is a normal 143 // If probing finds an entry check that the value is a normal
203 // property. 144 // property.
204 __ bind(&done); // scratch2 == elements + 4 * index 145 __ bind(&done); // scratch2 == elements + 4 * index
205 const int kElementsStartOffset = StringDictionary::kHeaderSize + 146 const int kElementsStartOffset = StringDictionary::kHeaderSize +
206 StringDictionary::kElementsStartIndex * kPointerSize; 147 StringDictionary::kElementsStartIndex * kPointerSize;
207 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; 148 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
208 __ ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); 149 __ ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset));
209 __ tst(scratch1, Operand(PropertyDetails::TypeField::mask() << kSmiTagSize)); 150 __ tst(scratch1, Operand(PropertyDetails::TypeField::mask() << kSmiTagSize));
210 __ b(ne, miss); 151 __ b(ne, miss);
(...skipping 22 matching lines...) Expand all
233 Register value, 174 Register value,
234 Register scratch1, 175 Register scratch1,
235 Register scratch2) { 176 Register scratch2) {
236 // Main use of the scratch registers. 177 // Main use of the scratch registers.
237 // scratch1: Used as temporary and to hold the capacity of the property 178 // scratch1: Used as temporary and to hold the capacity of the property
238 // dictionary. 179 // dictionary.
239 // scratch2: Used as temporary. 180 // scratch2: Used as temporary.
240 Label done; 181 Label done;
241 182
242 // Probe the dictionary. 183 // Probe the dictionary.
243 GenerateStringDictionaryProbes(masm, 184 StringDictionaryLookupStub::GeneratePositiveLookup(masm,
244 miss, 185 miss,
245 &done, 186 &done,
246 elements, 187 elements,
247 name, 188 name,
248 scratch1, 189 scratch1,
249 scratch2); 190 scratch2);
250 191
251 // If probing finds an entry in the dictionary check that the value 192 // If probing finds an entry in the dictionary check that the value
252 // is a normal property that is not read only. 193 // is a normal property that is not read only.
253 __ bind(&done); // scratch2 == elements + 4 * index 194 __ bind(&done); // scratch2 == elements + 4 * index
254 const int kElementsStartOffset = StringDictionary::kHeaderSize + 195 const int kElementsStartOffset = StringDictionary::kHeaderSize +
255 StringDictionary::kElementsStartIndex * kPointerSize; 196 StringDictionary::kElementsStartIndex * kPointerSize;
256 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; 197 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
257 const int kTypeAndReadOnlyMask 198 const int kTypeAndReadOnlyMask
258 = (PropertyDetails::TypeField::mask() | 199 = (PropertyDetails::TypeField::mask() |
259 PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize; 200 PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize;
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 __ mov(r3, r0); 863 __ mov(r3, r0);
923 __ Push(r3, r2); 864 __ Push(r3, r2);
924 865
925 // Perform tail call to the entry. 866 // Perform tail call to the entry.
926 ExternalReference ref = 867 ExternalReference ref =
927 ExternalReference(IC_Utility(kLoadIC_Miss), isolate); 868 ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
928 __ TailCallExternalReference(ref, 2, 1); 869 __ TailCallExternalReference(ref, 2, 1);
929 } 870 }
930 871
931 872
932 Object* KeyedLoadIC_Miss(Arguments args); 873 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
933
934
935 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
936 // ---------- S t a t e -------------- 874 // ---------- S t a t e --------------
937 // -- lr : return address 875 // -- lr : return address
938 // -- r0 : key 876 // -- r0 : key
939 // -- r1 : receiver 877 // -- r1 : receiver
940 // ----------------------------------- 878 // -----------------------------------
941 Isolate* isolate = masm->isolate(); 879 Isolate* isolate = masm->isolate();
942 880
943 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r3, r4); 881 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r3, r4);
944 882
945 __ Push(r1, r0); 883 __ Push(r1, r0);
946 884
947 ExternalReference ref = 885 // Perform tail call to the entry.
948 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate); 886 ExternalReference ref = force_generic
887 ? ExternalReference(IC_Utility(kKeyedLoadIC_MissForceGeneric), isolate)
888 : ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
889
949 __ TailCallExternalReference(ref, 2, 1); 890 __ TailCallExternalReference(ref, 2, 1);
950 } 891 }
951 892
952 893
953 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { 894 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
954 // ---------- S t a t e -------------- 895 // ---------- S t a t e --------------
955 // -- lr : return address 896 // -- lr : return address
956 // -- r0 : key 897 // -- r0 : key
957 // -- r1 : receiver 898 // -- r1 : receiver
958 // ----------------------------------- 899 // -----------------------------------
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 &miss, // When not a number. 1070 &miss, // When not a number.
1130 &miss, // When index out of range. 1071 &miss, // When index out of range.
1131 STRING_INDEX_IS_ARRAY_INDEX); 1072 STRING_INDEX_IS_ARRAY_INDEX);
1132 char_at_generator.GenerateFast(masm); 1073 char_at_generator.GenerateFast(masm);
1133 __ Ret(); 1074 __ Ret();
1134 1075
1135 StubRuntimeCallHelper call_helper; 1076 StubRuntimeCallHelper call_helper;
1136 char_at_generator.GenerateSlow(masm, call_helper); 1077 char_at_generator.GenerateSlow(masm, call_helper);
1137 1078
1138 __ bind(&miss); 1079 __ bind(&miss);
1139 GenerateMiss(masm); 1080 GenerateMiss(masm, false);
1140 } 1081 }
1141 1082
1142 1083
1143 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { 1084 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
1144 // ---------- S t a t e -------------- 1085 // ---------- S t a t e --------------
1145 // -- lr : return address 1086 // -- lr : return address
1146 // -- r0 : key 1087 // -- r0 : key
1147 // -- r1 : receiver 1088 // -- r1 : receiver
1148 // ----------------------------------- 1089 // -----------------------------------
1149 Label slow; 1090 Label slow;
(...skipping 19 matching lines...) Expand all
1169 __ Push(r1, r0); // Receiver, key. 1110 __ Push(r1, r0); // Receiver, key.
1170 1111
1171 // Perform tail call to the entry. 1112 // Perform tail call to the entry.
1172 __ TailCallExternalReference( 1113 __ TailCallExternalReference(
1173 ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor), 1114 ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor),
1174 masm->isolate()), 1115 masm->isolate()),
1175 2, 1116 2,
1176 1); 1117 1);
1177 1118
1178 __ bind(&slow); 1119 __ bind(&slow);
1179 GenerateMiss(masm); 1120 GenerateMiss(masm, false);
1180 } 1121 }
1181 1122
1182 1123
1183 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { 1124 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
1184 // ---------- S t a t e -------------- 1125 // ---------- S t a t e --------------
1185 // -- r0 : value 1126 // -- r0 : value
1186 // -- r1 : key 1127 // -- r1 : key
1187 // -- r2 : receiver 1128 // -- r2 : receiver
1188 // -- lr : return address 1129 // -- lr : return address
1189 // ----------------------------------- 1130 // -----------------------------------
1190 1131
1191 // Push receiver, key and value for runtime call. 1132 // Push receiver, key and value for runtime call.
1192 __ Push(r2, r1, r0); 1133 __ Push(r2, r1, r0);
1193 1134
1194 ExternalReference ref = 1135 ExternalReference ref = force_generic
1195 ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate()); 1136 ? ExternalReference(IC_Utility(kKeyedStoreIC_MissForceGeneric),
1137 masm->isolate())
1138 : ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate());
1196 __ TailCallExternalReference(ref, 3, 1); 1139 __ TailCallExternalReference(ref, 3, 1);
1197 } 1140 }
1198 1141
1142
1143 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
1144 // ---------- S t a t e --------------
1145 // -- r0 : value
1146 // -- r1 : key
1147 // -- r2 : receiver
1148 // -- lr : return address
1149 // -----------------------------------
1150
1151 // Push receiver, key and value for runtime call.
1152 __ Push(r2, r1, r0);
1153
1154 // The slow case calls into the runtime to complete the store without causing
1155 // an IC miss that would otherwise cause a transition to the generic stub.
1156 ExternalReference ref =
1157 ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate());
1158 __ TailCallExternalReference(ref, 3, 1);
1159 }
1160
1199 1161
1200 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, 1162 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
1201 StrictModeFlag strict_mode) { 1163 StrictModeFlag strict_mode) {
1202 // ---------- S t a t e -------------- 1164 // ---------- S t a t e --------------
1203 // -- r0 : value 1165 // -- r0 : value
1204 // -- r1 : key 1166 // -- r1 : key
1205 // -- r2 : receiver 1167 // -- r2 : receiver
1206 // -- lr : return address 1168 // -- lr : return address
1207 // ----------------------------------- 1169 // -----------------------------------
1208 1170
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
1578 Register reg = Assembler::GetRn(instr_at_patch); 1540 Register reg = Assembler::GetRn(instr_at_patch);
1579 patcher.masm()->tst(reg, Operand(kSmiTagMask)); 1541 patcher.masm()->tst(reg, Operand(kSmiTagMask));
1580 patcher.EmitCondition(eq); 1542 patcher.EmitCondition(eq);
1581 } 1543 }
1582 } 1544 }
1583 1545
1584 1546
1585 } } // namespace v8::internal 1547 } } // namespace v8::internal
1586 1548
1587 #endif // V8_TARGET_ARCH_ARM 1549 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/full-codegen-arm.cc ('k') | src/arm/lithium-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698