| 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 |