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

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

Issue 878263002: Add MEGAMORPHIC state support for KeyedLoadIC (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 10 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
« no previous file with comments | « src/ic/arm/ic-arm.cc ('k') | src/ic/ia32/ic-ia32.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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_ARM64 7 #if V8_TARGET_ARCH_ARM64
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/ic/ic.h" 10 #include "src/ic/ic.h"
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 scratch5)); 520 scratch5));
521 521
522 Isolate* isolate = masm->isolate(); 522 Isolate* isolate = masm->isolate();
523 Label probe_dictionary, property_array_property; 523 Label probe_dictionary, property_array_property;
524 // If we can load the value, it should be returned in x0. 524 // If we can load the value, it should be returned in x0.
525 Register result = x0; 525 Register result = x0;
526 526
527 GenerateKeyedLoadReceiverCheck(masm, receiver, scratch1, scratch2, 527 GenerateKeyedLoadReceiverCheck(masm, receiver, scratch1, scratch2,
528 Map::kHasNamedInterceptor, slow); 528 Map::kHasNamedInterceptor, slow);
529 529
530 // If the receiver is a fast-case object, check the keyed lookup cache. 530 // If the receiver is a fast-case object, check the stub cache. Otherwise
531 // Otherwise probe the dictionary. 531 // probe the dictionary.
532 __ Ldr(scratch2, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 532 __ Ldr(scratch2, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
533 __ Ldr(scratch3, FieldMemOperand(scratch2, HeapObject::kMapOffset)); 533 __ Ldr(scratch3, FieldMemOperand(scratch2, HeapObject::kMapOffset));
534 __ JumpIfRoot(scratch3, Heap::kHashTableMapRootIndex, &probe_dictionary); 534 __ JumpIfRoot(scratch3, Heap::kHashTableMapRootIndex, &probe_dictionary);
535 535
536 // We keep the map of the receiver in scratch1. 536 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
537 Register receiver_map = scratch1; 537 Code::ComputeHandlerFlags(Code::LOAD_IC));
538 538 masm->isolate()->stub_cache()->GenerateProbe(masm, Code::LOAD_IC, flags,
539 // Load the map of the receiver, compute the keyed lookup cache hash 539 false, receiver, key, scratch1,
540 // based on 32 bits of the map pointer and the name hash. 540 scratch2, scratch3, scratch4);
541 __ Ldr(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset)); 541 // Cache miss.
542 __ Mov(scratch2, Operand(receiver_map, ASR, KeyedLookupCache::kMapHashShift)); 542 KeyedLoadIC::GenerateMiss(masm);
543 __ Ldr(scratch3.W(), FieldMemOperand(key, Name::kHashFieldOffset));
544 __ Eor(scratch2, scratch2, Operand(scratch3, ASR, Name::kHashShift));
545 int mask = KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask;
546 __ And(scratch2, scratch2, mask);
547
548 // Load the key (consisting of map and unique name) from the cache and
549 // check for match.
550 Label load_in_object_property;
551 static const int kEntriesPerBucket = KeyedLookupCache::kEntriesPerBucket;
552 Label hit_on_nth_entry[kEntriesPerBucket];
553 ExternalReference cache_keys =
554 ExternalReference::keyed_lookup_cache_keys(isolate);
555
556 __ Mov(scratch3, cache_keys);
557 __ Add(scratch3, scratch3, Operand(scratch2, LSL, kPointerSizeLog2 + 1));
558
559 for (int i = 0; i < kEntriesPerBucket - 1; i++) {
560 Label try_next_entry;
561 // Load map and make scratch3 pointing to the next entry.
562 __ Ldr(scratch4, MemOperand(scratch3, kPointerSize * 2, PostIndex));
563 __ Cmp(receiver_map, scratch4);
564 __ B(ne, &try_next_entry);
565 __ Ldr(scratch4, MemOperand(scratch3, -kPointerSize)); // Load name
566 __ Cmp(key, scratch4);
567 __ B(eq, &hit_on_nth_entry[i]);
568 __ Bind(&try_next_entry);
569 }
570
571 // Last entry.
572 __ Ldr(scratch4, MemOperand(scratch3, kPointerSize, PostIndex));
573 __ Cmp(receiver_map, scratch4);
574 __ B(ne, slow);
575 __ Ldr(scratch4, MemOperand(scratch3));
576 __ Cmp(key, scratch4);
577 __ B(ne, slow);
578
579 // Get field offset.
580 ExternalReference cache_field_offsets =
581 ExternalReference::keyed_lookup_cache_field_offsets(isolate);
582
583 // Hit on nth entry.
584 for (int i = kEntriesPerBucket - 1; i >= 0; i--) {
585 __ Bind(&hit_on_nth_entry[i]);
586 __ Mov(scratch3, cache_field_offsets);
587 if (i != 0) {
588 __ Add(scratch2, scratch2, i);
589 }
590 __ Ldr(scratch4.W(), MemOperand(scratch3, scratch2, LSL, 2));
591 __ Ldrb(scratch5,
592 FieldMemOperand(receiver_map, Map::kInObjectPropertiesOffset));
593 __ Subs(scratch4, scratch4, scratch5);
594 __ B(ge, &property_array_property);
595 if (i != 0) {
596 __ B(&load_in_object_property);
597 }
598 }
599
600 // Load in-object property.
601 __ Bind(&load_in_object_property);
602 __ Ldrb(scratch5, FieldMemOperand(receiver_map, Map::kInstanceSizeOffset));
603 __ Add(scratch5, scratch5, scratch4); // Index from start of object.
604 __ Sub(receiver, receiver, kHeapObjectTag); // Remove the heap tag.
605 __ Ldr(result, MemOperand(receiver, scratch5, LSL, kPointerSizeLog2));
606 __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(), 1,
607 scratch1, scratch2);
608 __ Ret();
609
610 // Load property array property.
611 __ Bind(&property_array_property);
612 __ Ldr(scratch1, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
613 __ Add(scratch1, scratch1, FixedArray::kHeaderSize - kHeapObjectTag);
614 __ Ldr(result, MemOperand(scratch1, scratch4, LSL, kPointerSizeLog2));
615 __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(), 1,
616 scratch1, scratch2);
617 __ Ret();
618 543
619 // Do a quick inline probe of the receiver's dictionary, if it exists. 544 // Do a quick inline probe of the receiver's dictionary, if it exists.
620 __ Bind(&probe_dictionary); 545 __ Bind(&probe_dictionary);
621 __ Ldr(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset)); 546 __ Ldr(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset));
622 __ Ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); 547 __ Ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
623 GenerateGlobalInstanceTypeCheck(masm, scratch1, slow); 548 GenerateGlobalInstanceTypeCheck(masm, scratch1, slow);
624 // Load the property. 549 // Load the property.
625 GenerateDictionaryLoad(masm, slow, scratch2, key, result, scratch1, scratch3); 550 GenerateDictionaryLoad(masm, slow, scratch2, key, result, scratch1, scratch3);
626 __ IncrementCounter(isolate->counters()->keyed_load_generic_symbol(), 1, 551 __ IncrementCounter(isolate->counters()->keyed_load_generic_symbol(), 1,
627 scratch1, scratch2); 552 scratch1, scratch2);
628 __ Ret(); 553 __ Ret();
629 } 554 }
630 555
631 556
632 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 557 void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
633 // The return address is in lr. 558 // The return address is in lr.
634 Label slow, check_name, index_smi, index_name; 559 Label slow, check_name, index_smi, index_name;
635 560
636 Register key = LoadDescriptor::NameRegister(); 561 Register key = LoadDescriptor::NameRegister();
637 Register receiver = LoadDescriptor::ReceiverRegister(); 562 Register receiver = LoadDescriptor::ReceiverRegister();
638 DCHECK(key.is(x2)); 563 DCHECK(key.is(x2));
639 DCHECK(receiver.is(x1)); 564 DCHECK(receiver.is(x1));
640 565
641 __ JumpIfNotSmi(key, &check_name); 566 __ JumpIfNotSmi(key, &check_name);
642 __ Bind(&index_smi); 567 __ Bind(&index_smi);
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 } else { 980 } else {
1056 DCHECK(to_patch->Mask(TestBranchMask) == TBNZ); 981 DCHECK(to_patch->Mask(TestBranchMask) == TBNZ);
1057 // This is JumpIfSmi(smi_reg, branch_imm). 982 // This is JumpIfSmi(smi_reg, branch_imm).
1058 patcher.tbz(smi_reg, 0, branch_imm); 983 patcher.tbz(smi_reg, 0, branch_imm);
1059 } 984 }
1060 } 985 }
1061 } 986 }
1062 } // namespace v8::internal 987 } // namespace v8::internal
1063 988
1064 #endif // V8_TARGET_ARCH_ARM64 989 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/ic/arm/ic-arm.cc ('k') | src/ic/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698