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

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

Issue 1148007: Merge bleeding_edge from version 2.1.3 up to revision 4205... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: Created 10 years, 9 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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 __ test(Operand(r0, r1, times_4, kDetailsOffset - kHeapObjectTag), 145 __ test(Operand(r0, r1, times_4, kDetailsOffset - kHeapObjectTag),
146 Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize)); 146 Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize));
147 __ j(not_zero, miss_label, not_taken); 147 __ j(not_zero, miss_label, not_taken);
148 148
149 // Get the value at the masked, scaled index. 149 // Get the value at the masked, scaled index.
150 const int kValueOffset = kElementsStartOffset + kPointerSize; 150 const int kValueOffset = kElementsStartOffset + kPointerSize;
151 __ mov(r1, Operand(r0, r1, times_4, kValueOffset - kHeapObjectTag)); 151 __ mov(r1, Operand(r0, r1, times_4, kValueOffset - kHeapObjectTag));
152 } 152 }
153 153
154 154
155 static void GenerateNumberDictionaryLoad(MacroAssembler* masm,
156 Label* miss,
157 Register elements,
158 Register key,
159 Register r0,
160 Register r1,
161 Register r2) {
162 // Register use:
163 //
164 // elements - holds the slow-case elements of the receiver and is unchanged.
165 //
166 // key - holds the smi key on entry and is unchanged if a branch is
167 // performed to the miss label. If the load succeeds and we
168 // fall through, key holds the result on exit.
169 //
170 // Scratch registers:
171 //
172 // r0 - holds the untagged key on entry and holds the hash once computed.
173 //
174 // r1 - used to hold the capacity mask of the dictionary
175 //
176 // r2 - used for the index into the dictionary.
177 Label done;
178
179 // Compute the hash code from the untagged key. This must be kept in sync
180 // with ComputeIntegerHash in utils.h.
181 //
182 // hash = ~hash + (hash << 15);
183 __ mov(r1, r0);
184 __ not_(r0);
185 __ shl(r1, 15);
186 __ add(r0, Operand(r1));
187 // hash = hash ^ (hash >> 12);
188 __ mov(r1, r0);
189 __ shr(r1, 12);
190 __ xor_(r0, Operand(r1));
191 // hash = hash + (hash << 2);
192 __ lea(r0, Operand(r0, r0, times_4, 0));
193 // hash = hash ^ (hash >> 4);
194 __ mov(r1, r0);
195 __ shr(r1, 4);
196 __ xor_(r0, Operand(r1));
197 // hash = hash * 2057;
198 __ imul(r0, r0, 2057);
199 // hash = hash ^ (hash >> 16);
200 __ mov(r1, r0);
201 __ shr(r1, 16);
202 __ xor_(r0, Operand(r1));
203
204 // Compute capacity mask.
205 const int kCapacityOffset =
206 NumberDictionary::kHeaderSize +
207 NumberDictionary::kCapacityIndex * kPointerSize;
208 __ mov(r1, FieldOperand(elements, kCapacityOffset));
209 __ shr(r1, kSmiTagSize); // convert smi to int
210 __ dec(r1);
211
212 const int kElementsStartOffset =
213 NumberDictionary::kHeaderSize +
214 NumberDictionary::kElementsStartIndex * kPointerSize;
215
216 // Generate an unrolled loop that performs a few probes before giving up.
217 const int kProbes = 4;
218 for (int i = 0; i < kProbes; i++) {
219 // Use r2 for index calculations and keep the hash intact in r0.
220 __ mov(r2, r0);
221 // Compute the masked index: (hash + i + i * i) & mask.
222 if (i > 0) {
223 __ add(Operand(r2), Immediate(NumberDictionary::GetProbeOffset(i)));
224 }
225 __ and_(r2, Operand(r1));
226
227 // Scale the index by multiplying by the entry size.
228 ASSERT(NumberDictionary::kEntrySize == 3);
229 __ lea(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3
230
231 // Check if the key matches.
232 __ cmp(key, FieldOperand(elements,
233 r2,
234 times_pointer_size,
235 kElementsStartOffset));
236 if (i != (kProbes - 1)) {
237 __ j(equal, &done, taken);
238 } else {
239 __ j(not_equal, miss, not_taken);
240 }
241 }
242
243 __ bind(&done);
244 // Check that the value is a normal propety.
245 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
246 ASSERT_EQ(NORMAL, 0);
247 __ test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
248 Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize));
249 __ j(not_zero, miss);
250
251 // Get the value at the masked, scaled index.
252 const int kValueOffset = kElementsStartOffset + kPointerSize;
253 __ mov(key, FieldOperand(elements, r2, times_pointer_size, kValueOffset));
254 }
255
256
155 // The offset from the inlined patch site to the start of the 257 // The offset from the inlined patch site to the start of the
156 // inlined load instruction. It is 7 bytes (test eax, imm) plus 258 // inlined load instruction. It is 7 bytes (test eax, imm) plus
157 // 6 bytes (jne slow_label). 259 // 6 bytes (jne slow_label).
158 const int LoadIC::kOffsetToLoadInstruction = 13; 260 const int LoadIC::kOffsetToLoadInstruction = 13;
159 261
160 262
161 void LoadIC::GenerateArrayLength(MacroAssembler* masm) { 263 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
162 // ----------- S t a t e ------------- 264 // ----------- S t a t e -------------
163 // -- eax : receiver 265 // -- eax : receiver
164 // -- ecx : name 266 // -- ecx : name
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 303
202 304
203 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 305 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
204 // ----------- S t a t e ------------- 306 // ----------- S t a t e -------------
205 // -- eax : key 307 // -- eax : key
206 // -- edx : receiver 308 // -- edx : receiver
207 // -- esp[0] : return address 309 // -- esp[0] : return address
208 // ----------------------------------- 310 // -----------------------------------
209 Label slow, check_string, index_int, index_string; 311 Label slow, check_string, index_int, index_string;
210 Label check_pixel_array, probe_dictionary; 312 Label check_pixel_array, probe_dictionary;
313 Label check_number_dictionary;
211 314
212 // Check that the object isn't a smi. 315 // Check that the object isn't a smi.
213 __ test(edx, Immediate(kSmiTagMask)); 316 __ test(edx, Immediate(kSmiTagMask));
214 __ j(zero, &slow, not_taken); 317 __ j(zero, &slow, not_taken);
215 318
216 // Get the map of the receiver. 319 // Get the map of the receiver.
217 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 320 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
218 321
219 // Check bit field. 322 // Check bit field.
220 __ movzx_b(ebx, FieldOperand(ecx, Map::kBitFieldOffset)); 323 __ movzx_b(ebx, FieldOperand(ecx, Map::kBitFieldOffset));
(...skipping 28 matching lines...) Expand all
249 __ mov(eax, ecx); 352 __ mov(eax, ecx);
250 __ IncrementCounter(&Counters::keyed_load_generic_smi, 1); 353 __ IncrementCounter(&Counters::keyed_load_generic_smi, 1);
251 __ ret(0); 354 __ ret(0);
252 355
253 __ bind(&check_pixel_array); 356 __ bind(&check_pixel_array);
254 // Check whether the elements is a pixel array. 357 // Check whether the elements is a pixel array.
255 // edx: receiver 358 // edx: receiver
256 // ebx: untagged index 359 // ebx: untagged index
257 // eax: key 360 // eax: key
258 // ecx: elements 361 // ecx: elements
259 __ CheckMap(ecx, Factory::pixel_array_map(), &slow, true); 362 __ CheckMap(ecx, Factory::pixel_array_map(), &check_number_dictionary, true);
260 __ cmp(ebx, FieldOperand(ecx, PixelArray::kLengthOffset)); 363 __ cmp(ebx, FieldOperand(ecx, PixelArray::kLengthOffset));
261 __ j(above_equal, &slow); 364 __ j(above_equal, &slow);
262 __ mov(eax, FieldOperand(ecx, PixelArray::kExternalPointerOffset)); 365 __ mov(eax, FieldOperand(ecx, PixelArray::kExternalPointerOffset));
263 __ movzx_b(eax, Operand(eax, ebx, times_1, 0)); 366 __ movzx_b(eax, Operand(eax, ebx, times_1, 0));
264 __ SmiTag(eax); 367 __ SmiTag(eax);
265 __ ret(0); 368 __ ret(0);
266 369
370 __ bind(&check_number_dictionary);
371 // Check whether the elements is a number dictionary.
372 // edx: receiver
373 // ebx: untagged index
374 // eax: key
375 // ecx: elements
376 __ CheckMap(ecx, Factory::hash_table_map(), &slow, true);
377 Label slow_pop_receiver;
378 // Push receiver on the stack to free up a register for the dictionary
379 // probing.
380 __ push(edx);
381 GenerateNumberDictionaryLoad(masm,
382 &slow_pop_receiver,
383 ecx,
384 eax,
385 ebx,
386 edx,
387 edi);
388 // Pop receiver before returning.
389 __ pop(edx);
390 __ ret(0);
391
392 __ bind(&slow_pop_receiver);
393 // Pop the receiver from the stack and jump to runtime.
394 __ pop(edx);
395
267 __ bind(&slow); 396 __ bind(&slow);
268 // Slow case: jump to runtime. 397 // Slow case: jump to runtime.
269 // edx: receiver 398 // edx: receiver
270 // eax: key 399 // eax: key
271 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1); 400 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1);
272 GenerateRuntimeGetProperty(masm); 401 GenerateRuntimeGetProperty(masm);
273 402
274 __ bind(&check_string); 403 __ bind(&check_string);
275 // The key is not a smi. 404 // The key is not a smi.
276 // Is it a string? 405 // Is it a string?
(...skipping 1205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1482 1611
1483 // Do tail-call to runtime routine. 1612 // Do tail-call to runtime routine.
1484 ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss)); 1613 ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss));
1485 __ TailCallExternalReference(ref, 3, 1); 1614 __ TailCallExternalReference(ref, 3, 1);
1486 } 1615 }
1487 1616
1488 #undef __ 1617 #undef __
1489 1618
1490 1619
1491 } } // namespace v8::internal 1620 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698