OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 | 557 |
558 | 558 |
559 #undef __ | 559 #undef __ |
560 | 560 |
561 //----------------------------------------------------------------------------- | 561 //----------------------------------------------------------------------------- |
562 // StubCompiler static helper functions | 562 // StubCompiler static helper functions |
563 | 563 |
564 #define __ ACCESS_MASM(masm) | 564 #define __ ACCESS_MASM(masm) |
565 | 565 |
566 | 566 |
| 567 static void ProbeTable(MacroAssembler* masm, |
| 568 Code::Flags flags, |
| 569 StubCache::Table table, |
| 570 Register name, |
| 571 Register offset) { |
| 572 ExternalReference key_offset(SCTableReference::keyReference(table)); |
| 573 Label miss; |
| 574 |
| 575 __ movq(kScratchRegister, key_offset); |
| 576 // Check that the key in the entry matches the name. |
| 577 __ cmpl(name, Operand(kScratchRegister, offset, times_4, 0)); |
| 578 __ j(not_equal, &miss); |
| 579 // Get the code entry from the cache. |
| 580 // Use key_offset + kPointerSize, rather than loading value_offset. |
| 581 __ movq(kScratchRegister, |
| 582 Operand(kScratchRegister, offset, times_4, kPointerSize)); |
| 583 // Check that the flags match what we're looking for. |
| 584 __ movl(offset, FieldOperand(kScratchRegister, Code::kFlagsOffset)); |
| 585 __ and_(offset, Immediate(~Code::kFlagsNotUsedInLookup)); |
| 586 __ cmpl(offset, Immediate(flags)); |
| 587 __ j(not_equal, &miss); |
| 588 |
| 589 // Jump to the first instruction in the code stub. |
| 590 __ addq(kScratchRegister, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 591 __ jmp(kScratchRegister); |
| 592 |
| 593 __ bind(&miss); |
| 594 } |
| 595 |
| 596 |
567 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { | 597 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { |
568 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); | 598 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); |
569 Code* code = NULL; | 599 Code* code = NULL; |
570 if (kind == Code::LOAD_IC) { | 600 if (kind == Code::LOAD_IC) { |
571 code = Builtins::builtin(Builtins::LoadIC_Miss); | 601 code = Builtins::builtin(Builtins::LoadIC_Miss); |
572 } else { | 602 } else { |
573 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss); | 603 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss); |
574 } | 604 } |
575 | 605 |
576 Handle<Code> ic(code); | 606 Handle<Code> ic(code); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 } | 648 } |
619 | 649 |
620 | 650 |
621 void StubCache::GenerateProbe(MacroAssembler* masm, | 651 void StubCache::GenerateProbe(MacroAssembler* masm, |
622 Code::Flags flags, | 652 Code::Flags flags, |
623 Register receiver, | 653 Register receiver, |
624 Register name, | 654 Register name, |
625 Register scratch, | 655 Register scratch, |
626 Register extra) { | 656 Register extra) { |
627 Label miss; | 657 Label miss; |
628 // TODO(X64): Probe the primary and secondary StubCache tables. | 658 USE(extra); // The register extra is not used on the X64 platform. |
| 659 // Make sure that code is valid. The shifting code relies on the |
| 660 // entry size being 16. |
| 661 ASSERT(sizeof(Entry) == 16); |
| 662 |
| 663 // Make sure the flags do not name a specific type. |
| 664 ASSERT(Code::ExtractTypeFromFlags(flags) == 0); |
| 665 |
| 666 // Make sure that there are no register conflicts. |
| 667 ASSERT(!scratch.is(receiver)); |
| 668 ASSERT(!scratch.is(name)); |
| 669 |
| 670 // Check that the receiver isn't a smi. |
| 671 __ testl(receiver, Immediate(kSmiTagMask)); |
| 672 __ j(zero, &miss); |
| 673 |
| 674 // Get the map of the receiver and compute the hash. |
| 675 __ movl(scratch, FieldOperand(name, String::kLengthOffset)); |
| 676 // Use only the low 32 bits of the map pointer. |
| 677 __ addl(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 678 __ xor_(scratch, Immediate(flags)); |
| 679 __ and_(scratch, Immediate((kPrimaryTableSize - 1) << kHeapObjectTagSize)); |
| 680 |
| 681 // Probe the primary table. |
| 682 ProbeTable(masm, flags, kPrimary, name, scratch); |
| 683 |
| 684 // Primary miss: Compute hash for secondary probe. |
| 685 __ movl(scratch, FieldOperand(name, String::kLengthOffset)); |
| 686 __ addl(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 687 __ xor_(scratch, Immediate(flags)); |
| 688 __ and_(scratch, Immediate((kPrimaryTableSize - 1) << kHeapObjectTagSize)); |
| 689 __ subl(scratch, name); |
| 690 __ addl(scratch, Immediate(flags)); |
| 691 __ and_(scratch, Immediate((kSecondaryTableSize - 1) << kHeapObjectTagSize)); |
| 692 |
| 693 // Probe the secondary table. |
| 694 ProbeTable(masm, flags, kSecondary, name, scratch); |
629 | 695 |
630 // Cache miss: Fall-through and let caller handle the miss by | 696 // Cache miss: Fall-through and let caller handle the miss by |
631 // entering the runtime system. | 697 // entering the runtime system. |
632 __ bind(&miss); | 698 __ bind(&miss); |
633 } | 699 } |
634 | 700 |
635 | 701 |
636 #undef __ | 702 #undef __ |
637 | 703 |
638 | 704 |
639 } } // namespace v8::internal | 705 } } // namespace v8::internal |
OLD | NEW |