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

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

Issue 10254005: ia32: Redefine register usage in LoadIC/KeyedLoadIC to match StoreIC and KeyedStoreIC (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 8 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 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 __ mov(Operand(r0, 0), value); 211 __ mov(Operand(r0, 0), value);
212 212
213 // Update write barrier. Make sure not to clobber the value. 213 // Update write barrier. Make sure not to clobber the value.
214 __ mov(r1, value); 214 __ mov(r1, value);
215 __ RecordWrite(elements, r0, r1, kDontSaveFPRegs); 215 __ RecordWrite(elements, r0, r1, kDontSaveFPRegs);
216 } 216 }
217 217
218 218
219 void LoadIC::GenerateArrayLength(MacroAssembler* masm) { 219 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
220 // ----------- S t a t e ------------- 220 // ----------- S t a t e -------------
221 // -- eax : receiver
222 // -- ecx : name 221 // -- ecx : name
222 // -- edx : receiver
223 // -- esp[0] : return address 223 // -- esp[0] : return address
224 // ----------------------------------- 224 // -----------------------------------
225 Label miss; 225 Label miss;
226 226
227 StubCompiler::GenerateLoadArrayLength(masm, eax, edx, &miss); 227 StubCompiler::GenerateLoadArrayLength(masm, edx, eax, &miss);
228 __ bind(&miss); 228 __ bind(&miss);
229 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); 229 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
230 } 230 }
231 231
232 232
233 void LoadIC::GenerateStringLength(MacroAssembler* masm, 233 void LoadIC::GenerateStringLength(MacroAssembler* masm,
234 bool support_wrappers) { 234 bool support_wrappers) {
235 // ----------- S t a t e ------------- 235 // ----------- S t a t e -------------
236 // -- eax : receiver
237 // -- ecx : name 236 // -- ecx : name
237 // -- edx : receiver
238 // -- esp[0] : return address 238 // -- esp[0] : return address
239 // ----------------------------------- 239 // -----------------------------------
240 Label miss; 240 Label miss;
241 241
242 StubCompiler::GenerateLoadStringLength(masm, eax, edx, ebx, &miss, 242 StubCompiler::GenerateLoadStringLength(masm, edx, eax, ebx, &miss,
243 support_wrappers); 243 support_wrappers);
244 __ bind(&miss); 244 __ bind(&miss);
245 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); 245 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
246 } 246 }
247 247
248 248
249 void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) { 249 void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
250 // ----------- S t a t e ------------- 250 // ----------- S t a t e -------------
251 // -- eax : receiver
252 // -- ecx : name 251 // -- ecx : name
252 // -- edx : receiver
253 // -- esp[0] : return address 253 // -- esp[0] : return address
254 // ----------------------------------- 254 // -----------------------------------
255 Label miss; 255 Label miss;
256 256
257 StubCompiler::GenerateLoadFunctionPrototype(masm, eax, edx, ebx, &miss); 257 StubCompiler::GenerateLoadFunctionPrototype(masm, edx, eax, ebx, &miss);
258 __ bind(&miss); 258 __ bind(&miss);
259 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); 259 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
260 } 260 }
261 261
262 262
263 // Checks the receiver for special cases (value type, slow case bits). 263 // Checks the receiver for special cases (value type, slow case bits).
264 // Falls through for regular JS object. 264 // Falls through for regular JS object.
265 static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm, 265 static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
266 Register receiver, 266 Register receiver,
267 Register map, 267 Register map,
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 __ j(greater_equal, slow_case); 436 __ j(greater_equal, slow_case);
437 return FieldOperand(backing_store, 437 return FieldOperand(backing_store,
438 key, 438 key,
439 times_half_pointer_size, 439 times_half_pointer_size,
440 FixedArray::kHeaderSize); 440 FixedArray::kHeaderSize);
441 } 441 }
442 442
443 443
444 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 444 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
445 // ----------- S t a t e ------------- 445 // ----------- S t a t e -------------
446 // -- eax : key 446 // -- ecx : key
447 // -- edx : receiver 447 // -- edx : receiver
448 // -- esp[0] : return address 448 // -- esp[0] : return address
449 // ----------------------------------- 449 // -----------------------------------
450 Label slow, check_string, index_smi, index_string, property_array_property; 450 Label slow, check_string, index_smi, index_string, property_array_property;
451 Label probe_dictionary, check_number_dictionary; 451 Label probe_dictionary, check_number_dictionary;
452 452
453 // Check that the key is a smi. 453 // Check that the key is a smi.
454 __ JumpIfNotSmi(eax, &check_string); 454 __ JumpIfNotSmi(ecx, &check_string);
455 __ bind(&index_smi); 455 __ bind(&index_smi);
456 // Now the key is known to be a smi. This place is also jumped to from 456 // Now the key is known to be a smi. This place is also jumped to from
457 // where a numeric string is converted to a smi. 457 // where a numeric string is converted to a smi.
458 458
459 GenerateKeyedLoadReceiverCheck( 459 GenerateKeyedLoadReceiverCheck(
460 masm, edx, ecx, Map::kHasIndexedInterceptor, &slow); 460 masm, edx, eax, Map::kHasIndexedInterceptor, &slow);
461 461
462 // Check the receiver's map to see if it has fast elements. 462 // Check the receiver's map to see if it has fast elements.
463 __ CheckFastElements(ecx, &check_number_dictionary); 463 __ CheckFastElements(eax, &check_number_dictionary);
464 464
465 GenerateFastArrayLoad(masm, 465 GenerateFastArrayLoad(masm, edx, ecx, eax, eax, NULL, &slow);
466 edx,
467 eax,
468 ecx,
469 eax,
470 NULL,
471 &slow);
472 Isolate* isolate = masm->isolate(); 466 Isolate* isolate = masm->isolate();
473 Counters* counters = isolate->counters(); 467 Counters* counters = isolate->counters();
474 __ IncrementCounter(counters->keyed_load_generic_smi(), 1); 468 __ IncrementCounter(counters->keyed_load_generic_smi(), 1);
475 __ ret(0); 469 __ ret(0);
470
476 __ bind(&check_number_dictionary); 471 __ bind(&check_number_dictionary);
477 __ mov(ebx, eax); 472 __ mov(ebx, ecx);
478 __ SmiUntag(ebx); 473 __ SmiUntag(ebx);
479 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); 474 __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset));
480 475
481 // Check whether the elements is a number dictionary. 476 // Check whether the elements is a number dictionary.
482 // edx: receiver 477 // edx: receiver
483 // ebx: untagged index 478 // ebx: untagged index
484 // eax: key 479 // ecx: key
485 // ecx: elements 480 // eax: elements
486 __ CheckMap(ecx, 481 __ CheckMap(eax,
487 isolate->factory()->hash_table_map(), 482 isolate->factory()->hash_table_map(),
488 &slow, 483 &slow,
489 DONT_DO_SMI_CHECK); 484 DONT_DO_SMI_CHECK);
490 Label slow_pop_receiver; 485 Label slow_pop_receiver;
491 // Push receiver on the stack to free up a register for the dictionary 486 // Push receiver on the stack to free up a register for the dictionary
492 // probing. 487 // probing.
493 __ push(edx); 488 __ push(edx);
494 __ LoadFromNumberDictionary(&slow_pop_receiver, 489 __ LoadFromNumberDictionary(&slow_pop_receiver, eax, ecx, ebx, edx, edi, eax);
495 ecx,
496 eax,
497 ebx,
498 edx,
499 edi,
500 eax);
501 // Pop receiver before returning. 490 // Pop receiver before returning.
502 __ pop(edx); 491 __ pop(edx);
503 __ ret(0); 492 __ ret(0);
504 493
505 __ bind(&slow_pop_receiver); 494 __ bind(&slow_pop_receiver);
506 // Pop the receiver from the stack and jump to runtime. 495 // Pop the receiver from the stack and jump to runtime.
507 __ pop(edx); 496 __ pop(edx);
508 497
509 __ bind(&slow); 498 __ bind(&slow);
510 // Slow case: jump to runtime. 499 // Slow case: jump to runtime.
511 // edx: receiver 500 // edx: receiver
512 // eax: key 501 // ecx: key
513 __ IncrementCounter(counters->keyed_load_generic_slow(), 1); 502 __ IncrementCounter(counters->keyed_load_generic_slow(), 1);
514 GenerateRuntimeGetProperty(masm); 503 GenerateRuntimeGetProperty(masm);
515 504
516 __ bind(&check_string); 505 __ bind(&check_string);
517 GenerateKeyStringCheck(masm, eax, ecx, ebx, &index_string, &slow); 506 GenerateKeyStringCheck(masm, ecx, eax, ebx, &index_string, &slow);
518 507
519 GenerateKeyedLoadReceiverCheck( 508 GenerateKeyedLoadReceiverCheck(
520 masm, edx, ecx, Map::kHasNamedInterceptor, &slow); 509 masm, edx, eax, Map::kHasNamedInterceptor, &slow);
521 510
522 // If the receiver is a fast-case object, check the keyed lookup 511 // If the receiver is a fast-case object, check the keyed lookup
523 // cache. Otherwise probe the dictionary. 512 // cache. Otherwise probe the dictionary.
524 __ mov(ebx, FieldOperand(edx, JSObject::kPropertiesOffset)); 513 __ mov(ebx, FieldOperand(edx, JSObject::kPropertiesOffset));
525 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), 514 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
526 Immediate(isolate->factory()->hash_table_map())); 515 Immediate(isolate->factory()->hash_table_map()));
527 __ j(equal, &probe_dictionary); 516 __ j(equal, &probe_dictionary);
528 517
529 // Load the map of the receiver, compute the keyed lookup cache hash 518 // The receiver's map is still in eax, compute the keyed lookup cache hash
530 // based on 32 bits of the map pointer and the string hash. 519 // based on 32 bits of the map pointer and the string hash.
531 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); 520 if (FLAG_debug_code) {
532 __ mov(ecx, ebx); 521 Label ok;
533 __ shr(ecx, KeyedLookupCache::kMapHashShift); 522 __ cmp(eax, FieldOperand(edx, HeapObject::kMapOffset));
534 __ mov(edi, FieldOperand(eax, String::kHashFieldOffset)); 523 __ j(equal, &ok);
524 __ Abort("Map is no longer in eax.");
525 __ bind(&ok);
Yang 2012/04/27 12:47:12 Can be shortened with MacroAssembler::Check(Condit
Jakob Kummerow 2012/04/27 13:01:24 Good point. Done.
526 }
527 __ mov(ebx, eax); // Keep the map around for later.
528 __ shr(eax, KeyedLookupCache::kMapHashShift);
529 __ mov(edi, FieldOperand(ecx, String::kHashFieldOffset));
535 __ shr(edi, String::kHashShift); 530 __ shr(edi, String::kHashShift);
536 __ xor_(ecx, edi); 531 __ xor_(eax, edi);
537 __ and_(ecx, KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask); 532 __ and_(eax, KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask);
538 533
539 // Load the key (consisting of map and symbol) from the cache and 534 // Load the key (consisting of map and symbol) from the cache and
540 // check for match. 535 // check for match.
541 Label load_in_object_property; 536 Label load_in_object_property;
542 static const int kEntriesPerBucket = KeyedLookupCache::kEntriesPerBucket; 537 static const int kEntriesPerBucket = KeyedLookupCache::kEntriesPerBucket;
543 Label hit_on_nth_entry[kEntriesPerBucket]; 538 Label hit_on_nth_entry[kEntriesPerBucket];
544 ExternalReference cache_keys = 539 ExternalReference cache_keys =
545 ExternalReference::keyed_lookup_cache_keys(masm->isolate()); 540 ExternalReference::keyed_lookup_cache_keys(masm->isolate());
546 541
547 for (int i = 0; i < kEntriesPerBucket - 1; i++) { 542 for (int i = 0; i < kEntriesPerBucket - 1; i++) {
548 Label try_next_entry; 543 Label try_next_entry;
549 __ mov(edi, ecx); 544 __ mov(edi, eax);
550 __ shl(edi, kPointerSizeLog2 + 1); 545 __ shl(edi, kPointerSizeLog2 + 1);
551 if (i != 0) { 546 if (i != 0) {
552 __ add(edi, Immediate(kPointerSize * i * 2)); 547 __ add(edi, Immediate(kPointerSize * i * 2));
553 } 548 }
554 __ cmp(ebx, Operand::StaticArray(edi, times_1, cache_keys)); 549 __ cmp(ebx, Operand::StaticArray(edi, times_1, cache_keys));
555 __ j(not_equal, &try_next_entry); 550 __ j(not_equal, &try_next_entry);
556 __ add(edi, Immediate(kPointerSize)); 551 __ add(edi, Immediate(kPointerSize));
557 __ cmp(eax, Operand::StaticArray(edi, times_1, cache_keys)); 552 __ cmp(ecx, Operand::StaticArray(edi, times_1, cache_keys));
558 __ j(equal, &hit_on_nth_entry[i]); 553 __ j(equal, &hit_on_nth_entry[i]);
559 __ bind(&try_next_entry); 554 __ bind(&try_next_entry);
560 } 555 }
561 556
562 __ lea(edi, Operand(ecx, 1)); 557 __ lea(edi, Operand(eax, 1));
563 __ shl(edi, kPointerSizeLog2 + 1); 558 __ shl(edi, kPointerSizeLog2 + 1);
564 __ add(edi, Immediate(kPointerSize * (kEntriesPerBucket - 1) * 2)); 559 __ add(edi, Immediate(kPointerSize * (kEntriesPerBucket - 1) * 2));
565 __ cmp(ebx, Operand::StaticArray(edi, times_1, cache_keys)); 560 __ cmp(ebx, Operand::StaticArray(edi, times_1, cache_keys));
566 __ j(not_equal, &slow); 561 __ j(not_equal, &slow);
567 __ add(edi, Immediate(kPointerSize)); 562 __ add(edi, Immediate(kPointerSize));
568 __ cmp(eax, Operand::StaticArray(edi, times_1, cache_keys)); 563 __ cmp(ecx, Operand::StaticArray(edi, times_1, cache_keys));
569 __ j(not_equal, &slow); 564 __ j(not_equal, &slow);
570 565
571 // Get field offset. 566 // Get field offset.
572 // edx : receiver 567 // edx : receiver
573 // ebx : receiver's map 568 // ebx : receiver's map
574 // eax : key 569 // ecx : key
575 // ecx : lookup cache index 570 // eax : lookup cache index
576 ExternalReference cache_field_offsets = 571 ExternalReference cache_field_offsets =
577 ExternalReference::keyed_lookup_cache_field_offsets(masm->isolate()); 572 ExternalReference::keyed_lookup_cache_field_offsets(masm->isolate());
578 573
579 // Hit on nth entry. 574 // Hit on nth entry.
580 for (int i = kEntriesPerBucket - 1; i >= 0; i--) { 575 for (int i = kEntriesPerBucket - 1; i >= 0; i--) {
581 __ bind(&hit_on_nth_entry[i]); 576 __ bind(&hit_on_nth_entry[i]);
582 if (i != 0) { 577 if (i != 0) {
583 __ add(ecx, Immediate(i)); 578 __ add(eax, Immediate(i));
584 } 579 }
585 __ mov(edi, 580 __ mov(edi,
586 Operand::StaticArray(ecx, times_pointer_size, cache_field_offsets)); 581 Operand::StaticArray(eax, times_pointer_size, cache_field_offsets));
587 __ movzx_b(ecx, FieldOperand(ebx, Map::kInObjectPropertiesOffset)); 582 __ movzx_b(eax, FieldOperand(ebx, Map::kInObjectPropertiesOffset));
588 __ sub(edi, ecx); 583 __ sub(edi, eax);
589 __ j(above_equal, &property_array_property); 584 __ j(above_equal, &property_array_property);
590 if (i != 0) { 585 if (i != 0) {
591 __ jmp(&load_in_object_property); 586 __ jmp(&load_in_object_property);
592 } 587 }
593 } 588 }
594 589
595 // Load in-object property. 590 // Load in-object property.
596 __ bind(&load_in_object_property); 591 __ bind(&load_in_object_property);
597 __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceSizeOffset)); 592 __ movzx_b(eax, FieldOperand(ebx, Map::kInstanceSizeOffset));
598 __ add(ecx, edi); 593 __ add(eax, edi);
599 __ mov(eax, FieldOperand(edx, ecx, times_pointer_size, 0)); 594 __ mov(eax, FieldOperand(edx, eax, times_pointer_size, 0));
600 __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1); 595 __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
601 __ ret(0); 596 __ ret(0);
602 597
603 // Load property array property. 598 // Load property array property.
604 __ bind(&property_array_property); 599 __ bind(&property_array_property);
605 __ mov(eax, FieldOperand(edx, JSObject::kPropertiesOffset)); 600 __ mov(eax, FieldOperand(edx, JSObject::kPropertiesOffset));
606 __ mov(eax, FieldOperand(eax, edi, times_pointer_size, 601 __ mov(eax, FieldOperand(eax, edi, times_pointer_size,
607 FixedArray::kHeaderSize)); 602 FixedArray::kHeaderSize));
608 __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1); 603 __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
609 __ ret(0); 604 __ ret(0);
610 605
611 // Do a quick inline probe of the receiver's dictionary, if it 606 // Do a quick inline probe of the receiver's dictionary, if it
612 // exists. 607 // exists.
613 __ bind(&probe_dictionary); 608 __ bind(&probe_dictionary);
614 609
615 __ mov(ecx, FieldOperand(edx, JSObject::kMapOffset)); 610 __ mov(eax, FieldOperand(edx, JSObject::kMapOffset));
616 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 611 __ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset));
617 GenerateGlobalInstanceTypeCheck(masm, ecx, &slow); 612 GenerateGlobalInstanceTypeCheck(masm, eax, &slow);
618 613
619 GenerateDictionaryLoad(masm, &slow, ebx, eax, ecx, edi, eax); 614 GenerateDictionaryLoad(masm, &slow, ebx, ecx, eax, edi, eax);
620 __ IncrementCounter(counters->keyed_load_generic_symbol(), 1); 615 __ IncrementCounter(counters->keyed_load_generic_symbol(), 1);
621 __ ret(0); 616 __ ret(0);
622 617
623 __ bind(&index_string); 618 __ bind(&index_string);
624 __ IndexFromHash(ebx, eax); 619 __ IndexFromHash(ebx, ecx);
625 // Now jump to the place where smi keys are handled. 620 // Now jump to the place where smi keys are handled.
626 __ jmp(&index_smi); 621 __ jmp(&index_smi);
627 } 622 }
628 623
629 624
630 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { 625 void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
631 // ----------- S t a t e ------------- 626 // ----------- S t a t e -------------
632 // -- eax : key (index) 627 // -- ecx : key (index)
633 // -- edx : receiver 628 // -- edx : receiver
634 // -- esp[0] : return address 629 // -- esp[0] : return address
635 // ----------------------------------- 630 // -----------------------------------
636 Label miss; 631 Label miss;
637 632
638 Register receiver = edx; 633 Register receiver = edx;
639 Register index = eax; 634 Register index = ecx;
640 Register scratch = ecx; 635 Register scratch = ebx;
641 Register result = eax; 636 Register result = eax;
642 637
643 StringCharAtGenerator char_at_generator(receiver, 638 StringCharAtGenerator char_at_generator(receiver,
644 index, 639 index,
645 scratch, 640 scratch,
646 result, 641 result,
647 &miss, // When not a string. 642 &miss, // When not a string.
648 &miss, // When not a number. 643 &miss, // When not a number.
649 &miss, // When index out of range. 644 &miss, // When index out of range.
650 STRING_INDEX_IS_ARRAY_INDEX); 645 STRING_INDEX_IS_ARRAY_INDEX);
651 char_at_generator.GenerateFast(masm); 646 char_at_generator.GenerateFast(masm);
652 __ ret(0); 647 __ ret(0);
653 648
654 StubRuntimeCallHelper call_helper; 649 StubRuntimeCallHelper call_helper;
655 char_at_generator.GenerateSlow(masm, call_helper); 650 char_at_generator.GenerateSlow(masm, call_helper);
656 651
657 __ bind(&miss); 652 __ bind(&miss);
658 GenerateMiss(masm, false); 653 GenerateMiss(masm, false);
659 } 654 }
660 655
661 656
662 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { 657 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
663 // ----------- S t a t e ------------- 658 // ----------- S t a t e -------------
664 // -- eax : key 659 // -- ecx : key
665 // -- edx : receiver 660 // -- edx : receiver
666 // -- esp[0] : return address 661 // -- esp[0] : return address
667 // ----------------------------------- 662 // -----------------------------------
668 Label slow; 663 Label slow;
669 664
670 // Check that the receiver isn't a smi. 665 // Check that the receiver isn't a smi.
671 __ JumpIfSmi(edx, &slow); 666 __ JumpIfSmi(edx, &slow);
672 667
673 // Check that the key is an array index, that is Uint32. 668 // Check that the key is an array index, that is Uint32.
674 __ test(eax, Immediate(kSmiTagMask | kSmiSignMask)); 669 __ test(ecx, Immediate(kSmiTagMask | kSmiSignMask));
675 __ j(not_zero, &slow); 670 __ j(not_zero, &slow);
676 671
677 // Get the map of the receiver. 672 // Get the map of the receiver.
678 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 673 __ mov(eax, FieldOperand(edx, HeapObject::kMapOffset));
679 674
680 // Check that it has indexed interceptor and access checks 675 // Check that it has indexed interceptor and access checks
681 // are not enabled for this object. 676 // are not enabled for this object.
682 __ movzx_b(ecx, FieldOperand(ecx, Map::kBitFieldOffset)); 677 __ movzx_b(eax, FieldOperand(eax, Map::kBitFieldOffset));
683 __ and_(ecx, Immediate(kSlowCaseBitFieldMask)); 678 __ and_(eax, Immediate(kSlowCaseBitFieldMask));
684 __ cmp(ecx, Immediate(1 << Map::kHasIndexedInterceptor)); 679 __ cmp(eax, Immediate(1 << Map::kHasIndexedInterceptor));
685 __ j(not_zero, &slow); 680 __ j(not_zero, &slow);
686 681
687 // Everything is fine, call runtime. 682 // Everything is fine, call runtime.
688 __ pop(ecx); 683 __ pop(eax);
689 __ push(edx); // receiver 684 __ push(edx); // receiver
690 __ push(eax); // key 685 __ push(ecx); // key
691 __ push(ecx); // return address 686 __ push(eax); // return address
692 687
693 // Perform tail call to the entry. 688 // Perform tail call to the entry.
694 ExternalReference ref = 689 ExternalReference ref =
695 ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor), 690 ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor),
696 masm->isolate()); 691 masm->isolate());
697 __ TailCallExternalReference(ref, 2, 1); 692 __ TailCallExternalReference(ref, 2, 1);
698 693
699 __ bind(&slow); 694 __ bind(&slow);
700 GenerateMiss(masm, false); 695 GenerateMiss(masm, false);
701 } 696 }
702 697
703 698
704 void KeyedLoadIC::GenerateNonStrictArguments(MacroAssembler* masm) { 699 void KeyedLoadIC::GenerateNonStrictArguments(MacroAssembler* masm) {
705 // ----------- S t a t e ------------- 700 // ----------- S t a t e -------------
706 // -- eax : key 701 // -- ecx : key
707 // -- edx : receiver 702 // -- edx : receiver
708 // -- esp[0] : return address 703 // -- esp[0] : return address
709 // ----------------------------------- 704 // -----------------------------------
710 Label slow, notin; 705 Label slow, notin;
711 Factory* factory = masm->isolate()->factory(); 706 Factory* factory = masm->isolate()->factory();
712 Operand mapped_location = 707 Operand mapped_location =
713 GenerateMappedArgumentsLookup(masm, edx, eax, ebx, ecx, &notin, &slow); 708 GenerateMappedArgumentsLookup(masm, edx, ecx, ebx, eax, &notin, &slow);
714 __ mov(eax, mapped_location); 709 __ mov(eax, mapped_location);
715 __ Ret(); 710 __ Ret();
716 __ bind(&notin); 711 __ bind(&notin);
717 // The unmapped lookup expects that the parameter map is in ebx. 712 // The unmapped lookup expects that the parameter map is in ebx.
718 Operand unmapped_location = 713 Operand unmapped_location =
719 GenerateUnmappedArgumentsLookup(masm, eax, ebx, ecx, &slow); 714 GenerateUnmappedArgumentsLookup(masm, ecx, ebx, eax, &slow);
720 __ cmp(unmapped_location, factory->the_hole_value()); 715 __ cmp(unmapped_location, factory->the_hole_value());
721 __ j(equal, &slow); 716 __ j(equal, &slow);
722 __ mov(eax, unmapped_location); 717 __ mov(eax, unmapped_location);
723 __ Ret(); 718 __ Ret();
724 __ bind(&slow); 719 __ bind(&slow);
725 GenerateMiss(masm, false); 720 GenerateMiss(masm, false);
726 } 721 }
727 722
728 723
729 void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) { 724 void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) {
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after
1301 Condition cond = masm->IsObjectStringType(ecx, eax, eax); 1296 Condition cond = masm->IsObjectStringType(ecx, eax, eax);
1302 __ j(NegateCondition(cond), &miss); 1297 __ j(NegateCondition(cond), &miss);
1303 CallICBase::GenerateNormal(masm, argc); 1298 CallICBase::GenerateNormal(masm, argc);
1304 __ bind(&miss); 1299 __ bind(&miss);
1305 GenerateMiss(masm, argc); 1300 GenerateMiss(masm, argc);
1306 } 1301 }
1307 1302
1308 1303
1309 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { 1304 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
1310 // ----------- S t a t e ------------- 1305 // ----------- S t a t e -------------
1311 // -- eax : receiver
1312 // -- ecx : name 1306 // -- ecx : name
1307 // -- edx : receiver
1313 // -- esp[0] : return address 1308 // -- esp[0] : return address
1314 // ----------------------------------- 1309 // -----------------------------------
1315 1310
1316 // Probe the stub cache. 1311 // Probe the stub cache.
1317 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, MONOMORPHIC); 1312 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, MONOMORPHIC);
1318 Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, eax, ecx, ebx, 1313 Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx,
1319 edx); 1314 eax);
1320 1315
1321 // Cache miss: Jump to runtime. 1316 // Cache miss: Jump to runtime.
1322 GenerateMiss(masm); 1317 GenerateMiss(masm);
1323 } 1318 }
1324 1319
1325 1320
1326 void LoadIC::GenerateNormal(MacroAssembler* masm) { 1321 void LoadIC::GenerateNormal(MacroAssembler* masm) {
1327 // ----------- S t a t e ------------- 1322 // ----------- S t a t e -------------
1328 // -- eax : receiver
1329 // -- ecx : name 1323 // -- ecx : name
1324 // -- edx : receiver
1330 // -- esp[0] : return address 1325 // -- esp[0] : return address
1331 // ----------------------------------- 1326 // -----------------------------------
1332 Label miss; 1327 Label miss;
1333 1328
1334 GenerateStringDictionaryReceiverCheck(masm, eax, edx, ebx, &miss); 1329 GenerateStringDictionaryReceiverCheck(masm, edx, eax, ebx, &miss);
1335 1330
1336 // edx: elements 1331 // eax: elements
1337 // Search the dictionary placing the result in eax. 1332 // Search the dictionary placing the result in eax.
1338 GenerateDictionaryLoad(masm, &miss, edx, ecx, edi, ebx, eax); 1333 GenerateDictionaryLoad(masm, &miss, eax, ecx, edi, ebx, eax);
1339 __ ret(0); 1334 __ ret(0);
1340 1335
1341 // Cache miss: Jump to runtime. 1336 // Cache miss: Jump to runtime.
1342 __ bind(&miss); 1337 __ bind(&miss);
1343 GenerateMiss(masm); 1338 GenerateMiss(masm);
1344 } 1339 }
1345 1340
1346 1341
1347 void LoadIC::GenerateMiss(MacroAssembler* masm) { 1342 void LoadIC::GenerateMiss(MacroAssembler* masm) {
1348 // ----------- S t a t e ------------- 1343 // ----------- S t a t e -------------
1349 // -- eax : receiver
1350 // -- ecx : name 1344 // -- ecx : name
1345 // -- edx : receiver
1351 // -- esp[0] : return address 1346 // -- esp[0] : return address
1352 // ----------------------------------- 1347 // -----------------------------------
1353 1348
1354 __ IncrementCounter(masm->isolate()->counters()->load_miss(), 1); 1349 __ IncrementCounter(masm->isolate()->counters()->load_miss(), 1);
1355 1350
1356 __ pop(ebx); 1351 __ pop(ebx);
1357 __ push(eax); // receiver 1352 __ push(edx); // receiver
1358 __ push(ecx); // name 1353 __ push(ecx); // name
1359 __ push(ebx); // return address 1354 __ push(ebx); // return address
1360 1355
1361 // Perform tail call to the entry. 1356 // Perform tail call to the entry.
1362 ExternalReference ref = 1357 ExternalReference ref =
1363 ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate()); 1358 ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate());
1364 __ TailCallExternalReference(ref, 2, 1); 1359 __ TailCallExternalReference(ref, 2, 1);
1365 } 1360 }
1366 1361
1367 1362
1368 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) { 1363 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
1369 // ----------- S t a t e ------------- 1364 // ----------- S t a t e -------------
1370 // -- eax : key 1365 // -- ecx : key
1371 // -- edx : receiver 1366 // -- edx : receiver
1372 // -- esp[0] : return address 1367 // -- esp[0] : return address
1373 // ----------------------------------- 1368 // -----------------------------------
1374 1369
1375 __ IncrementCounter(masm->isolate()->counters()->keyed_load_miss(), 1); 1370 __ IncrementCounter(masm->isolate()->counters()->keyed_load_miss(), 1);
1376 1371
1377 __ pop(ebx); 1372 __ pop(ebx);
1378 __ push(edx); // receiver 1373 __ push(edx); // receiver
1379 __ push(eax); // name 1374 __ push(ecx); // name
1380 __ push(ebx); // return address 1375 __ push(ebx); // return address
1381 1376
1382 // Perform tail call to the entry. 1377 // Perform tail call to the entry.
1383 ExternalReference ref = force_generic 1378 ExternalReference ref = force_generic
1384 ? ExternalReference(IC_Utility(kKeyedLoadIC_MissForceGeneric), 1379 ? ExternalReference(IC_Utility(kKeyedLoadIC_MissForceGeneric),
1385 masm->isolate()) 1380 masm->isolate())
1386 : ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); 1381 : ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate());
1387 __ TailCallExternalReference(ref, 2, 1); 1382 __ TailCallExternalReference(ref, 2, 1);
1388 } 1383 }
1389 1384
1390 1385
1391 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { 1386 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
1392 // ----------- S t a t e ------------- 1387 // ----------- S t a t e -------------
1393 // -- eax : key 1388 // -- ecx : key
1394 // -- edx : receiver 1389 // -- edx : receiver
1395 // -- esp[0] : return address 1390 // -- esp[0] : return address
1396 // ----------------------------------- 1391 // -----------------------------------
1397 1392
1398 __ pop(ebx); 1393 __ pop(ebx);
1399 __ push(edx); // receiver 1394 __ push(edx); // receiver
1400 __ push(eax); // name 1395 __ push(ecx); // name
1401 __ push(ebx); // return address 1396 __ push(ebx); // return address
1402 1397
1403 // Perform tail call to the entry. 1398 // Perform tail call to the entry.
1404 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); 1399 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
1405 } 1400 }
1406 1401
1407 1402
1408 void StoreIC::GenerateMegamorphic(MacroAssembler* masm, 1403 void StoreIC::GenerateMegamorphic(MacroAssembler* masm,
1409 StrictModeFlag strict_mode) { 1404 StrictModeFlag strict_mode) {
1410 // ----------- S t a t e ------------- 1405 // ----------- S t a t e -------------
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
1769 Condition cc = *jmp_address == Assembler::kJncShortOpcode 1764 Condition cc = *jmp_address == Assembler::kJncShortOpcode
1770 ? not_zero 1765 ? not_zero
1771 : zero; 1766 : zero;
1772 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 1767 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
1773 } 1768 }
1774 1769
1775 1770
1776 } } // namespace v8::internal 1771 } } // namespace v8::internal
1777 1772
1778 #endif // V8_TARGET_ARCH_IA32 1773 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698