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

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

Issue 2732273003: Disentangle assembler from isolate. (Closed)
Patch Set: Address feedback. Created 3 years, 9 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/arm64/assembler-arm64.h ('k') | src/arm64/assembler-arm64-inl.h » ('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 // 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 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 DCHECK(IsWasmGlobalReference(rmode_)); 192 DCHECK(IsWasmGlobalReference(rmode_));
193 return Memory::Address_at(Assembler::target_pointer_address_at(pc_)); 193 return Memory::Address_at(Assembler::target_pointer_address_at(pc_));
194 } 194 }
195 195
196 uint32_t RelocInfo::wasm_function_table_size_reference() { 196 uint32_t RelocInfo::wasm_function_table_size_reference() {
197 DCHECK(IsWasmFunctionTableSizeReference(rmode_)); 197 DCHECK(IsWasmFunctionTableSizeReference(rmode_));
198 return Memory::uint32_at(Assembler::target_pointer_address_at(pc_)); 198 return Memory::uint32_at(Assembler::target_pointer_address_at(pc_));
199 } 199 }
200 200
201 void RelocInfo::unchecked_update_wasm_memory_reference( 201 void RelocInfo::unchecked_update_wasm_memory_reference(
202 Address address, ICacheFlushMode flush_mode) { 202 Isolate* isolate, Address address, ICacheFlushMode flush_mode) {
203 Assembler::set_target_address_at(isolate_, pc_, host_, address, flush_mode); 203 Assembler::set_target_address_at(isolate, pc_, host_, address, flush_mode);
204 } 204 }
205 205
206 void RelocInfo::unchecked_update_wasm_size(uint32_t size, 206 void RelocInfo::unchecked_update_wasm_size(Isolate* isolate, uint32_t size,
207 ICacheFlushMode flush_mode) { 207 ICacheFlushMode flush_mode) {
208 Memory::uint32_at(Assembler::target_pointer_address_at(pc_)) = size; 208 Memory::uint32_at(Assembler::target_pointer_address_at(pc_)) = size;
209 // No icache flushing needed, see comment in set_target_address_at. 209 // No icache flushing needed, see comment in set_target_address_at.
210 } 210 }
211 211
212 Register GetAllocatableRegisterThatIsNotOneOf(Register reg1, Register reg2, 212 Register GetAllocatableRegisterThatIsNotOneOf(Register reg1, Register reg2,
213 Register reg3, Register reg4) { 213 Register reg3, Register reg4) {
214 CPURegList regs(reg1, reg2, reg3, reg4); 214 CPURegList regs(reg1, reg2, reg3, reg4);
215 const RegisterConfiguration* config = RegisterConfiguration::Crankshaft(); 215 const RegisterConfiguration* config = RegisterConfiguration::Crankshaft();
216 for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { 216 for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 std::pair<SharedEntriesIterator, SharedEntriesIterator> range; 521 std::pair<SharedEntriesIterator, SharedEntriesIterator> range;
522 uint64_t data = value_it->first; 522 uint64_t data = value_it->first;
523 range = shared_entries_.equal_range(data); 523 range = shared_entries_.equal_range(data);
524 SharedEntriesIterator offset_it; 524 SharedEntriesIterator offset_it;
525 // Iterate through the offsets of a given key. 525 // Iterate through the offsets of a given key.
526 for (offset_it = range.first; offset_it != range.second; offset_it++) { 526 for (offset_it = range.first; offset_it != range.second; offset_it++) {
527 Instruction* instr = assm_->InstructionAt(offset_it->second); 527 Instruction* instr = assm_->InstructionAt(offset_it->second);
528 528
529 // Instruction to patch must be 'ldr rd, [pc, #offset]' with offset == 0. 529 // Instruction to patch must be 'ldr rd, [pc, #offset]' with offset == 0.
530 DCHECK(instr->IsLdrLiteral() && instr->ImmLLiteral() == 0); 530 DCHECK(instr->IsLdrLiteral() && instr->ImmLLiteral() == 0);
531 instr->SetImmPCOffsetTarget(assm_->isolate(), assm_->pc()); 531 instr->SetImmPCOffsetTarget(assm_->isolate_data(), assm_->pc());
532 } 532 }
533 assm_->dc64(data); 533 assm_->dc64(data);
534 } 534 }
535 shared_entries_.clear(); 535 shared_entries_.clear();
536 shared_entries_count = 0; 536 shared_entries_count = 0;
537 537
538 // Emit unique entries. 538 // Emit unique entries.
539 std::vector<std::pair<uint64_t, int> >::const_iterator unique_it; 539 std::vector<std::pair<uint64_t, int> >::const_iterator unique_it;
540 for (unique_it = unique_entries_.begin(); 540 for (unique_it = unique_entries_.begin();
541 unique_it != unique_entries_.end(); 541 unique_it != unique_entries_.end();
542 unique_it++) { 542 unique_it++) {
543 Instruction* instr = assm_->InstructionAt(unique_it->second); 543 Instruction* instr = assm_->InstructionAt(unique_it->second);
544 544
545 // Instruction to patch must be 'ldr rd, [pc, #offset]' with offset == 0. 545 // Instruction to patch must be 'ldr rd, [pc, #offset]' with offset == 0.
546 DCHECK(instr->IsLdrLiteral() && instr->ImmLLiteral() == 0); 546 DCHECK(instr->IsLdrLiteral() && instr->ImmLLiteral() == 0);
547 instr->SetImmPCOffsetTarget(assm_->isolate(), assm_->pc()); 547 instr->SetImmPCOffsetTarget(assm_->isolate_data(), assm_->pc());
548 assm_->dc64(unique_it->first); 548 assm_->dc64(unique_it->first);
549 } 549 }
550 unique_entries_.clear(); 550 unique_entries_.clear();
551 first_use_ = -1; 551 first_use_ = -1;
552 } 552 }
553 553
554 554
555 // Assembler 555 // Assembler
556 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) 556 Assembler::Assembler(IsolateData isolate_data, void* buffer, int buffer_size)
557 : AssemblerBase(isolate, buffer, buffer_size), 557 : AssemblerBase(isolate_data, buffer, buffer_size),
558 constpool_(this), 558 constpool_(this),
559 recorded_ast_id_(TypeFeedbackId::None()), 559 recorded_ast_id_(TypeFeedbackId::None()),
560 unresolved_branches_() { 560 unresolved_branches_() {
561 const_pool_blocked_nesting_ = 0; 561 const_pool_blocked_nesting_ = 0;
562 veneer_pool_blocked_nesting_ = 0; 562 veneer_pool_blocked_nesting_ = 0;
563 Reset(); 563 Reset();
564 } 564 }
565 565
566 566
567 Assembler::~Assembler() { 567 Assembler::~Assembler() {
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 // It is also the last instruction in the chain, so it is the only branch 668 // It is also the last instruction in the chain, so it is the only branch
669 // currently referring to this label. 669 // currently referring to this label.
670 label->Unuse(); 670 label->Unuse();
671 } else { 671 } else {
672 label->link_to( 672 label->link_to(
673 static_cast<int>(reinterpret_cast<byte*>(next_link) - buffer_)); 673 static_cast<int>(reinterpret_cast<byte*>(next_link) - buffer_));
674 } 674 }
675 675
676 } else if (branch == next_link) { 676 } else if (branch == next_link) {
677 // The branch is the last (but not also the first) instruction in the chain. 677 // The branch is the last (but not also the first) instruction in the chain.
678 prev_link->SetImmPCOffsetTarget(isolate(), prev_link); 678 prev_link->SetImmPCOffsetTarget(isolate_data(), prev_link);
679 679
680 } else { 680 } else {
681 // The branch is in the middle of the chain. 681 // The branch is in the middle of the chain.
682 if (prev_link->IsTargetInImmPCOffsetRange(next_link)) { 682 if (prev_link->IsTargetInImmPCOffsetRange(next_link)) {
683 prev_link->SetImmPCOffsetTarget(isolate(), next_link); 683 prev_link->SetImmPCOffsetTarget(isolate_data(), next_link);
684 } else if (label_veneer != NULL) { 684 } else if (label_veneer != NULL) {
685 // Use the veneer for all previous links in the chain. 685 // Use the veneer for all previous links in the chain.
686 prev_link->SetImmPCOffsetTarget(isolate(), prev_link); 686 prev_link->SetImmPCOffsetTarget(isolate_data(), prev_link);
687 687
688 end_of_chain = false; 688 end_of_chain = false;
689 link = next_link; 689 link = next_link;
690 while (!end_of_chain) { 690 while (!end_of_chain) {
691 next_link = link->ImmPCOffsetTarget(); 691 next_link = link->ImmPCOffsetTarget();
692 end_of_chain = (link == next_link); 692 end_of_chain = (link == next_link);
693 link->SetImmPCOffsetTarget(isolate(), label_veneer); 693 link->SetImmPCOffsetTarget(isolate_data(), label_veneer);
694 link = next_link; 694 link = next_link;
695 } 695 }
696 } else { 696 } else {
697 // The assert below will fire. 697 // The assert below will fire.
698 // Some other work could be attempted to fix up the chain, but it would be 698 // Some other work could be attempted to fix up the chain, but it would be
699 // rather complicated. If we crash here, we may want to consider using an 699 // rather complicated. If we crash here, we may want to consider using an
700 // other mechanism than a chain of branches. 700 // other mechanism than a chain of branches.
701 // 701 //
702 // Note that this situation currently should not happen, as we always call 702 // Note that this situation currently should not happen, as we always call
703 // this function with a veneer to the target label. 703 // this function with a veneer to the target label.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 DCHECK(linkoffset < pc_offset()); 754 DCHECK(linkoffset < pc_offset());
755 DCHECK((linkoffset > prevlinkoffset) || 755 DCHECK((linkoffset > prevlinkoffset) ||
756 (linkoffset - prevlinkoffset == kStartOfLabelLinkChain)); 756 (linkoffset - prevlinkoffset == kStartOfLabelLinkChain));
757 DCHECK(prevlinkoffset >= 0); 757 DCHECK(prevlinkoffset >= 0);
758 758
759 // Update the link to point to the label. 759 // Update the link to point to the label.
760 if (link->IsUnresolvedInternalReference()) { 760 if (link->IsUnresolvedInternalReference()) {
761 // Internal references do not get patched to an instruction but directly 761 // Internal references do not get patched to an instruction but directly
762 // to an address. 762 // to an address.
763 internal_reference_positions_.push_back(linkoffset); 763 internal_reference_positions_.push_back(linkoffset);
764 PatchingAssembler patcher(isolate(), link, 2); 764 PatchingAssembler patcher(isolate_data(), reinterpret_cast<byte*>(link),
765 2);
765 patcher.dc64(reinterpret_cast<uintptr_t>(pc_)); 766 patcher.dc64(reinterpret_cast<uintptr_t>(pc_));
766 } else { 767 } else {
767 link->SetImmPCOffsetTarget(isolate(), 768 link->SetImmPCOffsetTarget(isolate_data(),
768 reinterpret_cast<Instruction*>(pc_)); 769 reinterpret_cast<Instruction*>(pc_));
769 } 770 }
770 771
771 // Link the label to the previous link in the chain. 772 // Link the label to the previous link in the chain.
772 if (linkoffset - prevlinkoffset == kStartOfLabelLinkChain) { 773 if (linkoffset - prevlinkoffset == kStartOfLabelLinkChain) {
773 // We hit kStartOfLabelLinkChain, so the chain is fully processed. 774 // We hit kStartOfLabelLinkChain, so the chain is fully processed.
774 label->Unuse(); 775 label->Unuse();
775 } else { 776 } else {
776 // Update the label for the next iteration. 777 // Update the label for the next iteration.
777 label->link_to(prevlinkoffset); 778 label->link_to(prevlinkoffset);
(...skipping 2163 matching lines...) Expand 10 before | Expand all | Expand 10 after
2941 intptr_t* p = reinterpret_cast<intptr_t*>(buffer_ + pos); 2942 intptr_t* p = reinterpret_cast<intptr_t*>(buffer_ + pos);
2942 *p += pc_delta; 2943 *p += pc_delta;
2943 } 2944 }
2944 2945
2945 // Pending relocation entries are also relative, no need to relocate. 2946 // Pending relocation entries are also relative, no need to relocate.
2946 } 2947 }
2947 2948
2948 2949
2949 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 2950 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2950 // We do not try to reuse pool constants. 2951 // We do not try to reuse pool constants.
2951 RelocInfo rinfo(isolate(), reinterpret_cast<byte*>(pc_), rmode, data, NULL); 2952 RelocInfo rinfo(reinterpret_cast<byte*>(pc_), rmode, data, NULL);
2952 if (((rmode >= RelocInfo::COMMENT) && 2953 if (((rmode >= RelocInfo::COMMENT) &&
2953 (rmode <= RelocInfo::DEBUG_BREAK_SLOT_AT_TAIL_CALL)) || 2954 (rmode <= RelocInfo::DEBUG_BREAK_SLOT_AT_TAIL_CALL)) ||
2954 (rmode == RelocInfo::INTERNAL_REFERENCE) || 2955 (rmode == RelocInfo::INTERNAL_REFERENCE) ||
2955 (rmode == RelocInfo::CONST_POOL) || (rmode == RelocInfo::VENEER_POOL) || 2956 (rmode == RelocInfo::CONST_POOL) || (rmode == RelocInfo::VENEER_POOL) ||
2956 (rmode == RelocInfo::DEOPT_SCRIPT_OFFSET) || 2957 (rmode == RelocInfo::DEOPT_SCRIPT_OFFSET) ||
2957 (rmode == RelocInfo::DEOPT_INLINING_ID) || 2958 (rmode == RelocInfo::DEOPT_INLINING_ID) ||
2958 (rmode == RelocInfo::DEOPT_REASON) || (rmode == RelocInfo::DEOPT_ID)) { 2959 (rmode == RelocInfo::DEOPT_REASON) || (rmode == RelocInfo::DEOPT_ID)) {
2959 // Adjust code for new modes. 2960 // Adjust code for new modes.
2960 DCHECK(RelocInfo::IsDebugBreakSlot(rmode) || RelocInfo::IsComment(rmode) || 2961 DCHECK(RelocInfo::IsDebugBreakSlot(rmode) || RelocInfo::IsComment(rmode) ||
2961 RelocInfo::IsDeoptReason(rmode) || RelocInfo::IsDeoptId(rmode) || 2962 RelocInfo::IsDeoptReason(rmode) || RelocInfo::IsDeoptId(rmode) ||
2962 RelocInfo::IsDeoptPosition(rmode) || 2963 RelocInfo::IsDeoptPosition(rmode) ||
2963 RelocInfo::IsInternalReference(rmode) || 2964 RelocInfo::IsInternalReference(rmode) ||
2964 RelocInfo::IsConstPool(rmode) || RelocInfo::IsVeneerPool(rmode)); 2965 RelocInfo::IsConstPool(rmode) || RelocInfo::IsVeneerPool(rmode));
2965 // These modes do not need an entry in the constant pool. 2966 // These modes do not need an entry in the constant pool.
2966 } else { 2967 } else {
2967 constpool_.RecordEntry(data, rmode); 2968 constpool_.RecordEntry(data, rmode);
2968 // Make sure the constant pool is not emitted in place of the next 2969 // Make sure the constant pool is not emitted in place of the next
2969 // instruction for which we just recorded relocation info. 2970 // instruction for which we just recorded relocation info.
2970 BlockConstPoolFor(1); 2971 BlockConstPoolFor(1);
2971 } 2972 }
2972 2973
2973 if (!RelocInfo::IsNone(rmode)) { 2974 if (!RelocInfo::IsNone(rmode)) {
2974 // Don't record external references unless the heap will be serialized. 2975 // Don't record external references unless the heap will be serialized.
2975 if (rmode == RelocInfo::EXTERNAL_REFERENCE && 2976 if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
2976 !serializer_enabled() && !emit_debug_code()) { 2977 !serializer_enabled() && !emit_debug_code()) {
2977 return; 2978 return;
2978 } 2979 }
2979 DCHECK(buffer_space() >= kMaxRelocSize); // too late to grow buffer here 2980 DCHECK(buffer_space() >= kMaxRelocSize); // too late to grow buffer here
2980 if (rmode == RelocInfo::CODE_TARGET_WITH_ID) { 2981 if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
2981 RelocInfo reloc_info_with_ast_id(isolate(), reinterpret_cast<byte*>(pc_), 2982 RelocInfo reloc_info_with_ast_id(reinterpret_cast<byte*>(pc_), rmode,
2982 rmode, RecordedAstId().ToInt(), NULL); 2983 RecordedAstId().ToInt(), NULL);
2983 ClearRecordedAstId(); 2984 ClearRecordedAstId();
2984 reloc_info_writer.Write(&reloc_info_with_ast_id); 2985 reloc_info_writer.Write(&reloc_info_with_ast_id);
2985 } else { 2986 } else {
2986 reloc_info_writer.Write(&rinfo); 2987 reloc_info_writer.Write(&rinfo);
2987 } 2988 }
2988 } 2989 }
2989 } 2990 }
2990 2991
2991 2992
2992 void Assembler::BlockConstPoolFor(int instructions) { 2993 void Assembler::BlockConstPoolFor(int instructions) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
3061 3062
3062 bool Assembler::ShouldEmitVeneer(int max_reachable_pc, int margin) { 3063 bool Assembler::ShouldEmitVeneer(int max_reachable_pc, int margin) {
3063 // Account for the branch around the veneers and the guard. 3064 // Account for the branch around the veneers and the guard.
3064 int protection_offset = 2 * kInstructionSize; 3065 int protection_offset = 2 * kInstructionSize;
3065 return pc_offset() > max_reachable_pc - margin - protection_offset - 3066 return pc_offset() > max_reachable_pc - margin - protection_offset -
3066 static_cast<int>(unresolved_branches_.size() * kMaxVeneerCodeSize); 3067 static_cast<int>(unresolved_branches_.size() * kMaxVeneerCodeSize);
3067 } 3068 }
3068 3069
3069 3070
3070 void Assembler::RecordVeneerPool(int location_offset, int size) { 3071 void Assembler::RecordVeneerPool(int location_offset, int size) {
3071 RelocInfo rinfo(isolate(), buffer_ + location_offset, RelocInfo::VENEER_POOL, 3072 RelocInfo rinfo(buffer_ + location_offset, RelocInfo::VENEER_POOL,
3072 static_cast<intptr_t>(size), NULL); 3073 static_cast<intptr_t>(size), NULL);
3073 reloc_info_writer.Write(&rinfo); 3074 reloc_info_writer.Write(&rinfo);
3074 } 3075 }
3075 3076
3076 3077
3077 void Assembler::EmitVeneers(bool force_emit, bool need_protection, int margin) { 3078 void Assembler::EmitVeneers(bool force_emit, bool need_protection, int margin) {
3078 BlockPoolsScope scope(this); 3079 BlockPoolsScope scope(this);
3079 RecordComment("[ Veneers"); 3080 RecordComment("[ Veneers");
3080 3081
3081 // The exact size of the veneer pool must be recorded (see the comment at the 3082 // The exact size of the veneer pool must be recorded (see the comment at the
(...skipping 22 matching lines...) Expand all
3104 Instruction* branch = InstructionAt(it->second.pc_offset_); 3105 Instruction* branch = InstructionAt(it->second.pc_offset_);
3105 Label* label = it->second.label_; 3106 Label* label = it->second.label_;
3106 3107
3107 #ifdef DEBUG 3108 #ifdef DEBUG
3108 bind(&veneer_size_check); 3109 bind(&veneer_size_check);
3109 #endif 3110 #endif
3110 // Patch the branch to point to the current position, and emit a branch 3111 // Patch the branch to point to the current position, and emit a branch
3111 // to the label. 3112 // to the label.
3112 Instruction* veneer = reinterpret_cast<Instruction*>(pc_); 3113 Instruction* veneer = reinterpret_cast<Instruction*>(pc_);
3113 RemoveBranchFromLabelLinkChain(branch, label, veneer); 3114 RemoveBranchFromLabelLinkChain(branch, label, veneer);
3114 branch->SetImmPCOffsetTarget(isolate(), veneer); 3115 branch->SetImmPCOffsetTarget(isolate_data(), veneer);
3115 b(label); 3116 b(label);
3116 #ifdef DEBUG 3117 #ifdef DEBUG
3117 DCHECK(SizeOfCodeGeneratedSince(&veneer_size_check) <= 3118 DCHECK(SizeOfCodeGeneratedSince(&veneer_size_check) <=
3118 static_cast<uint64_t>(kMaxVeneerCodeSize)); 3119 static_cast<uint64_t>(kMaxVeneerCodeSize));
3119 veneer_size_check.Unuse(); 3120 veneer_size_check.Unuse();
3120 #endif 3121 #endif
3121 3122
3122 it_to_delete = it++; 3123 it_to_delete = it++;
3123 unresolved_branches_.erase(it_to_delete); 3124 unresolved_branches_.erase(it_to_delete);
3124 } else { 3125 } else {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
3217 movk(scratch, (target_offset >> 32) & 0xFFFF, 32); 3218 movk(scratch, (target_offset >> 32) & 0xFFFF, 32);
3218 DCHECK((target_offset >> 48) == 0); 3219 DCHECK((target_offset >> 48) == 0);
3219 add(rd, rd, scratch); 3220 add(rd, rd, scratch);
3220 } 3221 }
3221 3222
3222 3223
3223 } // namespace internal 3224 } // namespace internal
3224 } // namespace v8 3225 } // namespace v8
3225 3226
3226 #endif // V8_TARGET_ARCH_ARM64 3227 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm64/assembler-arm64.h ('k') | src/arm64/assembler-arm64-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698