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

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

Issue 13663: Make sure that the generic stubs for keyed load and store and for... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 12 years 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/ic-arm.cc ('k') | src/runtime.cc » ('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 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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 208
209 209
210 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 210 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
211 // ----------- S t a t e ------------- 211 // ----------- S t a t e -------------
212 // -- esp[0] : return address 212 // -- esp[0] : return address
213 // -- esp[4] : name 213 // -- esp[4] : name
214 // -- esp[8] : receiver 214 // -- esp[8] : receiver
215 // ----------------------------------- 215 // -----------------------------------
216 Label slow, fast, check_string, index_int, index_string; 216 Label slow, fast, check_string, index_int, index_string;
217 217
218 // Load name and receiver.
218 __ mov(eax, (Operand(esp, kPointerSize))); 219 __ mov(eax, (Operand(esp, kPointerSize)));
219 __ mov(ecx, (Operand(esp, 2 * kPointerSize))); 220 __ mov(ecx, (Operand(esp, 2 * kPointerSize)));
220 221
221 // Check that the object isn't a smi. 222 // Check that the object isn't a smi.
222 __ test(ecx, Immediate(kSmiTagMask)); 223 __ test(ecx, Immediate(kSmiTagMask));
223 __ j(zero, &slow, not_taken); 224 __ j(zero, &slow, not_taken);
225
226 // Get the map of the receiver.
227 __ mov(edx, FieldOperand(ecx, HeapObject::kMapOffset));
228 // Check that the receiver does not require access checks. We need
229 // to check this explicitly since this generic stub does not perform
230 // map checks.
231 __ movzx_b(ebx, FieldOperand(edx, Map::kBitFieldOffset));
232 __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded));
233 __ j(not_zero, &slow, not_taken);
224 // Check that the object is some kind of JS object EXCEPT JS Value type. 234 // Check that the object is some kind of JS object EXCEPT JS Value type.
225 // In the case that the object is a value-wrapper object, 235 // In the case that the object is a value-wrapper object,
226 // we enter the runtime system to make sure that indexing 236 // we enter the runtime system to make sure that indexing
227 // into string objects work as intended. 237 // into string objects work as intended.
228 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); 238 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE);
229 __ mov(edx, FieldOperand(ecx, HeapObject::kMapOffset));
230 __ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset)); 239 __ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset));
231 __ cmp(edx, JS_OBJECT_TYPE); 240 __ cmp(edx, JS_OBJECT_TYPE);
232 __ j(less, &slow, not_taken); 241 __ j(less, &slow, not_taken);
233 // Check that the key is a smi. 242 // Check that the key is a smi.
234 __ test(eax, Immediate(kSmiTagMask)); 243 __ test(eax, Immediate(kSmiTagMask));
235 __ j(not_zero, &check_string, not_taken); 244 __ j(not_zero, &check_string, not_taken);
236 __ sar(eax, kSmiTagSize); 245 __ sar(eax, kSmiTagSize);
237 // Get the elements array of the object. 246 // Get the elements array of the object.
238 __ bind(&index_int); 247 __ bind(&index_int);
239 __ mov(ecx, FieldOperand(ecx, JSObject::kElementsOffset)); 248 __ mov(ecx, FieldOperand(ecx, JSObject::kElementsOffset));
(...skipping 21 matching lines...) Expand all
261 GenerateDictionaryLoad(masm, &slow, ebx, ecx, edx, eax); 270 GenerateDictionaryLoad(masm, &slow, ebx, ecx, edx, eax);
262 GenerateCheckNonFunctionOrLoaded(masm, &slow, ecx, edx); 271 GenerateCheckNonFunctionOrLoaded(masm, &slow, ecx, edx);
263 __ mov(eax, Operand(ecx)); 272 __ mov(eax, Operand(ecx));
264 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1); 273 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1);
265 __ ret(0); 274 __ ret(0);
266 // Array index string: If short enough use cache in length/hash field (ebx). 275 // Array index string: If short enough use cache in length/hash field (ebx).
267 // We assert that there are enough bits in an int32_t after the hash shift 276 // We assert that there are enough bits in an int32_t after the hash shift
268 // bits have been subtracted to allow space for the length and the cached 277 // bits have been subtracted to allow space for the length and the cached
269 // array index. 278 // array index.
270 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < 279 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
271 (1 << (String::kShortLengthShift - String::kHashShift))); 280 (1 << (String::kShortLengthShift - String::kHashShift)));
272 __ bind(&index_string); 281 __ bind(&index_string);
273 const int kLengthFieldLimit = 282 const int kLengthFieldLimit =
274 (String::kMaxCachedArrayIndexLength + 1) << String::kShortLengthShift; 283 (String::kMaxCachedArrayIndexLength + 1) << String::kShortLengthShift;
275 __ cmp(ebx, kLengthFieldLimit); 284 __ cmp(ebx, kLengthFieldLimit);
276 __ j(above_equal, &slow); 285 __ j(above_equal, &slow);
277 __ mov(eax, Operand(ebx)); 286 __ mov(eax, Operand(ebx));
278 __ and_(eax, (1 << String::kShortLengthShift) - 1); 287 __ and_(eax, (1 << String::kShortLengthShift) - 1);
279 __ shr(eax, String::kLongLengthShift); 288 __ shr(eax, String::kLongLengthShift);
280 __ jmp(&index_int); 289 __ jmp(&index_int);
281 // Fast case: Do the load. 290 // Fast case: Do the load.
282 __ bind(&fast); 291 __ bind(&fast);
283 __ mov(eax, Operand(ecx, eax, times_4, Array::kHeaderSize - kHeapObjectTag)); 292 __ mov(eax, Operand(ecx, eax, times_4, Array::kHeaderSize - kHeapObjectTag));
284 __ cmp(Operand(eax), Immediate(Factory::the_hole_value())); 293 __ cmp(Operand(eax), Immediate(Factory::the_hole_value()));
285 // In case the loaded value is the_hole we have to consult GetProperty 294 // In case the loaded value is the_hole we have to consult GetProperty
286 // to ensure the prototype chain is searched. 295 // to ensure the prototype chain is searched.
287 __ j(equal, &slow, not_taken); 296 __ j(equal, &slow, not_taken);
288 __ IncrementCounter(&Counters::keyed_load_generic_smi, 1); 297 __ IncrementCounter(&Counters::keyed_load_generic_smi, 1);
289 __ ret(0); 298 __ ret(0);
290 } 299 }
291 300
292 301
293 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) { 302 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
294 // ----------- S t a t e ------------- 303 // ----------- S t a t e -------------
295 // -- eax : value 304 // -- eax : value
296 // -- esp[0] : return address 305 // -- esp[0] : return address
297 // -- esp[4] : key 306 // -- esp[4] : key
298 // -- esp[8] : receiver 307 // -- esp[8] : receiver
299 // ----------------------------------- 308 // -----------------------------------
300 Label slow, fast, array, extra; 309 Label slow, fast, array, extra;
301 // Get the key and the object from the stack. 310
311 // Get the receiver from the stack.
312 __ mov(edx, Operand(esp, 2 * kPointerSize)); // 2 ~ return address, key
313 // Check that the object isn't a smi.
314 __ test(edx, Immediate(kSmiTagMask));
315 __ j(zero, &slow, not_taken);
316 // Get the map from the receiver.
317 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
318 // Check that the receiver does not require access checks. We need
319 // to do this because this generic stub does not perform map checks.
320 __ movzx_b(ebx, FieldOperand(ecx, Map::kBitFieldOffset));
321 __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded));
322 __ j(not_zero, &slow, not_taken);
323 // Get the key from the stack.
302 __ mov(ebx, Operand(esp, 1 * kPointerSize)); // 1 ~ return address 324 __ mov(ebx, Operand(esp, 1 * kPointerSize)); // 1 ~ return address
303 __ mov(edx, Operand(esp, 2 * kPointerSize)); // 2 ~ return address, key
304 // Check that the key is a smi. 325 // Check that the key is a smi.
305 __ test(ebx, Immediate(kSmiTagMask)); 326 __ test(ebx, Immediate(kSmiTagMask));
306 __ j(not_zero, &slow, not_taken); 327 __ j(not_zero, &slow, not_taken);
307 // Check that the object isn't a smi. 328 // Get the instance type from the map of the receiver.
308 __ test(edx, Immediate(kSmiTagMask));
309 __ j(zero, &slow, not_taken);
310 // Get the type of the object from its map.
311 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
312 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 329 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
313 // Check if the object is a JS array or not. 330 // Check if the object is a JS array or not.
314 __ cmp(ecx, JS_ARRAY_TYPE); 331 __ cmp(ecx, JS_ARRAY_TYPE);
315 __ j(equal, &array); 332 __ j(equal, &array);
316 // Check that the object is some kind of JS object. 333 // Check that the object is some kind of JS object.
317 __ cmp(ecx, FIRST_JS_OBJECT_TYPE); 334 __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
318 __ j(less, &slow, not_taken); 335 __ j(less, &slow, not_taken);
319 336
320
321 // Object case: Check key against length in the elements array. 337 // Object case: Check key against length in the elements array.
322 // eax: value 338 // eax: value
323 // edx: JSObject 339 // edx: JSObject
324 // ebx: index (as a smi) 340 // ebx: index (as a smi)
325 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); 341 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
326 // Check that the object is in fast mode (not dictionary). 342 // Check that the object is in fast mode (not dictionary).
327 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), 343 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset),
328 Immediate(Factory::hash_table_map())); 344 Immediate(Factory::hash_table_map()));
329 __ j(equal, &slow, not_taken); 345 __ j(equal, &slow, not_taken);
330 // Untag the key (for checking against untagged length in the fixed array). 346 // Untag the key (for checking against untagged length in the fixed array).
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 // Get the receiver of the function from the stack; 1 ~ return address. 524 // Get the receiver of the function from the stack; 1 ~ return address.
509 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 525 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
510 // Get the name of the function from the stack; 2 ~ return address, receiver. 526 // Get the name of the function from the stack; 2 ~ return address, receiver.
511 __ mov(ecx, Operand(esp, (argc + 2) * kPointerSize)); 527 __ mov(ecx, Operand(esp, (argc + 2) * kPointerSize));
512 528
513 // Check that the receiver isn't a smi. 529 // Check that the receiver isn't a smi.
514 __ test(edx, Immediate(kSmiTagMask)); 530 __ test(edx, Immediate(kSmiTagMask));
515 __ j(zero, &miss, not_taken); 531 __ j(zero, &miss, not_taken);
516 532
517 // Check that the receiver is a valid JS object. 533 // Check that the receiver is a valid JS object.
518 __ mov(eax, FieldOperand(edx, HeapObject::kMapOffset)); 534 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
519 __ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset)); 535 __ movzx_b(eax, FieldOperand(ebx, Map::kInstanceTypeOffset));
520 __ cmp(eax, FIRST_JS_OBJECT_TYPE); 536 __ cmp(eax, FIRST_JS_OBJECT_TYPE);
521 __ j(less, &miss, not_taken); 537 __ j(less, &miss, not_taken);
522 538
523 // If this assert fails, we have to check upper bound too. 539 // If this assert fails, we have to check upper bound too.
524 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); 540 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
525 541
526 // Check for access to global object. 542 // Check for access to global object.
527 __ cmp(eax, JS_GLOBAL_OBJECT_TYPE); 543 __ cmp(eax, JS_GLOBAL_OBJECT_TYPE);
528 __ j(equal, &global_object); 544 __ j(equal, &global_object);
529 __ cmp(eax, JS_BUILTINS_OBJECT_TYPE); 545 __ cmp(eax, JS_BUILTINS_OBJECT_TYPE);
530 __ j(not_equal, &non_global_object); 546 __ j(not_equal, &non_global_object);
531 547
532 // Accessing global object: Load and invoke. 548 // Accessing global object: Load and invoke.
533 __ bind(&global_object); 549 __ bind(&global_object);
550 // Check that the global object does not require access checks.
551 __ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset));
552 __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded));
553 __ j(not_equal, &miss, not_taken);
534 GenerateNormalHelper(masm, argc, true, &miss); 554 GenerateNormalHelper(masm, argc, true, &miss);
535 555
536 // Accessing non-global object: Check for access to global proxy. 556 // Accessing non-global object: Check for access to global proxy.
537 Label global_proxy, invoke; 557 Label global_proxy, invoke;
538 __ bind(&non_global_object); 558 __ bind(&non_global_object);
539 __ cmp(eax, JS_GLOBAL_PROXY_TYPE); 559 __ cmp(eax, JS_GLOBAL_PROXY_TYPE);
540 __ j(equal, &global_proxy, not_taken); 560 __ j(equal, &global_proxy, not_taken);
561 // Check that the non-global, non-global-proxy object does not
562 // require access checks.
563 __ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset));
564 __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded));
565 __ j(not_equal, &miss, not_taken);
541 __ bind(&invoke); 566 __ bind(&invoke);
542 GenerateNormalHelper(masm, argc, false, &miss); 567 GenerateNormalHelper(masm, argc, false, &miss);
543 568
544 // Global object proxy access: Check access rights. 569 // Global object proxy access: Check access rights.
545 __ bind(&global_proxy); 570 __ bind(&global_proxy);
546 __ CheckAccessGlobalProxy(edx, eax, &miss); 571 __ CheckAccessGlobalProxy(edx, eax, &miss);
547 __ jmp(&invoke); 572 __ jmp(&invoke);
548 573
549 // Cache miss: Jump to runtime. 574 // Cache miss: Jump to runtime.
550 __ bind(&miss); 575 __ bind(&miss);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 660
636 Label miss, probe, global; 661 Label miss, probe, global;
637 662
638 __ mov(eax, Operand(esp, kPointerSize)); 663 __ mov(eax, Operand(esp, kPointerSize));
639 664
640 // Check that the receiver isn't a smi. 665 // Check that the receiver isn't a smi.
641 __ test(eax, Immediate(kSmiTagMask)); 666 __ test(eax, Immediate(kSmiTagMask));
642 __ j(zero, &miss, not_taken); 667 __ j(zero, &miss, not_taken);
643 668
644 // Check that the receiver is a valid JS object. 669 // Check that the receiver is a valid JS object.
645 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); 670 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
646 __ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset)); 671 __ movzx_b(edx, FieldOperand(ebx, Map::kInstanceTypeOffset));
647 __ cmp(edx, FIRST_JS_OBJECT_TYPE); 672 __ cmp(edx, FIRST_JS_OBJECT_TYPE);
648 __ j(less, &miss, not_taken); 673 __ j(less, &miss, not_taken);
649 674
650 // If this assert fails, we have to check upper bound too. 675 // If this assert fails, we have to check upper bound too.
651 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); 676 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
652 677
653 // Check for access to global object (unlikely). 678 // Check for access to global object (unlikely).
654 __ cmp(edx, JS_GLOBAL_PROXY_TYPE); 679 __ cmp(edx, JS_GLOBAL_PROXY_TYPE);
655 __ j(equal, &global, not_taken); 680 __ j(equal, &global, not_taken);
656 681
682 // Check for non-global object that requires access check.
683 __ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset));
684 __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded));
685 __ j(not_zero, &miss, not_taken);
686
657 // Search the dictionary placing the result in eax. 687 // Search the dictionary placing the result in eax.
658 __ bind(&probe); 688 __ bind(&probe);
659 GenerateDictionaryLoad(masm, &miss, edx, eax, ebx, ecx); 689 GenerateDictionaryLoad(masm, &miss, edx, eax, ebx, ecx);
660 GenerateCheckNonFunctionOrLoaded(masm, &miss, eax, edx); 690 GenerateCheckNonFunctionOrLoaded(masm, &miss, eax, edx);
661 __ ret(0); 691 __ ret(0);
662 692
663 // Global object access: Check access rights. 693 // Global object access: Check access rights.
664 __ bind(&global); 694 __ bind(&global);
665 __ CheckAccessGlobalProxy(eax, edx, &miss); 695 __ CheckAccessGlobalProxy(eax, edx, &miss);
666 __ jmp(&probe); 696 __ jmp(&probe);
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 868
839 // Do tail-call to runtime routine. 869 // Do tail-call to runtime routine.
840 __ TailCallRuntime( 870 __ TailCallRuntime(
841 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3); 871 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
842 } 872 }
843 873
844 #undef __ 874 #undef __
845 875
846 876
847 } } // namespace v8::internal 877 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic-arm.cc ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698