OLD | NEW |
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 | 5 |
6 #include "src/v8.h" | 6 #include "src/v8.h" |
7 | 7 |
8 #if V8_TARGET_ARCH_MIPS | 8 #if V8_TARGET_ARCH_MIPS |
9 | 9 |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 | 468 |
469 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 469 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
470 // The return address is in ra. | 470 // The return address is in ra. |
471 | 471 |
472 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); | 472 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); |
473 | 473 |
474 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); | 474 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); |
475 } | 475 } |
476 | 476 |
477 | 477 |
478 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 478 void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) { |
479 // The return address is in ra. | 479 // The return address is in ra. |
480 Label slow, check_name, index_smi, index_name, property_array_property; | 480 Label slow, check_name, index_smi, index_name, property_array_property; |
481 Label probe_dictionary, check_number_dictionary; | 481 Label probe_dictionary, check_number_dictionary; |
482 | 482 |
483 Register key = LoadDescriptor::NameRegister(); | 483 Register key = LoadDescriptor::NameRegister(); |
484 Register receiver = LoadDescriptor::ReceiverRegister(); | 484 Register receiver = LoadDescriptor::ReceiverRegister(); |
485 DCHECK(key.is(a2)); | 485 DCHECK(key.is(a2)); |
486 DCHECK(receiver.is(a1)); | 486 DCHECK(receiver.is(a1)); |
487 | 487 |
488 Isolate* isolate = masm->isolate(); | 488 Isolate* isolate = masm->isolate(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
522 a3); | 522 a3); |
523 GenerateRuntimeGetProperty(masm); | 523 GenerateRuntimeGetProperty(masm); |
524 | 524 |
525 __ bind(&check_name); | 525 __ bind(&check_name); |
526 GenerateKeyNameCheck(masm, key, a0, a3, &index_name, &slow); | 526 GenerateKeyNameCheck(masm, key, a0, a3, &index_name, &slow); |
527 | 527 |
528 GenerateKeyedLoadReceiverCheck(masm, receiver, a0, a3, | 528 GenerateKeyedLoadReceiverCheck(masm, receiver, a0, a3, |
529 Map::kHasNamedInterceptor, &slow); | 529 Map::kHasNamedInterceptor, &slow); |
530 | 530 |
531 | 531 |
532 // If the receiver is a fast-case object, check the keyed lookup | 532 // If the receiver is a fast-case object, check the stub cache. Otherwise |
533 // cache. Otherwise probe the dictionary. | 533 // probe the dictionary. |
534 __ lw(a3, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 534 __ lw(a3, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
535 __ lw(t0, FieldMemOperand(a3, HeapObject::kMapOffset)); | 535 __ lw(t0, FieldMemOperand(a3, HeapObject::kMapOffset)); |
536 __ LoadRoot(at, Heap::kHashTableMapRootIndex); | 536 __ LoadRoot(at, Heap::kHashTableMapRootIndex); |
537 __ Branch(&probe_dictionary, eq, t0, Operand(at)); | 537 __ Branch(&probe_dictionary, eq, t0, Operand(at)); |
538 | 538 |
539 // Load the map of the receiver, compute the keyed lookup cache hash | 539 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
540 // based on 32 bits of the map pointer and the name hash. | 540 Code::ComputeHandlerFlags(Code::LOAD_IC)); |
541 __ lw(a0, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 541 masm->isolate()->stub_cache()->GenerateProbe( |
542 __ sra(a3, a0, KeyedLookupCache::kMapHashShift); | 542 masm, Code::LOAD_IC, flags, false, receiver, key, a3, t0, t1, t2); |
543 __ lw(t0, FieldMemOperand(key, Name::kHashFieldOffset)); | 543 // Cache miss. |
544 __ sra(at, t0, Name::kHashShift); | 544 GenerateMiss(masm); |
545 __ xor_(a3, a3, at); | |
546 int mask = KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask; | |
547 __ And(a3, a3, Operand(mask)); | |
548 | |
549 // Load the key (consisting of map and unique name) from the cache and | |
550 // check for match. | |
551 Label load_in_object_property; | |
552 static const int kEntriesPerBucket = KeyedLookupCache::kEntriesPerBucket; | |
553 Label hit_on_nth_entry[kEntriesPerBucket]; | |
554 ExternalReference cache_keys = | |
555 ExternalReference::keyed_lookup_cache_keys(isolate); | |
556 __ li(t0, Operand(cache_keys)); | |
557 __ sll(at, a3, kPointerSizeLog2 + 1); | |
558 __ addu(t0, t0, at); | |
559 | |
560 for (int i = 0; i < kEntriesPerBucket - 1; i++) { | |
561 Label try_next_entry; | |
562 __ lw(t1, MemOperand(t0, kPointerSize * i * 2)); | |
563 __ Branch(&try_next_entry, ne, a0, Operand(t1)); | |
564 __ lw(t1, MemOperand(t0, kPointerSize * (i * 2 + 1))); | |
565 __ Branch(&hit_on_nth_entry[i], eq, key, Operand(t1)); | |
566 __ bind(&try_next_entry); | |
567 } | |
568 | |
569 __ lw(t1, MemOperand(t0, kPointerSize * (kEntriesPerBucket - 1) * 2)); | |
570 __ Branch(&slow, ne, a0, Operand(t1)); | |
571 __ lw(t1, MemOperand(t0, kPointerSize * ((kEntriesPerBucket - 1) * 2 + 1))); | |
572 __ Branch(&slow, ne, key, Operand(t1)); | |
573 | |
574 // Get field offset. | |
575 // a0 : receiver's map | |
576 // a3 : lookup cache index | |
577 ExternalReference cache_field_offsets = | |
578 ExternalReference::keyed_lookup_cache_field_offsets(isolate); | |
579 | |
580 // Hit on nth entry. | |
581 for (int i = kEntriesPerBucket - 1; i >= 0; i--) { | |
582 __ bind(&hit_on_nth_entry[i]); | |
583 __ li(t0, Operand(cache_field_offsets)); | |
584 __ sll(at, a3, kPointerSizeLog2); | |
585 __ addu(at, t0, at); | |
586 __ lw(t1, MemOperand(at, kPointerSize * i)); | |
587 __ lbu(t2, FieldMemOperand(a0, Map::kInObjectPropertiesOffset)); | |
588 __ Subu(t1, t1, t2); | |
589 __ Branch(&property_array_property, ge, t1, Operand(zero_reg)); | |
590 if (i != 0) { | |
591 __ Branch(&load_in_object_property); | |
592 } | |
593 } | |
594 | |
595 // Load in-object property. | |
596 __ bind(&load_in_object_property); | |
597 __ lbu(t2, FieldMemOperand(a0, Map::kInstanceSizeOffset)); | |
598 __ addu(t2, t2, t1); // Index from start of object. | |
599 __ Subu(receiver, receiver, Operand(kHeapObjectTag)); // Remove the heap tag. | |
600 __ sll(at, t2, kPointerSizeLog2); | |
601 __ addu(at, receiver, at); | |
602 __ lw(v0, MemOperand(at)); | |
603 __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(), 1, | |
604 t0, a3); | |
605 __ Ret(); | |
606 | |
607 // Load property array property. | |
608 __ bind(&property_array_property); | |
609 __ lw(receiver, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | |
610 __ Addu(receiver, receiver, FixedArray::kHeaderSize - kHeapObjectTag); | |
611 __ sll(v0, t1, kPointerSizeLog2); | |
612 __ Addu(v0, v0, receiver); | |
613 __ lw(v0, MemOperand(v0)); | |
614 __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(), 1, | |
615 t0, a3); | |
616 __ Ret(); | |
617 | |
618 | 545 |
619 // Do a quick inline probe of the receiver's dictionary, if it | 546 // Do a quick inline probe of the receiver's dictionary, if it |
620 // exists. | 547 // exists. |
621 __ bind(&probe_dictionary); | 548 __ bind(&probe_dictionary); |
622 // a3: elements | 549 // a3: elements |
623 __ lw(a0, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 550 __ lw(a0, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
624 __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset)); | 551 __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset)); |
625 GenerateGlobalInstanceTypeCheck(masm, a0, &slow); | 552 GenerateGlobalInstanceTypeCheck(masm, a0, &slow); |
626 // Load the property to v0. | 553 // Load the property to v0. |
627 GenerateDictionaryLoad(masm, &slow, a3, key, v0, t1, t0); | 554 GenerateDictionaryLoad(masm, &slow, a3, key, v0, t1, t0); |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1046 patcher.ChangeBranchCondition(ne); | 973 patcher.ChangeBranchCondition(ne); |
1047 } else { | 974 } else { |
1048 DCHECK(Assembler::IsBne(branch_instr)); | 975 DCHECK(Assembler::IsBne(branch_instr)); |
1049 patcher.ChangeBranchCondition(eq); | 976 patcher.ChangeBranchCondition(eq); |
1050 } | 977 } |
1051 } | 978 } |
1052 } | 979 } |
1053 } // namespace v8::internal | 980 } // namespace v8::internal |
1054 | 981 |
1055 #endif // V8_TARGET_ARCH_MIPS | 982 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |