# HG changeset patch # User kvn # Date 1354066898 28800 # Node ID 1acccb7c0b01d04d74a47a25f3b465ef3e34507e # Parent 2aff40cb47031bde5ce55a6b6563b040d050d669 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 diff -r 2aff40cb4703 -r 1acccb7c0b01 src/share/vm/asm/assembler.cpp --- a/src/share/vm/asm/assembler.cpp Tue Nov 27 17:24:15 2012 -0800 +++ b/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()); diff -r 2aff40cb4703 -r 1acccb7c0b01 src/share/vm/asm/assembler.hpp --- a/src/share/vm/asm/assembler.hpp Tue Nov 27 17:24:15 2012 -0800 +++ b/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; } diff -r 2aff40cb4703 -r 1acccb7c0b01 src/share/vm/asm/codeBuffer.cpp --- a/src/share/vm/asm/codeBuffer.cpp Tue Nov 27 17:24:15 2012 -0800 +++ b/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()) {