mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8166562: C2: Suppress relocations in scratch emit
Reviewed-by: kvn
This commit is contained in:
parent
3c1ab21ffa
commit
969358fbb3
5 changed files with 79 additions and 73 deletions
|
@ -1097,21 +1097,19 @@ EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address en
|
||||||
// No entry point given, use the current pc.
|
// No entry point given, use the current pc.
|
||||||
if (entry_point == NULL) entry_point = __ 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.
|
||||||
// Put the entry point as a constant into the constant pool.
|
const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none);
|
||||||
const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none);
|
if (entry_point_toc_addr == NULL) {
|
||||||
if (entry_point_toc_addr == NULL) {
|
ciEnv::current()->record_out_of_memory_failure();
|
||||||
ciEnv::current()->record_out_of_memory_failure();
|
return offsets;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
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
|
// 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()
|
// stub, and the entry point might be too far away for bl, so __ pc()
|
||||||
// serves as dummy and the bl will be patched later.
|
// serves as dummy and the bl will be patched later.
|
||||||
|
@ -2434,23 +2432,21 @@ encode %{
|
||||||
MacroAssembler _masm(&cbuf);
|
MacroAssembler _masm(&cbuf);
|
||||||
int toc_offset = 0;
|
int toc_offset = 0;
|
||||||
|
|
||||||
if (!ra_->C->in_scratch_emit_size()) {
|
address const_toc_addr;
|
||||||
address const_toc_addr;
|
// Create a non-oop constant, no relocation needed.
|
||||||
// Create a non-oop constant, no relocation needed.
|
// If it is an IC, it has a virtual_call_Relocation.
|
||||||
// If it is an IC, it has a virtual_call_Relocation.
|
const_toc_addr = __ long_constant((jlong)$src$$constant);
|
||||||
const_toc_addr = __ long_constant((jlong)$src$$constant);
|
if (const_toc_addr == NULL) {
|
||||||
if (const_toc_addr == NULL) {
|
ciEnv::current()->record_out_of_memory_failure();
|
||||||
ciEnv::current()->record_out_of_memory_failure();
|
return;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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);
|
__ ld($dst$$Register, toc_offset, $toc$$Register);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -2586,32 +2582,30 @@ encode %{
|
||||||
MacroAssembler _masm(&cbuf);
|
MacroAssembler _masm(&cbuf);
|
||||||
int toc_offset = 0;
|
int toc_offset = 0;
|
||||||
|
|
||||||
if (!ra_->C->in_scratch_emit_size()) {
|
intptr_t val = $src$$constant;
|
||||||
intptr_t val = $src$$constant;
|
relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
|
||||||
relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
|
address const_toc_addr;
|
||||||
address const_toc_addr;
|
if (constant_reloc == relocInfo::oop_type) {
|
||||||
if (constant_reloc == relocInfo::oop_type) {
|
// Create an oop constant and a corresponding relocation.
|
||||||
// Create an oop constant and a corresponding relocation.
|
AddressLiteral a = __ allocate_oop_address((jobject)val);
|
||||||
AddressLiteral a = __ allocate_oop_address((jobject)val);
|
const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
|
||||||
const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
|
__ relocate(a.rspec());
|
||||||
__ relocate(a.rspec());
|
} else if (constant_reloc == relocInfo::metadata_type) {
|
||||||
} else if (constant_reloc == relocInfo::metadata_type) {
|
AddressLiteral a = __ constant_metadata_address((Metadata *)val);
|
||||||
AddressLiteral a = __ constant_metadata_address((Metadata *)val);
|
const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
|
||||||
const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
|
__ relocate(a.rspec());
|
||||||
__ relocate(a.rspec());
|
} else {
|
||||||
} else {
|
// Create a non-oop constant, no relocation needed.
|
||||||
// Create a non-oop constant, no relocation needed.
|
const_toc_addr = __ long_constant((jlong)$src$$constant);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
__ ld($dst$$Register, toc_offset, $toc$$Register);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -3282,28 +3276,26 @@ encode %{
|
||||||
} else {
|
} else {
|
||||||
// Remember the offset not the address.
|
// Remember the offset not the address.
|
||||||
const int start_offset = __ offset();
|
const int start_offset = __ offset();
|
||||||
|
|
||||||
// The trampoline stub.
|
// The trampoline stub.
|
||||||
if (!Compile::current()->in_scratch_emit_size()) {
|
// No entry point given, use the current pc.
|
||||||
// No entry point given, use the current pc.
|
// Make sure branch fits into
|
||||||
// Make sure branch fits into
|
if (entry_point == 0) entry_point = __ pc();
|
||||||
if (entry_point == 0) entry_point = __ pc();
|
|
||||||
|
|
||||||
// Put the entry point as a constant into the constant pool.
|
// Put the entry point as a constant into the constant pool.
|
||||||
const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none);
|
const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none);
|
||||||
if (entry_point_toc_addr == NULL) {
|
if (entry_point_toc_addr == NULL) {
|
||||||
ciEnv::current()->record_out_of_memory_failure();
|
ciEnv::current()->record_out_of_memory_failure();
|
||||||
return;
|
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));
|
|
||||||
}
|
}
|
||||||
|
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.
|
// The real call.
|
||||||
// Note: At this point we do not have the address of the trampoline
|
// Note: At this point we do not have the address of the trampoline
|
||||||
|
|
|
@ -153,6 +153,8 @@ void AbstractAssembler::generate_stack_overflow_check(int frame_size_in_bytes) {
|
||||||
|
|
||||||
void Label::add_patch_at(CodeBuffer* cb, int branch_loc) {
|
void Label::add_patch_at(CodeBuffer* cb, int branch_loc) {
|
||||||
assert(_loc == -1, "Label is unbound");
|
assert(_loc == -1, "Label is unbound");
|
||||||
|
// Don't add patch locations during scratch emit.
|
||||||
|
if (cb->insts()->scratch_emit()) { return; }
|
||||||
if (_patch_index < PatchCacheSize) {
|
if (_patch_index < PatchCacheSize) {
|
||||||
_patches[_patch_index] = branch_loc;
|
_patches[_patch_index] = branch_loc;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -331,6 +331,8 @@ void CodeSection::relocate(address at, relocInfo::relocType rtype, int format, j
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeSection::relocate(address at, RelocationHolder const& spec, int format) {
|
void CodeSection::relocate(address at, RelocationHolder const& spec, int format) {
|
||||||
|
// Do not relocate in scratch buffers.
|
||||||
|
if (scratch_emit()) { return; }
|
||||||
Relocation* reloc = spec.reloc();
|
Relocation* reloc = spec.reloc();
|
||||||
relocInfo::relocType rtype = (relocInfo::relocType) reloc->type();
|
relocInfo::relocType rtype = (relocInfo::relocType) reloc->type();
|
||||||
if (rtype == relocInfo::none) return;
|
if (rtype == relocInfo::none) return;
|
||||||
|
|
|
@ -92,6 +92,7 @@ class CodeSection VALUE_OBJ_CLASS_SPEC {
|
||||||
address _locs_point; // last relocated position (grows upward)
|
address _locs_point; // last relocated position (grows upward)
|
||||||
bool _locs_own; // did I allocate the locs myself?
|
bool _locs_own; // did I allocate the locs myself?
|
||||||
bool _frozen; // no more expansion of this section
|
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.)
|
char _index; // my section number (SECT_INST, etc.)
|
||||||
CodeBuffer* _outer; // enclosing CodeBuffer
|
CodeBuffer* _outer; // enclosing CodeBuffer
|
||||||
|
|
||||||
|
@ -108,6 +109,7 @@ class CodeSection VALUE_OBJ_CLASS_SPEC {
|
||||||
_locs_point = NULL;
|
_locs_point = NULL;
|
||||||
_locs_own = false;
|
_locs_own = false;
|
||||||
_frozen = false;
|
_frozen = false;
|
||||||
|
_scratch_emit = false;
|
||||||
debug_only(_index = (char)-1);
|
debug_only(_index = (char)-1);
|
||||||
debug_only(_outer = (CodeBuffer*)badAddress);
|
debug_only(_outer = (CodeBuffer*)badAddress);
|
||||||
}
|
}
|
||||||
|
@ -166,6 +168,10 @@ class CodeSection VALUE_OBJ_CLASS_SPEC {
|
||||||
bool is_frozen() const { return _frozen; }
|
bool is_frozen() const { return _frozen; }
|
||||||
bool has_locs() const { return _locs_end != NULL; }
|
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; }
|
CodeBuffer* outer() const { return _outer; }
|
||||||
|
|
||||||
// is a given address in this section? (2nd version is end-inclusive)
|
// is a given address in this section? (2nd version is end-inclusive)
|
||||||
|
|
|
@ -574,6 +574,10 @@ uint Compile::scratch_emit_size(const Node* n) {
|
||||||
buf.consts()->initialize_shared_locs(&locs_buf[lsize * 0], lsize);
|
buf.consts()->initialize_shared_locs(&locs_buf[lsize * 0], lsize);
|
||||||
buf.insts()->initialize_shared_locs( &locs_buf[lsize * 1], lsize);
|
buf.insts()->initialize_shared_locs( &locs_buf[lsize * 1], lsize);
|
||||||
buf.stubs()->initialize_shared_locs( &locs_buf[lsize * 2], 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.
|
// Do the emission.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue