8003850: add support for constants in stub code
Summary: remember the code section and switch back to the proper one when adding constants.
Reviewed-by: twisti, kvn
Contributed-by: goetz.lindenmaier@sap.com
--- a/hotspot/src/share/vm/asm/assembler.cpp Tue Nov 27 17:24:15 2012 -0800
+++ b/hotspot/src/share/vm/asm/assembler.cpp Tue Nov 27 17:41:38 2012 -0800
@@ -104,7 +104,7 @@
address AbstractAssembler::start_a_const(int required_space, int required_align) {
CodeBuffer* cb = code();
CodeSection* cs = cb->consts();
- assert(_code_section == cb->insts(), "not in insts?");
+ assert(_code_section == cb->insts() || _code_section == cb->stubs(), "not in insts/stubs?");
sync();
address end = cs->end();
int pad = -(intptr_t)end & (required_align-1);
@@ -121,14 +121,13 @@
}
// Inform CodeBuffer that incoming code and relocation will be code
-// Should not be called if start_a_const() returned NULL
-void AbstractAssembler::end_a_const() {
+// in section cs (insts or stubs).
+void AbstractAssembler::end_a_const(CodeSection* cs) {
assert(_code_section == code()->consts(), "not in consts?");
sync();
- set_code_section(code()->insts());
+ set_code_section(cs);
}
-
void AbstractAssembler::flush() {
sync();
ICache::invalidate_range(addr_at(0), offset());
--- a/hotspot/src/share/vm/asm/assembler.hpp Tue Nov 27 17:24:15 2012 -0800
+++ b/hotspot/src/share/vm/asm/assembler.hpp Tue Nov 27 17:41:38 2012 -0800
@@ -348,52 +348,60 @@
void end_a_stub();
// Ditto for constants.
address start_a_const(int required_space, int required_align = sizeof(double));
- void end_a_const();
+ void end_a_const(CodeSection* cs); // Pass the codesection to continue in (insts or stubs?).
// constants support
+ //
+ // We must remember the code section (insts or stubs) in c1
+ // so we can reset to the proper section in end_a_const().
address long_constant(jlong c) {
+ CodeSection* c1 = _code_section;
address ptr = start_a_const(sizeof(c), sizeof(c));
if (ptr != NULL) {
*(jlong*)ptr = c;
_code_pos = ptr + sizeof(c);
- end_a_const();
+ end_a_const(c1);
}
return ptr;
}
address double_constant(jdouble c) {
+ CodeSection* c1 = _code_section;
address ptr = start_a_const(sizeof(c), sizeof(c));
if (ptr != NULL) {
*(jdouble*)ptr = c;
_code_pos = ptr + sizeof(c);
- end_a_const();
+ end_a_const(c1);
}
return ptr;
}
address float_constant(jfloat c) {
+ CodeSection* c1 = _code_section;
address ptr = start_a_const(sizeof(c), sizeof(c));
if (ptr != NULL) {
*(jfloat*)ptr = c;
_code_pos = ptr + sizeof(c);
- end_a_const();
+ end_a_const(c1);
}
return ptr;
}
address address_constant(address c) {
+ CodeSection* c1 = _code_section;
address ptr = start_a_const(sizeof(c), sizeof(c));
if (ptr != NULL) {
*(address*)ptr = c;
_code_pos = ptr + sizeof(c);
- end_a_const();
+ end_a_const(c1);
}
return ptr;
}
address address_constant(address c, RelocationHolder const& rspec) {
+ CodeSection* c1 = _code_section;
address ptr = start_a_const(sizeof(c), sizeof(c));
if (ptr != NULL) {
relocate(rspec);
*(address*)ptr = c;
_code_pos = ptr + sizeof(c);
- end_a_const();
+ end_a_const(c1);
}
return ptr;
}
--- a/hotspot/src/share/vm/asm/codeBuffer.cpp Tue Nov 27 17:24:15 2012 -0800
+++ b/hotspot/src/share/vm/asm/codeBuffer.cpp Tue Nov 27 17:41:38 2012 -0800
@@ -749,7 +749,18 @@
// Make the new code copy use the old copy's relocations:
dest_cs->initialize_locs_from(cs);
+ }
+ // Do relocation after all sections are copied.
+ // This is necessary if the code uses constants in stubs, which are
+ // relocated when the corresponding instruction in the code (e.g., a
+ // call) is relocated. Stubs are placed behind the main code
+ // section, so that section has to be copied before relocating.
+ for (int n = (int) SECT_FIRST; n < (int)SECT_LIMIT; n++) {
+ // pull code out of each section
+ const CodeSection* cs = code_section(n);
+ if (cs->is_empty()) continue; // skip trivial section
+ CodeSection* dest_cs = dest->code_section(n);
{ // Repair the pc relative information in the code after the move
RelocIterator iter(dest_cs);
while (iter.next()) {