OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // | 2 // |
3 // Redistribution and use in source and binary forms, with or without | 3 // Redistribution and use in source and binary forms, with or without |
4 // modification, are permitted provided that the following conditions are | 4 // modification, are permitted provided that the following conditions are |
5 // met: | 5 // met: |
6 // | 6 // |
7 // * Redistributions of source code must retain the above copyright | 7 // * Redistributions of source code must retain the above copyright |
8 // notice, this list of conditions and the following disclaimer. | 8 // notice, this list of conditions and the following disclaimer. |
9 // * Redistributions in binary form must reproduce the above | 9 // * Redistributions in binary form must reproduce the above |
10 // copyright notice, this list of conditions and the following | 10 // copyright notice, this list of conditions and the following |
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 std::pair<SharedEntriesIterator, SharedEntriesIterator> range; | 504 std::pair<SharedEntriesIterator, SharedEntriesIterator> range; |
505 uint64_t data = value_it->first; | 505 uint64_t data = value_it->first; |
506 range = shared_entries_.equal_range(data); | 506 range = shared_entries_.equal_range(data); |
507 SharedEntriesIterator offset_it; | 507 SharedEntriesIterator offset_it; |
508 // Iterate through the offsets of a given key. | 508 // Iterate through the offsets of a given key. |
509 for (offset_it = range.first; offset_it != range.second; offset_it++) { | 509 for (offset_it = range.first; offset_it != range.second; offset_it++) { |
510 Instruction* instr = assm_->InstructionAt(offset_it->second); | 510 Instruction* instr = assm_->InstructionAt(offset_it->second); |
511 | 511 |
512 // Instruction to patch must be 'ldr rd, [pc, #offset]' with offset == 0. | 512 // Instruction to patch must be 'ldr rd, [pc, #offset]' with offset == 0. |
513 DCHECK(instr->IsLdrLiteral() && instr->ImmLLiteral() == 0); | 513 DCHECK(instr->IsLdrLiteral() && instr->ImmLLiteral() == 0); |
514 instr->SetImmPCOffsetTarget(assm_->pc()); | 514 instr->SetImmPCOffsetTarget(assm_->isolate(), assm_->pc()); |
515 } | 515 } |
516 assm_->dc64(data); | 516 assm_->dc64(data); |
517 } | 517 } |
518 shared_entries_.clear(); | 518 shared_entries_.clear(); |
519 shared_entries_count = 0; | 519 shared_entries_count = 0; |
520 | 520 |
521 // Emit unique entries. | 521 // Emit unique entries. |
522 std::vector<std::pair<uint64_t, int> >::const_iterator unique_it; | 522 std::vector<std::pair<uint64_t, int> >::const_iterator unique_it; |
523 for (unique_it = unique_entries_.begin(); | 523 for (unique_it = unique_entries_.begin(); |
524 unique_it != unique_entries_.end(); | 524 unique_it != unique_entries_.end(); |
525 unique_it++) { | 525 unique_it++) { |
526 Instruction* instr = assm_->InstructionAt(unique_it->second); | 526 Instruction* instr = assm_->InstructionAt(unique_it->second); |
527 | 527 |
528 // Instruction to patch must be 'ldr rd, [pc, #offset]' with offset == 0. | 528 // Instruction to patch must be 'ldr rd, [pc, #offset]' with offset == 0. |
529 DCHECK(instr->IsLdrLiteral() && instr->ImmLLiteral() == 0); | 529 DCHECK(instr->IsLdrLiteral() && instr->ImmLLiteral() == 0); |
530 instr->SetImmPCOffsetTarget(assm_->pc()); | 530 instr->SetImmPCOffsetTarget(assm_->isolate(), assm_->pc()); |
531 assm_->dc64(unique_it->first); | 531 assm_->dc64(unique_it->first); |
532 } | 532 } |
533 unique_entries_.clear(); | 533 unique_entries_.clear(); |
534 first_use_ = -1; | 534 first_use_ = -1; |
535 } | 535 } |
536 | 536 |
537 | 537 |
538 // Assembler | 538 // Assembler |
539 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) | 539 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) |
540 : AssemblerBase(isolate, buffer, buffer_size), | 540 : AssemblerBase(isolate, buffer, buffer_size), |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
651 // It is also the last instruction in the chain, so it is the only branch | 651 // It is also the last instruction in the chain, so it is the only branch |
652 // currently referring to this label. | 652 // currently referring to this label. |
653 label->Unuse(); | 653 label->Unuse(); |
654 } else { | 654 } else { |
655 label->link_to( | 655 label->link_to( |
656 static_cast<int>(reinterpret_cast<byte*>(next_link) - buffer_)); | 656 static_cast<int>(reinterpret_cast<byte*>(next_link) - buffer_)); |
657 } | 657 } |
658 | 658 |
659 } else if (branch == next_link) { | 659 } else if (branch == next_link) { |
660 // The branch is the last (but not also the first) instruction in the chain. | 660 // The branch is the last (but not also the first) instruction in the chain. |
661 prev_link->SetImmPCOffsetTarget(prev_link); | 661 prev_link->SetImmPCOffsetTarget(isolate(), prev_link); |
662 | 662 |
663 } else { | 663 } else { |
664 // The branch is in the middle of the chain. | 664 // The branch is in the middle of the chain. |
665 if (prev_link->IsTargetInImmPCOffsetRange(next_link)) { | 665 if (prev_link->IsTargetInImmPCOffsetRange(next_link)) { |
666 prev_link->SetImmPCOffsetTarget(next_link); | 666 prev_link->SetImmPCOffsetTarget(isolate(), next_link); |
667 } else if (label_veneer != NULL) { | 667 } else if (label_veneer != NULL) { |
668 // Use the veneer for all previous links in the chain. | 668 // Use the veneer for all previous links in the chain. |
669 prev_link->SetImmPCOffsetTarget(prev_link); | 669 prev_link->SetImmPCOffsetTarget(isolate(), prev_link); |
670 | 670 |
671 end_of_chain = false; | 671 end_of_chain = false; |
672 link = next_link; | 672 link = next_link; |
673 while (!end_of_chain) { | 673 while (!end_of_chain) { |
674 next_link = link->ImmPCOffsetTarget(); | 674 next_link = link->ImmPCOffsetTarget(); |
675 end_of_chain = (link == next_link); | 675 end_of_chain = (link == next_link); |
676 link->SetImmPCOffsetTarget(label_veneer); | 676 link->SetImmPCOffsetTarget(isolate(), label_veneer); |
677 link = next_link; | 677 link = next_link; |
678 } | 678 } |
679 } else { | 679 } else { |
680 // The assert below will fire. | 680 // The assert below will fire. |
681 // Some other work could be attempted to fix up the chain, but it would be | 681 // Some other work could be attempted to fix up the chain, but it would be |
682 // rather complicated. If we crash here, we may want to consider using an | 682 // rather complicated. If we crash here, we may want to consider using an |
683 // other mechanism than a chain of branches. | 683 // other mechanism than a chain of branches. |
684 // | 684 // |
685 // Note that this situation currently should not happen, as we always call | 685 // Note that this situation currently should not happen, as we always call |
686 // this function with a veneer to the target label. | 686 // this function with a veneer to the target label. |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
737 DCHECK(linkoffset < pc_offset()); | 737 DCHECK(linkoffset < pc_offset()); |
738 DCHECK((linkoffset > prevlinkoffset) || | 738 DCHECK((linkoffset > prevlinkoffset) || |
739 (linkoffset - prevlinkoffset == kStartOfLabelLinkChain)); | 739 (linkoffset - prevlinkoffset == kStartOfLabelLinkChain)); |
740 DCHECK(prevlinkoffset >= 0); | 740 DCHECK(prevlinkoffset >= 0); |
741 | 741 |
742 // Update the link to point to the label. | 742 // Update the link to point to the label. |
743 if (link->IsUnresolvedInternalReference()) { | 743 if (link->IsUnresolvedInternalReference()) { |
744 // Internal references do not get patched to an instruction but directly | 744 // Internal references do not get patched to an instruction but directly |
745 // to an address. | 745 // to an address. |
746 internal_reference_positions_.push_back(linkoffset); | 746 internal_reference_positions_.push_back(linkoffset); |
747 PatchingAssembler patcher(link, 2); | 747 PatchingAssembler patcher(isolate(), link, 2); |
748 patcher.dc64(reinterpret_cast<uintptr_t>(pc_)); | 748 patcher.dc64(reinterpret_cast<uintptr_t>(pc_)); |
749 } else { | 749 } else { |
750 link->SetImmPCOffsetTarget(reinterpret_cast<Instruction*>(pc_)); | 750 link->SetImmPCOffsetTarget(isolate(), |
| 751 reinterpret_cast<Instruction*>(pc_)); |
751 } | 752 } |
752 | 753 |
753 // Link the label to the previous link in the chain. | 754 // Link the label to the previous link in the chain. |
754 if (linkoffset - prevlinkoffset == kStartOfLabelLinkChain) { | 755 if (linkoffset - prevlinkoffset == kStartOfLabelLinkChain) { |
755 // We hit kStartOfLabelLinkChain, so the chain is fully processed. | 756 // We hit kStartOfLabelLinkChain, so the chain is fully processed. |
756 label->Unuse(); | 757 label->Unuse(); |
757 } else { | 758 } else { |
758 // Update the label for the next iteration. | 759 // Update the label for the next iteration. |
759 label->link_to(prevlinkoffset); | 760 label->link_to(prevlinkoffset); |
760 } | 761 } |
(...skipping 2262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3023 Instruction* branch = InstructionAt(it->second.pc_offset_); | 3024 Instruction* branch = InstructionAt(it->second.pc_offset_); |
3024 Label* label = it->second.label_; | 3025 Label* label = it->second.label_; |
3025 | 3026 |
3026 #ifdef DEBUG | 3027 #ifdef DEBUG |
3027 bind(&veneer_size_check); | 3028 bind(&veneer_size_check); |
3028 #endif | 3029 #endif |
3029 // Patch the branch to point to the current position, and emit a branch | 3030 // Patch the branch to point to the current position, and emit a branch |
3030 // to the label. | 3031 // to the label. |
3031 Instruction* veneer = reinterpret_cast<Instruction*>(pc_); | 3032 Instruction* veneer = reinterpret_cast<Instruction*>(pc_); |
3032 RemoveBranchFromLabelLinkChain(branch, label, veneer); | 3033 RemoveBranchFromLabelLinkChain(branch, label, veneer); |
3033 branch->SetImmPCOffsetTarget(veneer); | 3034 branch->SetImmPCOffsetTarget(isolate(), veneer); |
3034 b(label); | 3035 b(label); |
3035 #ifdef DEBUG | 3036 #ifdef DEBUG |
3036 DCHECK(SizeOfCodeGeneratedSince(&veneer_size_check) <= | 3037 DCHECK(SizeOfCodeGeneratedSince(&veneer_size_check) <= |
3037 static_cast<uint64_t>(kMaxVeneerCodeSize)); | 3038 static_cast<uint64_t>(kMaxVeneerCodeSize)); |
3038 veneer_size_check.Unuse(); | 3039 veneer_size_check.Unuse(); |
3039 #endif | 3040 #endif |
3040 | 3041 |
3041 it_to_delete = it++; | 3042 it_to_delete = it++; |
3042 unresolved_branches_.erase(it_to_delete); | 3043 unresolved_branches_.erase(it_to_delete); |
3043 } else { | 3044 } else { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3136 movk(scratch, (target_offset >> 32) & 0xFFFF, 32); | 3137 movk(scratch, (target_offset >> 32) & 0xFFFF, 32); |
3137 DCHECK((target_offset >> 48) == 0); | 3138 DCHECK((target_offset >> 48) == 0); |
3138 add(rd, rd, scratch); | 3139 add(rd, rd, scratch); |
3139 } | 3140 } |
3140 | 3141 |
3141 | 3142 |
3142 } // namespace internal | 3143 } // namespace internal |
3143 } // namespace v8 | 3144 } // namespace v8 |
3144 | 3145 |
3145 #endif // V8_TARGET_ARCH_ARM64 | 3146 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |