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

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

Issue 7869: Apply Daniel's patch for array index strings. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years, 2 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 | « AUTHORS ('k') | src/objects.h » ('j') | src/objects.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); 205 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
206 } 206 }
207 207
208 208
209 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 209 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
210 // ----------- S t a t e ------------- 210 // ----------- S t a t e -------------
211 // -- esp[0] : return address 211 // -- esp[0] : return address
212 // -- esp[4] : name 212 // -- esp[4] : name
213 // -- esp[8] : receiver 213 // -- esp[8] : receiver
214 // ----------------------------------- 214 // -----------------------------------
215 Label slow, fast, check_string; 215 Label slow, fast, check_string, index_int, index_string;
216 216
217 __ mov(eax, (Operand(esp, kPointerSize))); 217 __ mov(eax, (Operand(esp, kPointerSize)));
218 __ mov(ecx, (Operand(esp, 2 * kPointerSize))); 218 __ mov(ecx, (Operand(esp, 2 * kPointerSize)));
219 219
220 // Check that the object isn't a smi. 220 // Check that the object isn't a smi.
221 __ test(ecx, Immediate(kSmiTagMask)); 221 __ test(ecx, Immediate(kSmiTagMask));
222 __ j(zero, &slow, not_taken); 222 __ j(zero, &slow, not_taken);
223 // Check that the object is some kind of JS object EXCEPT JS Value type. 223 // Check that the object is some kind of JS object EXCEPT JS Value type.
224 // In the case that the object is a value-wrapper object, 224 // In the case that the object is a value-wrapper object,
225 // we enter the runtime system to make sure that indexing 225 // we enter the runtime system to make sure that indexing
226 // into string objects work as intended. 226 // into string objects work as intended.
227 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); 227 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE);
228 __ mov(edx, FieldOperand(ecx, HeapObject::kMapOffset)); 228 __ mov(edx, FieldOperand(ecx, HeapObject::kMapOffset));
229 __ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset)); 229 __ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset));
230 __ cmp(edx, JS_OBJECT_TYPE); 230 __ cmp(edx, JS_OBJECT_TYPE);
231 __ j(less, &slow, not_taken); 231 __ j(less, &slow, not_taken);
232 // Check that the key is a smi. 232 // Check that the key is a smi.
233 __ test(eax, Immediate(kSmiTagMask)); 233 __ test(eax, Immediate(kSmiTagMask));
234 __ j(not_zero, &check_string, not_taken); 234 __ j(not_zero, &check_string, not_taken);
235 __ sar(eax, kSmiTagSize); 235 __ sar(eax, kSmiTagSize);
236 // Get the elements array of the object. 236 // Get the elements array of the object.
237 __ bind(&index_int);
237 __ mov(ecx, FieldOperand(ecx, JSObject::kElementsOffset)); 238 __ mov(ecx, FieldOperand(ecx, JSObject::kElementsOffset));
238 // Check that the object is in fast mode (not dictionary). 239 // Check that the object is in fast mode (not dictionary).
239 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), 240 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset),
240 Immediate(Factory::hash_table_map())); 241 Immediate(Factory::hash_table_map()));
241 __ j(equal, &slow, not_taken); 242 __ j(equal, &slow, not_taken);
242 // Check that the key (index) is within bounds. 243 // Check that the key (index) is within bounds.
243 __ cmp(eax, FieldOperand(ecx, Array::kLengthOffset)); 244 __ cmp(eax, FieldOperand(ecx, Array::kLengthOffset));
244 __ j(below, &fast, taken); 245 __ j(below, &fast, taken);
245 // Slow case: Load name and receiver from stack and jump to runtime. 246 // Slow case: Load name and receiver from stack and jump to runtime.
246 __ bind(&slow); 247 __ bind(&slow);
247 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1); 248 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1);
248 KeyedLoadIC::Generate(masm, ExternalReference(Runtime::kKeyedGetProperty)); 249 KeyedLoadIC::Generate(masm, ExternalReference(Runtime::kKeyedGetProperty));
249 // Check if the key is a symbol that is not an array index. 250 // Check if the key is a symbol that is not an array index.
250 __ bind(&check_string); 251 __ bind(&check_string);
252 __ mov(ebx, FieldOperand(eax, String::kLengthOffset));
253 __ test(ebx, Immediate(String::kIsArrayIndexMask));
254 __ j(not_zero, &index_string, not_taken);
251 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 255 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
252 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 256 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
253 __ test(ebx, Immediate(kIsSymbolMask)); 257 __ test(ebx, Immediate(kIsSymbolMask));
254 __ j(zero, &slow, not_taken);
255 __ mov(ebx, FieldOperand(eax, String::kLengthOffset));
256 __ test(ebx, Immediate(String::kIsArrayIndexMask));
257 __ j(not_zero, &slow, not_taken); 258 __ j(not_zero, &slow, not_taken);
258 // Probe the dictionary leaving result in ecx. 259 // Probe the dictionary leaving result in ecx.
259 GenerateDictionaryLoad(masm, &slow, ebx, ecx, edx, eax); 260 GenerateDictionaryLoad(masm, &slow, ebx, ecx, edx, eax);
260 __ mov(eax, Operand(ecx)); 261 __ mov(eax, Operand(ecx));
261 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1); 262 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1);
262 __ ret(0); 263 __ ret(0);
264 // Array index string: If short enough use cache in length/hash field (ebx).
265 __ bind(&index_string);
266 const int kLengthFieldLimit =
267 (String::kMaxCachedArrayIndexLength + 1) << String::kShortLengthShift;
268 __ cmp(ebx, kLengthFieldLimit);
269 __ j(above_equal, &slow);
270 __ mov(eax, Operand(ebx));
271 __ and_(eax, (1 << String::kShortLengthShift) - 1);
272 __ shr(eax, String::kLongLengthShift);
273 __ jmp(&index_int);
263 // Fast case: Do the load. 274 // Fast case: Do the load.
264 __ bind(&fast); 275 __ bind(&fast);
265 __ mov(eax, Operand(ecx, eax, times_4, Array::kHeaderSize - kHeapObjectTag)); 276 __ mov(eax, Operand(ecx, eax, times_4, Array::kHeaderSize - kHeapObjectTag));
266 __ cmp(Operand(eax), Immediate(Factory::the_hole_value())); 277 __ cmp(Operand(eax), Immediate(Factory::the_hole_value()));
267 // In case the loaded value is the_hole we have to consult GetProperty 278 // In case the loaded value is the_hole we have to consult GetProperty
268 // to ensure the prototype chain is searched. 279 // to ensure the prototype chain is searched.
269 __ j(equal, &slow, not_taken); 280 __ j(equal, &slow, not_taken);
270 __ IncrementCounter(&Counters::keyed_load_generic_smi, 1); 281 __ IncrementCounter(&Counters::keyed_load_generic_smi, 1);
271 __ ret(0); 282 __ ret(0);
272 } 283 }
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 780
770 // Do tail-call to runtime routine. 781 // Do tail-call to runtime routine.
771 __ TailCallRuntime( 782 __ TailCallRuntime(
772 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3); 783 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
773 } 784 }
774 785
775 #undef __ 786 #undef __
776 787
777 788
778 } } // namespace v8::internal 789 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « AUTHORS ('k') | src/objects.h » ('j') | src/objects.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698