# HG changeset patch # User goetz # Date 1475673635 -7200 # Node ID a530dbabe64f309a7b7dfde1c375d0642553db42 # Parent dca9294d9f5945801e16388671af860c3015d1fb 8167184: [s390] Extend relocations for pc-relative instructions. Reviewed-by: kvn diff -r dca9294d9f59 -r a530dbabe64f hotspot/src/share/vm/asm/codeBuffer.cpp --- a/hotspot/src/share/vm/asm/codeBuffer.cpp Thu Sep 22 18:29:15 2016 +0200 +++ b/hotspot/src/share/vm/asm/codeBuffer.cpp Wed Oct 05 15:20:35 2016 +0200 @@ -747,6 +747,10 @@ CodeBuffer dest(dest_blob); assert(dest_blob->content_size() >= total_content_size(), "good sizing"); this->compute_final_layout(&dest); + + // Set beginning of constant table before relocating. + dest_blob->set_ctable_begin(dest.consts()->start()); + relocate_code_to(&dest); // transfer strings and comments from buffer to blob @@ -940,6 +944,9 @@ } } + // Needs to be initialized when calling fix_relocation_after_move. + cb.blob()->set_ctable_begin(cb.consts()->start()); + // Move all the code and relocations to the new blob: relocate_code_to(&cb); diff -r dca9294d9f59 -r a530dbabe64f hotspot/src/share/vm/code/codeBlob.hpp --- a/hotspot/src/share/vm/code/codeBlob.hpp Thu Sep 22 18:29:15 2016 +0200 +++ b/hotspot/src/share/vm/code/codeBlob.hpp Wed Oct 05 15:20:35 2016 +0200 @@ -30,6 +30,7 @@ #include "compiler/oopMap.hpp" #include "runtime/frame.hpp" #include "runtime/handles.hpp" +#include "utilities/macros.hpp" // CodeBlob Types // Used in the CodeCache to assign CodeBlobs to different CodeHeaps @@ -95,6 +96,7 @@ bool _caller_must_gc_arguments; CodeStrings _strings; const char* _name; + S390_ONLY(int _ctable_offset;) CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments); CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments); @@ -140,6 +142,12 @@ address code_end() const { return _code_end; } address data_end() const { return _data_end; } + // This field holds the beginning of the const section in the old code buffer. + // It is needed to fix relocations of pc-relative loads when resizing the + // the constant pool or moving it. + S390_ONLY(address ctable_begin() const { return header_begin() + _ctable_offset; }) + void set_ctable_begin(address ctable) { S390_ONLY(_ctable_offset = ctable - header_begin();) } + // Sizes int size() const { return _size; } int header_size() const { return _header_size; } diff -r dca9294d9f59 -r a530dbabe64f hotspot/src/share/vm/code/nmethod.cpp --- a/hotspot/src/share/vm/code/nmethod.cpp Thu Sep 22 18:29:15 2016 +0200 +++ b/hotspot/src/share/vm/code/nmethod.cpp Wed Oct 05 15:20:35 2016 +0200 @@ -682,6 +682,7 @@ // Section offsets _consts_offset = content_offset() + code_buffer->total_offset_of(code_buffer->consts()); _stub_offset = content_offset() + code_buffer->total_offset_of(code_buffer->stubs()); + set_ctable_begin(header_begin() + _consts_offset); #if INCLUDE_JVMCI _jvmci_installed_code = installed_code(); @@ -2177,6 +2178,7 @@ //verify_interrupt_point(iter.addr()); break; case relocInfo::runtime_call_type: + case relocInfo::runtime_call_w_cp_type: address destination = iter.reloc()->value(); // Right now there is no way to find out which entries support // an interrupt point. It would be nice if we had this @@ -2435,10 +2437,11 @@ st.print(")"); return st.as_string(); } - case relocInfo::runtime_call_type: { + case relocInfo::runtime_call_type: + case relocInfo::runtime_call_w_cp_type: { stringStream st; st.print("runtime_call"); - runtime_call_Relocation* r = iter.runtime_call_reloc(); + CallRelocation* r = (CallRelocation*)iter.reloc(); address dest = r->destination(); CodeBlob* cb = CodeCache::find_blob(dest); if (cb != NULL) { diff -r dca9294d9f59 -r a530dbabe64f hotspot/src/share/vm/code/relocInfo.cpp --- a/hotspot/src/share/vm/code/relocInfo.cpp Thu Sep 22 18:29:15 2016 +0200 +++ b/hotspot/src/share/vm/code/relocInfo.cpp Wed Oct 05 15:20:35 2016 +0200 @@ -552,6 +552,14 @@ _cached_value = x0==0? NULL: address_from_scaled_offset(x0, point); } +void runtime_call_w_cp_Relocation::pack_data_to(CodeSection * dest) { + short* p = pack_1_int_to((short *)dest->locs_end(), (jint)(_offset >> 2)); + dest->set_locs_end((relocInfo*) p); +} + +void runtime_call_w_cp_Relocation::unpack_data() { + _offset = unpack_1_int() << 2; +} void static_stub_Relocation::pack_data_to(CodeSection* dest) { short* p = (short*) dest->locs_end(); @@ -1017,6 +1025,7 @@ break; } case relocInfo::runtime_call_type: + case relocInfo::runtime_call_w_cp_type: { CallRelocation* r = (CallRelocation*) reloc(); tty->print(" | [destination=" INTPTR_FORMAT "]", p2i(r->destination())); diff -r dca9294d9f59 -r a530dbabe64f hotspot/src/share/vm/code/relocInfo.hpp --- a/hotspot/src/share/vm/code/relocInfo.hpp Thu Sep 22 18:29:15 2016 +0200 +++ b/hotspot/src/share/vm/code/relocInfo.hpp Wed Oct 05 15:20:35 2016 +0200 @@ -270,7 +270,7 @@ poll_return_type = 11, // polling instruction for safepoints at return metadata_type = 12, // metadata that used to be oops trampoline_stub_type = 13, // stub-entry for trampoline - yet_unused_type_1 = 14, // Still unused + runtime_call_w_cp_type = 14, // Runtime call which may load its target from the constant pool data_prefix_tag = 15, // tag for a prefix (carries data arguments) type_mask = 15 // A mask which selects only the above values }; @@ -305,6 +305,7 @@ visitor(static_call) \ visitor(static_stub) \ visitor(runtime_call) \ + visitor(runtime_call_w_cp) \ visitor(external_word) \ visitor(internal_word) \ visitor(poll) \ @@ -827,8 +828,6 @@ // ic_call_type is not always posisition dependent (depending on the state of the cache)). However, this is // probably a reasonable assumption, since empty caches simplifies code reloacation. virtual void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { } - - void print(); }; @@ -1175,6 +1174,36 @@ public: }; + +class runtime_call_w_cp_Relocation : public CallRelocation { + relocInfo::relocType type() { return relocInfo::runtime_call_w_cp_type; } + + public: + static RelocationHolder spec() { + RelocationHolder rh = newHolder(); + new(rh) runtime_call_w_cp_Relocation(); + return rh; + } + + private: + friend class RelocIterator; + runtime_call_w_cp_Relocation() { _offset = -4; /* <0 = invalid */ } + // On z/Architecture, runtime calls are either a sequence + // of two instructions (load destination of call from constant pool + do call) + // or a pc-relative call. The pc-relative call is faster, but it can only + // be used if the destination of the call is not too far away. + // In order to be able to patch a pc-relative call back into one using + // the constant pool, we have to remember the location of the call's destination + // in the constant pool. + int _offset; + + public: + void set_constant_pool_offset(int offset) { _offset = offset; } + int get_constant_pool_offset() { return _offset; } + void pack_data_to(CodeSection * dest); + void unpack_data(); +}; + // Trampoline Relocations. // A trampoline allows to encode a small branch in the code, even if there // is the chance that this branch can not reach all possible code locations.