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

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

Issue 338963003: KeyedLoadIC should have same register spec as LoadIC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Last comment response. Created 6 years, 5 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.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_ARM 7 #if V8_TARGET_ARCH_ARM
8 8
9 #include "src/arm/assembler-arm.h" 9 #include "src/arm/assembler-arm.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 __ ldrb(hash, FieldMemOperand(map, Map::kInstanceTypeOffset)); 304 __ ldrb(hash, FieldMemOperand(map, Map::kInstanceTypeOffset));
305 STATIC_ASSERT(kInternalizedTag == 0); 305 STATIC_ASSERT(kInternalizedTag == 0);
306 __ tst(hash, Operand(kIsNotInternalizedMask)); 306 __ tst(hash, Operand(kIsNotInternalizedMask));
307 __ b(ne, not_unique); 307 __ b(ne, not_unique);
308 308
309 __ bind(&unique); 309 __ bind(&unique);
310 } 310 }
311 311
312 312
313 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { 313 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
314 // ----------- S t a t e ------------- 314 // The return address is in lr.
315 // -- r2 : name 315 Register receiver = ReceiverRegister();
316 // -- lr : return address 316 Register name = NameRegister();
317 // -- r0 : receiver 317 ASSERT(receiver.is(r1));
318 // ----------------------------------- 318 ASSERT(name.is(r2));
319 ASSERT(r0.is(ReceiverRegister()));
320 ASSERT(r2.is(NameRegister()));
321 319
322 // Probe the stub cache. 320 // Probe the stub cache.
323 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); 321 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC);
324 masm->isolate()->stub_cache()->GenerateProbe( 322 masm->isolate()->stub_cache()->GenerateProbe(
325 masm, flags, r0, r2, r3, r4, r5, r6); 323 masm, flags, receiver, name, r3, r4, r5, r6);
326 324
327 // Cache miss: Jump to runtime. 325 // Cache miss: Jump to runtime.
328 GenerateMiss(masm); 326 GenerateMiss(masm);
329 } 327 }
330 328
331 329
332 void LoadIC::GenerateNormal(MacroAssembler* masm) { 330 void LoadIC::GenerateNormal(MacroAssembler* masm) {
333 // ----------- S t a t e ------------- 331 // ----------- S t a t e -------------
334 // -- r2 : name 332 // -- r2 : name
335 // -- lr : return address 333 // -- lr : return address
336 // -- r0 : receiver 334 // -- r1 : receiver
337 // ----------------------------------- 335 // -----------------------------------
338 ASSERT(r0.is(ReceiverRegister())); 336 ASSERT(r1.is(ReceiverRegister()));
339 ASSERT(r2.is(NameRegister())); 337 ASSERT(r2.is(NameRegister()));
340 338
341 Label miss, slow; 339 Label miss, slow;
342 340
343 GenerateNameDictionaryReceiverCheck(masm, r0, r1, r3, r4, &miss); 341 GenerateNameDictionaryReceiverCheck(masm, r1, r0, r3, r4, &miss);
344 342
345 // r1: elements 343 // r0: elements
346 GenerateDictionaryLoad(masm, &slow, r1, r2, r0, r3, r4); 344 GenerateDictionaryLoad(masm, &slow, r0, r2, r0, r3, r4);
347 __ Ret(); 345 __ Ret();
348 346
349 // Dictionary load failed, go slow (but don't miss). 347 // Dictionary load failed, go slow (but don't miss).
350 __ bind(&slow); 348 __ bind(&slow);
351 GenerateRuntimeGetProperty(masm); 349 GenerateRuntimeGetProperty(masm);
352 350
353 // Cache miss: Jump to runtime. 351 // Cache miss: Jump to runtime.
354 __ bind(&miss); 352 __ bind(&miss);
355 GenerateMiss(masm); 353 GenerateMiss(masm);
356 } 354 }
357 355
358 356
359 // A register that isn't one of the parameters to the load ic. 357 // A register that isn't one of the parameters to the load ic.
360 static const Register LoadIC_TempRegister() { return r3; } 358 static const Register LoadIC_TempRegister() { return r3; }
361 359
362 360
363 void LoadIC::GenerateMiss(MacroAssembler* masm) { 361 void LoadIC::GenerateMiss(MacroAssembler* masm) {
364 // The return address is on the stack. 362 // The return address is in lr.
365 Isolate* isolate = masm->isolate(); 363 Isolate* isolate = masm->isolate();
366 364
367 __ IncrementCounter(isolate->counters()->load_miss(), 1, r3, r4); 365 __ IncrementCounter(isolate->counters()->load_miss(), 1, r3, r4);
368 366
369 __ mov(LoadIC_TempRegister(), ReceiverRegister()); 367 __ mov(LoadIC_TempRegister(), ReceiverRegister());
370 __ Push(LoadIC_TempRegister(), NameRegister()); 368 __ Push(LoadIC_TempRegister(), NameRegister());
371 369
372 // Perform tail call to the entry. 370 // Perform tail call to the entry.
373 ExternalReference ref = 371 ExternalReference ref =
374 ExternalReference(IC_Utility(kLoadIC_Miss), isolate); 372 ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
375 __ TailCallExternalReference(ref, 2, 1); 373 __ TailCallExternalReference(ref, 2, 1);
376 } 374 }
377 375
378 376
379 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { 377 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
380 // The return address is on the stack. 378 // The return address is in lr.
381 379
382 __ mov(LoadIC_TempRegister(), ReceiverRegister()); 380 __ mov(LoadIC_TempRegister(), ReceiverRegister());
383 __ Push(LoadIC_TempRegister(), NameRegister()); 381 __ Push(LoadIC_TempRegister(), NameRegister());
384 382
385 __ TailCallRuntime(Runtime::kGetProperty, 2, 1); 383 __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
386 } 384 }
387 385
388 386
389 static MemOperand GenerateMappedArgumentsLookup(MacroAssembler* masm, 387 static MemOperand GenerateMappedArgumentsLookup(MacroAssembler* masm,
390 Register object, 388 Register object,
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 __ mov(scratch, Operand(kPointerSize >> 1)); 463 __ mov(scratch, Operand(kPointerSize >> 1));
466 __ mul(scratch, key, scratch); 464 __ mul(scratch, key, scratch);
467 __ add(scratch, 465 __ add(scratch,
468 scratch, 466 scratch,
469 Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 467 Operand(FixedArray::kHeaderSize - kHeapObjectTag));
470 return MemOperand(backing_store, scratch); 468 return MemOperand(backing_store, scratch);
471 } 469 }
472 470
473 471
474 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { 472 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
475 // ---------- S t a t e -------------- 473 // The return address is in lr.
476 // -- lr : return address 474 Register receiver = ReceiverRegister();
477 // -- r0 : key 475 Register key = NameRegister();
478 // -- r1 : receiver 476 ASSERT(receiver.is(r1));
479 // ----------------------------------- 477 ASSERT(key.is(r2));
480 ASSERT(r1.is(ReceiverRegister())); 478
481 ASSERT(r0.is(NameRegister()));
482 Label slow, notin; 479 Label slow, notin;
483 MemOperand mapped_location = 480 MemOperand mapped_location =
484 GenerateMappedArgumentsLookup(masm, r1, r0, r2, r3, r4, &notin, &slow); 481 GenerateMappedArgumentsLookup(
482 masm, receiver, key, r0, r3, r4, &notin, &slow);
485 __ ldr(r0, mapped_location); 483 __ ldr(r0, mapped_location);
486 __ Ret(); 484 __ Ret();
487 __ bind(&notin); 485 __ bind(&notin);
488 // The unmapped lookup expects that the parameter map is in r2. 486 // The unmapped lookup expects that the parameter map is in r0.
489 MemOperand unmapped_location = 487 MemOperand unmapped_location =
490 GenerateUnmappedArgumentsLookup(masm, r0, r2, r3, &slow); 488 GenerateUnmappedArgumentsLookup(masm, key, r0, r3, &slow);
491 __ ldr(r2, unmapped_location); 489 __ ldr(r0, unmapped_location);
492 __ LoadRoot(r3, Heap::kTheHoleValueRootIndex); 490 __ LoadRoot(r3, Heap::kTheHoleValueRootIndex);
493 __ cmp(r2, r3); 491 __ cmp(r0, r3);
494 __ b(eq, &slow); 492 __ b(eq, &slow);
495 __ mov(r0, r2);
496 __ Ret(); 493 __ Ret();
497 __ bind(&slow); 494 __ bind(&slow);
498 GenerateMiss(masm); 495 GenerateMiss(masm);
499 } 496 }
500 497
501 498
502 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { 499 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
503 // ---------- S t a t e -------------- 500 // ---------- S t a t e --------------
504 // -- r0 : value 501 // -- r0 : value
505 // -- r1 : key 502 // -- r1 : key
(...skipping 16 matching lines...) Expand all
522 __ add(r6, r3, r4); 519 __ add(r6, r3, r4);
523 __ mov(r9, r0); 520 __ mov(r9, r0);
524 __ RecordWrite(r3, r6, r9, kLRHasNotBeenSaved, kDontSaveFPRegs); 521 __ RecordWrite(r3, r6, r9, kLRHasNotBeenSaved, kDontSaveFPRegs);
525 __ Ret(); 522 __ Ret();
526 __ bind(&slow); 523 __ bind(&slow);
527 GenerateMiss(masm); 524 GenerateMiss(masm);
528 } 525 }
529 526
530 527
531 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { 528 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
532 // The return address is on the stack. 529 // The return address is in lr.
533 Isolate* isolate = masm->isolate(); 530 Isolate* isolate = masm->isolate();
534 531
535 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r3, r4); 532 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r3, r4);
536 533
537 __ Push(ReceiverRegister(), NameRegister()); 534 __ Push(ReceiverRegister(), NameRegister());
538 535
539 // Perform tail call to the entry. 536 // Perform tail call to the entry.
540 ExternalReference ref = 537 ExternalReference ref =
541 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate); 538 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
542 539
543 __ TailCallExternalReference(ref, 2, 1); 540 __ TailCallExternalReference(ref, 2, 1);
544 } 541 }
545 542
546 543
547 // IC register specifications 544 // IC register specifications
548 const Register LoadIC::ReceiverRegister() { return r0; } 545 const Register LoadIC::ReceiverRegister() { return r1; }
549 const Register LoadIC::NameRegister() { return r2; } 546 const Register LoadIC::NameRegister() { return r2; }
550 const Register KeyedLoadIC::ReceiverRegister() { return r1; }
551 const Register KeyedLoadIC::NameRegister() { return r0; }
552 547
553 548
554 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { 549 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
555 // The return address is on the stack. 550 // The return address is in lr.
556 551
557 __ Push(ReceiverRegister(), NameRegister()); 552 __ Push(ReceiverRegister(), NameRegister());
558 553
559 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); 554 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
560 } 555 }
561 556
562 557
563 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 558 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
564 // ---------- S t a t e -------------- 559 // The return address is in lr.
565 // -- lr : return address
566 // -- r0 : key
567 // -- r1 : receiver
568 // -----------------------------------
569 Label slow, check_name, index_smi, index_name, property_array_property; 560 Label slow, check_name, index_smi, index_name, property_array_property;
570 Label probe_dictionary, check_number_dictionary; 561 Label probe_dictionary, check_number_dictionary;
571 562
572 Register key = NameRegister(); 563 Register key = NameRegister();
573 Register receiver = ReceiverRegister(); 564 Register receiver = ReceiverRegister();
574 ASSERT(key.is(r0)); 565 ASSERT(key.is(r2));
575 ASSERT(receiver.is(r1)); 566 ASSERT(receiver.is(r1));
576 567
577 Isolate* isolate = masm->isolate(); 568 Isolate* isolate = masm->isolate();
578 569
579 // Check that the key is a smi. 570 // Check that the key is a smi.
580 __ JumpIfNotSmi(key, &check_name); 571 __ JumpIfNotSmi(key, &check_name);
581 __ bind(&index_smi); 572 __ bind(&index_smi);
582 // Now the key is known to be a smi. This place is also jumped to from below 573 // Now the key is known to be a smi. This place is also jumped to from below
583 // where a numeric string is converted to a smi. 574 // where a numeric string is converted to a smi.
584 575
585 GenerateKeyedLoadReceiverCheck( 576 GenerateKeyedLoadReceiverCheck(
586 masm, receiver, r2, r3, Map::kHasIndexedInterceptor, &slow); 577 masm, receiver, r0, r3, Map::kHasIndexedInterceptor, &slow);
587 578
588 // Check the receiver's map to see if it has fast elements. 579 // Check the receiver's map to see if it has fast elements.
589 __ CheckFastElements(r2, r3, &check_number_dictionary); 580 __ CheckFastElements(r0, r3, &check_number_dictionary);
590 581
591 GenerateFastArrayLoad( 582 GenerateFastArrayLoad(
592 masm, receiver, key, r4, r3, r2, r0, NULL, &slow); 583 masm, receiver, key, r0, r3, r4, r0, NULL, &slow);
593 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r2, r3); 584 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r4, r3);
594 __ Ret(); 585 __ Ret();
595 586
596 __ bind(&check_number_dictionary); 587 __ bind(&check_number_dictionary);
597 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset)); 588 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset));
598 __ ldr(r3, FieldMemOperand(r4, JSObject::kMapOffset)); 589 __ ldr(r3, FieldMemOperand(r4, JSObject::kMapOffset));
599 590
600 // Check whether the elements is a number dictionary. 591 // Check whether the elements is a number dictionary.
601 // r0: key
602 // r3: elements map 592 // r3: elements map
603 // r4: elements 593 // r4: elements
604 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); 594 __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
605 __ cmp(r3, ip); 595 __ cmp(r3, ip);
606 __ b(ne, &slow); 596 __ b(ne, &slow);
607 __ SmiUntag(r2, r0); 597 __ SmiUntag(r0, key);
608 __ LoadFromNumberDictionary(&slow, r4, r0, r0, r2, r3, r5); 598 __ LoadFromNumberDictionary(&slow, r4, key, r0, r0, r3, r5);
609 __ Ret(); 599 __ Ret();
610 600
611 // Slow case, key and receiver still in r0 and r1. 601 // Slow case, key and receiver still in r2 and r1.
612 __ bind(&slow); 602 __ bind(&slow);
613 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 603 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(),
614 1, r2, r3); 604 1, r4, r3);
615 GenerateRuntimeGetProperty(masm); 605 GenerateRuntimeGetProperty(masm);
616 606
617 __ bind(&check_name); 607 __ bind(&check_name);
618 GenerateKeyNameCheck(masm, key, r2, r3, &index_name, &slow); 608 GenerateKeyNameCheck(masm, key, r0, r3, &index_name, &slow);
619 609
620 GenerateKeyedLoadReceiverCheck( 610 GenerateKeyedLoadReceiverCheck(
621 masm, receiver, r2, r3, Map::kHasNamedInterceptor, &slow); 611 masm, receiver, r0, r3, Map::kHasNamedInterceptor, &slow);
622 612
623 // If the receiver is a fast-case object, check the keyed lookup 613 // If the receiver is a fast-case object, check the keyed lookup
624 // cache. Otherwise probe the dictionary. 614 // cache. Otherwise probe the dictionary.
625 __ ldr(r3, FieldMemOperand(r1, JSObject::kPropertiesOffset)); 615 __ ldr(r3, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
626 __ ldr(r4, FieldMemOperand(r3, HeapObject::kMapOffset)); 616 __ ldr(r4, FieldMemOperand(r3, HeapObject::kMapOffset));
627 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); 617 __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
628 __ cmp(r4, ip); 618 __ cmp(r4, ip);
629 __ b(eq, &probe_dictionary); 619 __ b(eq, &probe_dictionary);
630 620
631 // Load the map of the receiver, compute the keyed lookup cache hash 621 // Load the map of the receiver, compute the keyed lookup cache hash
632 // based on 32 bits of the map pointer and the name hash. 622 // based on 32 bits of the map pointer and the name hash.
633 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); 623 __ ldr(r0, FieldMemOperand(receiver, HeapObject::kMapOffset));
634 __ mov(r3, Operand(r2, ASR, KeyedLookupCache::kMapHashShift)); 624 __ mov(r3, Operand(r0, ASR, KeyedLookupCache::kMapHashShift));
635 __ ldr(r4, FieldMemOperand(r0, Name::kHashFieldOffset)); 625 __ ldr(r4, FieldMemOperand(key, Name::kHashFieldOffset));
636 __ eor(r3, r3, Operand(r4, ASR, Name::kHashShift)); 626 __ eor(r3, r3, Operand(r4, ASR, Name::kHashShift));
637 int mask = KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask; 627 int mask = KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask;
638 __ And(r3, r3, Operand(mask)); 628 __ And(r3, r3, Operand(mask));
639 629
640 // Load the key (consisting of map and unique name) from the cache and 630 // Load the key (consisting of map and unique name) from the cache and
641 // check for match. 631 // check for match.
642 Label load_in_object_property; 632 Label load_in_object_property;
643 static const int kEntriesPerBucket = KeyedLookupCache::kEntriesPerBucket; 633 static const int kEntriesPerBucket = KeyedLookupCache::kEntriesPerBucket;
644 Label hit_on_nth_entry[kEntriesPerBucket]; 634 Label hit_on_nth_entry[kEntriesPerBucket];
645 ExternalReference cache_keys = 635 ExternalReference cache_keys =
646 ExternalReference::keyed_lookup_cache_keys(isolate); 636 ExternalReference::keyed_lookup_cache_keys(isolate);
647 637
648 __ mov(r4, Operand(cache_keys)); 638 __ mov(r4, Operand(cache_keys));
649 __ add(r4, r4, Operand(r3, LSL, kPointerSizeLog2 + 1)); 639 __ add(r4, r4, Operand(r3, LSL, kPointerSizeLog2 + 1));
650 640
651 for (int i = 0; i < kEntriesPerBucket - 1; i++) { 641 for (int i = 0; i < kEntriesPerBucket - 1; i++) {
652 Label try_next_entry; 642 Label try_next_entry;
653 // Load map and move r4 to next entry. 643 // Load map and move r4 to next entry.
654 __ ldr(r5, MemOperand(r4, kPointerSize * 2, PostIndex)); 644 __ ldr(r5, MemOperand(r4, kPointerSize * 2, PostIndex));
655 __ cmp(r2, r5); 645 __ cmp(r0, r5);
656 __ b(ne, &try_next_entry); 646 __ b(ne, &try_next_entry);
657 __ ldr(r5, MemOperand(r4, -kPointerSize)); // Load name 647 __ ldr(r5, MemOperand(r4, -kPointerSize)); // Load name
658 __ cmp(r0, r5); 648 __ cmp(key, r5);
659 __ b(eq, &hit_on_nth_entry[i]); 649 __ b(eq, &hit_on_nth_entry[i]);
660 __ bind(&try_next_entry); 650 __ bind(&try_next_entry);
661 } 651 }
662 652
663 // Last entry: Load map and move r4 to name. 653 // Last entry: Load map and move r4 to name.
664 __ ldr(r5, MemOperand(r4, kPointerSize, PostIndex)); 654 __ ldr(r5, MemOperand(r4, kPointerSize, PostIndex));
665 __ cmp(r2, r5); 655 __ cmp(r0, r5);
666 __ b(ne, &slow); 656 __ b(ne, &slow);
667 __ ldr(r5, MemOperand(r4)); 657 __ ldr(r5, MemOperand(r4));
668 __ cmp(r0, r5); 658 __ cmp(key, r5);
669 __ b(ne, &slow); 659 __ b(ne, &slow);
670 660
671 // Get field offset. 661 // Get field offset.
672 // r0 : key 662 // r0 : receiver's map
673 // r1 : receiver
674 // r2 : receiver's map
675 // r3 : lookup cache index 663 // r3 : lookup cache index
676 ExternalReference cache_field_offsets = 664 ExternalReference cache_field_offsets =
677 ExternalReference::keyed_lookup_cache_field_offsets(isolate); 665 ExternalReference::keyed_lookup_cache_field_offsets(isolate);
678 666
679 // Hit on nth entry. 667 // Hit on nth entry.
680 for (int i = kEntriesPerBucket - 1; i >= 0; i--) { 668 for (int i = kEntriesPerBucket - 1; i >= 0; i--) {
681 __ bind(&hit_on_nth_entry[i]); 669 __ bind(&hit_on_nth_entry[i]);
682 __ mov(r4, Operand(cache_field_offsets)); 670 __ mov(r4, Operand(cache_field_offsets));
683 if (i != 0) { 671 if (i != 0) {
684 __ add(r3, r3, Operand(i)); 672 __ add(r3, r3, Operand(i));
685 } 673 }
686 __ ldr(r5, MemOperand(r4, r3, LSL, kPointerSizeLog2)); 674 __ ldr(r5, MemOperand(r4, r3, LSL, kPointerSizeLog2));
687 __ ldrb(r6, FieldMemOperand(r2, Map::kInObjectPropertiesOffset)); 675 __ ldrb(r6, FieldMemOperand(r0, Map::kInObjectPropertiesOffset));
688 __ sub(r5, r5, r6, SetCC); 676 __ sub(r5, r5, r6, SetCC);
689 __ b(ge, &property_array_property); 677 __ b(ge, &property_array_property);
690 if (i != 0) { 678 if (i != 0) {
691 __ jmp(&load_in_object_property); 679 __ jmp(&load_in_object_property);
692 } 680 }
693 } 681 }
694 682
695 // Load in-object property. 683 // Load in-object property.
696 __ bind(&load_in_object_property); 684 __ bind(&load_in_object_property);
697 __ ldrb(r6, FieldMemOperand(r2, Map::kInstanceSizeOffset)); 685 __ ldrb(r6, FieldMemOperand(r0, Map::kInstanceSizeOffset));
698 __ add(r6, r6, r5); // Index from start of object. 686 __ add(r6, r6, r5); // Index from start of object.
699 __ sub(r1, r1, Operand(kHeapObjectTag)); // Remove the heap tag. 687 __ sub(receiver, receiver, Operand(kHeapObjectTag)); // Remove the heap tag.
700 __ ldr(r0, MemOperand(r1, r6, LSL, kPointerSizeLog2)); 688 __ ldr(r0, MemOperand(receiver, r6, LSL, kPointerSizeLog2));
701 __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(), 689 __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(),
702 1, r2, r3); 690 1, r4, r3);
703 __ Ret(); 691 __ Ret();
704 692
705 // Load property array property. 693 // Load property array property.
706 __ bind(&property_array_property); 694 __ bind(&property_array_property);
707 __ ldr(r1, FieldMemOperand(r1, JSObject::kPropertiesOffset)); 695 __ ldr(receiver, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
708 __ add(r1, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 696 __ add(receiver, receiver, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
709 __ ldr(r0, MemOperand(r1, r5, LSL, kPointerSizeLog2)); 697 __ ldr(r0, MemOperand(receiver, r5, LSL, kPointerSizeLog2));
710 __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(), 698 __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(),
711 1, r2, r3); 699 1, r4, r3);
712 __ Ret(); 700 __ Ret();
713 701
714 // Do a quick inline probe of the receiver's dictionary, if it 702 // Do a quick inline probe of the receiver's dictionary, if it
715 // exists. 703 // exists.
716 __ bind(&probe_dictionary); 704 __ bind(&probe_dictionary);
717 // r1: receiver
718 // r0: key
719 // r3: elements 705 // r3: elements
720 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); 706 __ ldr(r0, FieldMemOperand(receiver, HeapObject::kMapOffset));
721 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); 707 __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset));
722 GenerateGlobalInstanceTypeCheck(masm, r2, &slow); 708 GenerateGlobalInstanceTypeCheck(masm, r0, &slow);
723 // Load the property to r0. 709 // Load the property to r0.
724 GenerateDictionaryLoad(masm, &slow, r3, r0, r0, r2, r4); 710 GenerateDictionaryLoad(masm, &slow, r3, key, r0, r5, r4);
725 __ IncrementCounter( 711 __ IncrementCounter(
726 isolate->counters()->keyed_load_generic_symbol(), 1, r2, r3); 712 isolate->counters()->keyed_load_generic_symbol(), 1, r4, r3);
727 __ Ret(); 713 __ Ret();
728 714
729 __ bind(&index_name); 715 __ bind(&index_name);
730 __ IndexFromHash(r3, key); 716 __ IndexFromHash(r3, key);
731 // Now jump to the place where smi keys are handled. 717 // Now jump to the place where smi keys are handled.
732 __ jmp(&index_smi); 718 __ jmp(&index_smi);
733 } 719 }
734 720
735 721
736 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { 722 void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
737 // Return address is on the stack. 723 // Return address is in lr.
738 Label miss; 724 Label miss;
739 725
740 Register receiver = ReceiverRegister(); 726 Register receiver = ReceiverRegister();
741 Register index = NameRegister(); 727 Register index = NameRegister();
742 Register scratch = r3; 728 Register scratch = r3;
743 Register result = r0; 729 Register result = r0;
744 ASSERT(!scratch.is(receiver) && !scratch.is(index)); 730 ASSERT(!scratch.is(receiver) && !scratch.is(index));
745 731
746 StringCharAtGenerator char_at_generator(receiver, 732 StringCharAtGenerator char_at_generator(receiver,
747 index, 733 index,
748 scratch, 734 scratch,
749 result, 735 result,
750 &miss, // When not a string. 736 &miss, // When not a string.
751 &miss, // When not a number. 737 &miss, // When not a number.
752 &miss, // When index out of range. 738 &miss, // When index out of range.
753 STRING_INDEX_IS_ARRAY_INDEX); 739 STRING_INDEX_IS_ARRAY_INDEX);
754 char_at_generator.GenerateFast(masm); 740 char_at_generator.GenerateFast(masm);
755 __ Ret(); 741 __ Ret();
756 742
757 StubRuntimeCallHelper call_helper; 743 StubRuntimeCallHelper call_helper;
758 char_at_generator.GenerateSlow(masm, call_helper); 744 char_at_generator.GenerateSlow(masm, call_helper);
759 745
760 __ bind(&miss); 746 __ bind(&miss);
761 GenerateMiss(masm); 747 GenerateMiss(masm);
762 } 748 }
763 749
764 750
765 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { 751 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
766 // Return address is on the stack. 752 // Return address is in lr.
767 Label slow; 753 Label slow;
768 754
769 Register receiver = ReceiverRegister(); 755 Register receiver = ReceiverRegister();
770 Register key = NameRegister(); 756 Register key = NameRegister();
771 Register scratch1 = r2; 757 Register scratch1 = r3;
772 Register scratch2 = r3; 758 Register scratch2 = r4;
773 ASSERT(!scratch1.is(receiver) && !scratch1.is(key)); 759 ASSERT(!scratch1.is(receiver) && !scratch1.is(key));
774 ASSERT(!scratch2.is(receiver) && !scratch2.is(key)); 760 ASSERT(!scratch2.is(receiver) && !scratch2.is(key));
775 761
776 // Check that the receiver isn't a smi. 762 // Check that the receiver isn't a smi.
777 __ JumpIfSmi(receiver, &slow); 763 __ JumpIfSmi(receiver, &slow);
778 764
779 // Check that the key is an array index, that is Uint32. 765 // Check that the key is an array index, that is Uint32.
780 __ NonNegativeSmiTst(key); 766 __ NonNegativeSmiTst(key);
781 __ b(ne, &slow); 767 __ b(ne, &slow);
782 768
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
1316 } else { 1302 } else {
1317 ASSERT(Assembler::GetCondition(branch_instr) == ne); 1303 ASSERT(Assembler::GetCondition(branch_instr) == ne);
1318 patcher.EmitCondition(eq); 1304 patcher.EmitCondition(eq);
1319 } 1305 }
1320 } 1306 }
1321 1307
1322 1308
1323 } } // namespace v8::internal 1309 } } // namespace v8::internal
1324 1310
1325 #endif // V8_TARGET_ARCH_ARM 1311 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/full-codegen-arm.cc ('k') | src/arm/lithium-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698