# HG changeset patch # User goetz # Date 1474562027 -7200 # Node ID 8423d5775d77e7d9225c6154e5eb9a7bfd79c24f # Parent ebbfdf26a4eefaae6bb5000315459411f95d80f8 8166562: C2: Suppress relocations in scratch emit. diff --git a/src/cpu/ppc/vm/ppc.ad b/src/cpu/ppc/vm/ppc.ad --- a/src/cpu/ppc/vm/ppc.ad +++ b/src/cpu/ppc/vm/ppc.ad @@ -1097,21 +1097,19 @@ // No entry point given, use the current pc. if (entry_point == NULL) entry_point = __ pc(); - if (!Compile::current()->in_scratch_emit_size()) { - // Put the entry point as a constant into the constant pool. - const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); - if (entry_point_toc_addr == NULL) { - ciEnv::current()->record_out_of_memory_failure(); - return offsets; - } - const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); - - // Emit the trampoline stub which will be related to the branch-and-link below. - CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); - if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. - __ relocate(rtype); + // Put the entry point as a constant into the constant pool. + const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); + if (entry_point_toc_addr == NULL) { + ciEnv::current()->record_out_of_memory_failure(); + return offsets; } - + const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); + + // Emit the trampoline stub which will be related to the branch-and-link below. + CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); + if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. + __ relocate(rtype); + // Note: At this point we do not have the address of the trampoline // stub, and the entry point might be too far away for bl, so __ pc() // serves as dummy and the bl will be patched later. @@ -2424,6 +2422,29 @@ MacroAssembler _masm(&cbuf); int toc_offset = 0; + address const_toc_addr; + // Create a non-oop constant, no relocation needed. + // If it is an IC, it has a virtual_call_Relocation. + const_toc_addr = __ long_constant((jlong)$src$$constant); + if (const_toc_addr == NULL) { + ciEnv::current()->record_out_of_memory_failure(); + return; + } + + // Get the constant's TOC offset. + toc_offset = __ offset_to_method_toc(const_toc_addr); + + // Keep the current instruction offset in mind. + ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); + + __ ld($dst$$Register, toc_offset, $toc$$Register); + %} + + enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ + // TODO: PPC port $archOpcode(ppc64Opcode_addis); + + MacroAssembler _masm(&cbuf); + if (!ra_->C->in_scratch_emit_size()) { address const_toc_addr; // Create a non-oop constant, no relocation needed. @@ -2435,31 +2456,6 @@ } // Get the constant's TOC offset. - toc_offset = __ offset_to_method_toc(const_toc_addr); - - // Keep the current instruction offset in mind. - ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); - } - - __ ld($dst$$Register, toc_offset, $toc$$Register); - %} - - enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ - // TODO: PPC port $archOpcode(ppc64Opcode_addis); - - MacroAssembler _masm(&cbuf); - - if (!ra_->C->in_scratch_emit_size()) { - address const_toc_addr; - // Create a non-oop constant, no relocation needed. - // If it is an IC, it has a virtual_call_Relocation. - const_toc_addr = __ long_constant((jlong)$src$$constant); - if (const_toc_addr == NULL) { - ciEnv::current()->record_out_of_memory_failure(); - return; - } - - // Get the constant's TOC offset. const int toc_offset = __ offset_to_method_toc(const_toc_addr); // Store the toc offset of the constant. ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; @@ -2576,31 +2572,29 @@ MacroAssembler _masm(&cbuf); int toc_offset = 0; - if (!ra_->C->in_scratch_emit_size()) { - intptr_t val = $src$$constant; - relocInfo::relocType constant_reloc = $src->constant_reloc(); // src - address const_toc_addr; - if (constant_reloc == relocInfo::oop_type) { - // Create an oop constant and a corresponding relocation. - AddressLiteral a = __ allocate_oop_address((jobject)val); - const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); - __ relocate(a.rspec()); - } else if (constant_reloc == relocInfo::metadata_type) { - AddressLiteral a = __ constant_metadata_address((Metadata *)val); - const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); - __ relocate(a.rspec()); - } else { - // Create a non-oop constant, no relocation needed. - const_toc_addr = __ long_constant((jlong)$src$$constant); - } - - if (const_toc_addr == NULL) { - ciEnv::current()->record_out_of_memory_failure(); - return; - } - // Get the constant's TOC offset. - toc_offset = __ offset_to_method_toc(const_toc_addr); - } + intptr_t val = $src$$constant; + relocInfo::relocType constant_reloc = $src->constant_reloc(); // src + address const_toc_addr; + if (constant_reloc == relocInfo::oop_type) { + // Create an oop constant and a corresponding relocation. + AddressLiteral a = __ allocate_oop_address((jobject)val); + const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); + __ relocate(a.rspec()); + } else if (constant_reloc == relocInfo::metadata_type) { + AddressLiteral a = __ constant_metadata_address((Metadata *)val); + const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); + __ relocate(a.rspec()); + } else { + // Create a non-oop constant, no relocation needed. + const_toc_addr = __ long_constant((jlong)$src$$constant); + } + + if (const_toc_addr == NULL) { + ciEnv::current()->record_out_of_memory_failure(); + return; + } + // Get the constant's TOC offset. + toc_offset = __ offset_to_method_toc(const_toc_addr); __ ld($dst$$Register, toc_offset, $toc$$Register); %} @@ -3272,28 +3266,26 @@ } else { // Remember the offset not the address. const int start_offset = __ offset(); + // The trampoline stub. - if (!Compile::current()->in_scratch_emit_size()) { - // No entry point given, use the current pc. - // Make sure branch fits into - if (entry_point == 0) entry_point = __ pc(); - - // Put the entry point as a constant into the constant pool. - const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); - if (entry_point_toc_addr == NULL) { - ciEnv::current()->record_out_of_memory_failure(); - return; - } - const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); - - - // Emit the trampoline stub which will be related to the branch-and-link below. - CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); - if (ciEnv::current()->failing()) { return; } // Code cache may be full. - int method_index = resolved_method_index(cbuf); - __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) - : static_call_Relocation::spec(method_index)); + // No entry point given, use the current pc. + // Make sure branch fits into + if (entry_point == 0) entry_point = __ pc(); + + // Put the entry point as a constant into the constant pool. + const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); + if (entry_point_toc_addr == NULL) { + ciEnv::current()->record_out_of_memory_failure(); + return; } + const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); + + // Emit the trampoline stub which will be related to the branch-and-link below. + CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); + if (ciEnv::current()->failing()) { return; } // Code cache may be full. + int method_index = resolved_method_index(cbuf); + __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) + : static_call_Relocation::spec(method_index)); // The real call. // Note: At this point we do not have the address of the trampoline diff --git a/src/share/vm/asm/assembler.cpp b/src/share/vm/asm/assembler.cpp --- a/src/share/vm/asm/assembler.cpp +++ b/src/share/vm/asm/assembler.cpp @@ -153,6 +153,8 @@ void Label::add_patch_at(CodeBuffer* cb, int branch_loc) { assert(_loc == -1, "Label is unbound"); + // Don't add patch locations during scratch emit. + if (cb->insts()->scratch_emit()) { return; } if (_patch_index < PatchCacheSize) { _patches[_patch_index] = branch_loc; } else { diff --git a/src/share/vm/asm/codeBuffer.cpp b/src/share/vm/asm/codeBuffer.cpp --- a/src/share/vm/asm/codeBuffer.cpp +++ b/src/share/vm/asm/codeBuffer.cpp @@ -331,6 +331,8 @@ } void CodeSection::relocate(address at, RelocationHolder const& spec, int format) { + // Do not relocate in scratch buffers. + if (scratch_emit()) { return; } Relocation* reloc = spec.reloc(); relocInfo::relocType rtype = (relocInfo::relocType) reloc->type(); if (rtype == relocInfo::none) return; diff --git a/src/share/vm/asm/codeBuffer.hpp b/src/share/vm/asm/codeBuffer.hpp --- a/src/share/vm/asm/codeBuffer.hpp +++ b/src/share/vm/asm/codeBuffer.hpp @@ -92,6 +92,7 @@ address _locs_point; // last relocated position (grows upward) bool _locs_own; // did I allocate the locs myself? bool _frozen; // no more expansion of this section + bool _scratch_emit; // Buffer is used for scratch emit, don't relocate. char _index; // my section number (SECT_INST, etc.) CodeBuffer* _outer; // enclosing CodeBuffer @@ -108,6 +109,7 @@ _locs_point = NULL; _locs_own = false; _frozen = false; + _scratch_emit = false; debug_only(_index = (char)-1); debug_only(_outer = (CodeBuffer*)badAddress); } @@ -166,6 +168,10 @@ bool is_frozen() const { return _frozen; } bool has_locs() const { return _locs_end != NULL; } + // Mark scratch buffer. + void set_scratch_emit() { _scratch_emit = true; } + bool scratch_emit() { return _scratch_emit; } + CodeBuffer* outer() const { return _outer; } // is a given address in this section? (2nd version is end-inclusive) diff --git a/src/share/vm/opto/compile.cpp b/src/share/vm/opto/compile.cpp --- a/src/share/vm/opto/compile.cpp +++ b/src/share/vm/opto/compile.cpp @@ -574,6 +574,10 @@ buf.consts()->initialize_shared_locs(&locs_buf[lsize * 0], lsize); buf.insts()->initialize_shared_locs( &locs_buf[lsize * 1], lsize); buf.stubs()->initialize_shared_locs( &locs_buf[lsize * 2], lsize); + // Mark as scratch buffer. + buf.consts()->set_scratch_emit(); + buf.insts()->set_scratch_emit(); + buf.stubs()->set_scratch_emit(); // Do the emission.