8003850: add support for constants in stub code

Remember the code section and switch back to the proper one when adding constants.

Reviewed-by: twisti, kvn
This commit is contained in:
Goetz Lindenmaier 2012-11-27 17:41:38 -08:00 committed by Vladimir Kozlov
parent 2d2532e740
commit 8e00acca17
3 changed files with 29 additions and 11 deletions

View File

@ -104,7 +104,7 @@ void AbstractAssembler::end_a_stub() {
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 @@ address AbstractAssembler::start_a_const(int required_space, int required_align)
}
// 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());

View File

@ -348,52 +348,60 @@ class AbstractAssembler : public ResourceObj {
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;
}

View File

@ -749,7 +749,18 @@ void CodeBuffer::relocate_code_to(CodeBuffer* dest) const {
// 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()) {