8240669: Devirtualize Relocation::type

Reviewed-by: rbackman, thartmann
This commit is contained in:
Claes Redestad 2020-03-05 16:07:17 +01:00
parent 7fe46b2464
commit d49cf17db0
2 changed files with 63 additions and 84 deletions

View File

@ -231,7 +231,7 @@ Relocation* RelocIterator::reloc() {
APPLY_TO_RELOCATIONS(EACH_TYPE);
#undef EACH_TYPE
assert(t == relocInfo::none, "must be padding");
return new(_rh) Relocation();
return new(_rh) Relocation(t);
}
@ -260,12 +260,7 @@ RelocationHolder RelocationHolder::plus(int offset) const {
return (*this);
}
void Relocation::guarantee_size() {
guarantee(false, "Make _relocbuf bigger!");
}
// some relocations can compute their own values
// some relocations can compute their own values
address Relocation::value() {
ShouldNotReachHere();
return NULL;

View File

@ -515,9 +515,10 @@ class RelocationHolder {
// }
class RelocIterator : public StackObj {
friend class section_word_Relocation; // for section verification
enum { SECT_LIMIT = 3 }; // must be equal to CodeBuffer::SECT_LIMIT, checked in ctor
friend class Relocation;
friend class relocInfo; // for change_reloc_info_for_address only
friend class relocInfo; // for change_reloc_info_for_address only
typedef relocInfo::relocType relocType;
private:
@ -637,13 +638,13 @@ class Relocation {
friend class RelocIterator;
private:
static void guarantee_size();
// When a relocation has been created by a RelocIterator,
// this field is non-null. It allows the relocation to know
// its context, such as the address to which it applies.
RelocIterator* _binding;
relocInfo::relocType _rtype;
protected:
RelocIterator* binding() const {
assert(_binding != NULL, "must be bound");
@ -655,9 +656,7 @@ class Relocation {
assert(_binding != NULL, "must now be bound");
}
Relocation() {
_binding = NULL;
}
Relocation(relocInfo::relocType rtype) : _binding(NULL), _rtype(rtype) { }
static RelocationHolder newHolder() {
return RelocationHolder();
@ -665,7 +664,7 @@ class Relocation {
public:
void* operator new(size_t size, const RelocationHolder& holder) throw() {
if (size > sizeof(holder._relocbuf)) guarantee_size();
assert(size <= sizeof(holder._relocbuf), "Make _relocbuf bigger!");
assert((void* const *)holder.reloc() == &holder._relocbuf[0], "ptrs must agree");
return holder.reloc();
}
@ -792,7 +791,7 @@ class Relocation {
int format() const { return binding()->format(); }
public:
virtual relocInfo::relocType type() { return relocInfo::none; }
relocInfo::relocType type() const { return _rtype; }
// is it a call instruction?
virtual bool is_call() { return false; }
@ -819,7 +818,7 @@ class Relocation {
inline RelocationHolder::RelocationHolder() {
// initialize the vtbl, just to keep things type-safe
new(*this) Relocation();
new(*this) Relocation(relocInfo::none);
}
@ -830,7 +829,6 @@ inline RelocationHolder::RelocationHolder(Relocation* r) {
}
}
relocInfo::relocType RelocationHolder::type() const {
return reloc()->type();
}
@ -841,6 +839,8 @@ relocInfo::relocType RelocationHolder::type() const {
// By convention, the "value" does not include a separately reckoned "offset".
class DataRelocation : public Relocation {
public:
DataRelocation(relocInfo::relocType type) : Relocation(type) {}
bool is_data() { return true; }
// both target and offset must be computed somehow from relocation data
@ -877,6 +877,8 @@ class DataRelocation : public Relocation {
// It is PC-relative on most machines.
class CallRelocation : public Relocation {
public:
CallRelocation(relocInfo::relocType type) : Relocation(type) { }
bool is_call() { return true; }
address destination() { return pd_call_destination(); }
@ -888,8 +890,6 @@ class CallRelocation : public Relocation {
};
class oop_Relocation : public DataRelocation {
relocInfo::relocType type() { return relocInfo::oop_type; }
public:
// encode in one of these formats: [] [n] [n l] [Nn l] [Nn Ll]
// an oop in the CodeBlob's oop pool
@ -916,12 +916,11 @@ class oop_Relocation : public DataRelocation {
jint _oop_index; // if > 0, index into CodeBlob::oop_at
jint _offset; // byte offset to apply to the oop itself
oop_Relocation(int oop_index, int offset) {
_oop_index = oop_index; _offset = offset;
}
oop_Relocation(int oop_index, int offset)
: DataRelocation(relocInfo::oop_type), _oop_index(oop_index), _offset(offset) { }
friend class RelocIterator;
oop_Relocation() { }
oop_Relocation() : DataRelocation(relocInfo::oop_type) {}
public:
int oop_index() { return _oop_index; }
@ -947,7 +946,6 @@ class oop_Relocation : public DataRelocation {
// copy of oop_Relocation for now but may delete stuff in both/either
class metadata_Relocation : public DataRelocation {
relocInfo::relocType type() { return relocInfo::metadata_type; }
public:
// encode in one of these formats: [] [n] [n l] [Nn l] [Nn Ll]
@ -971,12 +969,11 @@ class metadata_Relocation : public DataRelocation {
jint _metadata_index; // if > 0, index into nmethod::metadata_at
jint _offset; // byte offset to apply to the metadata itself
metadata_Relocation(int metadata_index, int offset) {
_metadata_index = metadata_index; _offset = offset;
}
metadata_Relocation(int metadata_index, int offset)
: DataRelocation(relocInfo::metadata_type), _metadata_index(metadata_index), _offset(offset) { }
friend class RelocIterator;
metadata_Relocation() { }
metadata_Relocation() : DataRelocation(relocInfo::metadata_type) { }
// Fixes a Metadata pointer in the code. Most platforms embeds the
// Metadata pointer in the code at compile time so this is empty
@ -1004,7 +1001,6 @@ class metadata_Relocation : public DataRelocation {
class virtual_call_Relocation : public CallRelocation {
relocInfo::relocType type() { return relocInfo::virtual_call_type; }
public:
// "cached_value" points to the first associated set-oop.
@ -1020,14 +1016,15 @@ class virtual_call_Relocation : public CallRelocation {
address _cached_value; // location of set-value instruction
jint _method_index; // resolved method for a Java call
virtual_call_Relocation(address cached_value, int method_index) {
_cached_value = cached_value;
_method_index = method_index;
virtual_call_Relocation(address cached_value, int method_index)
: CallRelocation(relocInfo::virtual_call_type),
_cached_value(cached_value),
_method_index(method_index) {
assert(cached_value != NULL, "first oop address must be specified");
}
friend class RelocIterator;
virtual_call_Relocation() { }
virtual_call_Relocation() : CallRelocation(relocInfo::virtual_call_type) { }
public:
address cached_value();
@ -1047,8 +1044,6 @@ class virtual_call_Relocation : public CallRelocation {
class opt_virtual_call_Relocation : public CallRelocation {
relocInfo::relocType type() { return relocInfo::opt_virtual_call_type; }
public:
static RelocationHolder spec(int method_index = 0) {
RelocationHolder rh = newHolder();
@ -1059,12 +1054,12 @@ class opt_virtual_call_Relocation : public CallRelocation {
private:
jint _method_index; // resolved method for a Java call
opt_virtual_call_Relocation(int method_index) {
_method_index = method_index;
}
opt_virtual_call_Relocation(int method_index)
: CallRelocation(relocInfo::opt_virtual_call_type),
_method_index(method_index) { }
friend class RelocIterator;
opt_virtual_call_Relocation() {}
opt_virtual_call_Relocation() : CallRelocation(relocInfo::opt_virtual_call_type) {}
public:
int method_index() { return _method_index; }
@ -1081,8 +1076,6 @@ class opt_virtual_call_Relocation : public CallRelocation {
class static_call_Relocation : public CallRelocation {
relocInfo::relocType type() { return relocInfo::static_call_type; }
public:
static RelocationHolder spec(int method_index = 0) {
RelocationHolder rh = newHolder();
@ -1093,12 +1086,12 @@ class static_call_Relocation : public CallRelocation {
private:
jint _method_index; // resolved method for a Java call
static_call_Relocation(int method_index) {
_method_index = method_index;
}
static_call_Relocation(int method_index)
: CallRelocation(relocInfo::static_call_type),
_method_index(method_index) { }
friend class RelocIterator;
static_call_Relocation() {}
static_call_Relocation() : CallRelocation(relocInfo::static_call_type) {}
public:
int method_index() { return _method_index; }
@ -1114,8 +1107,6 @@ class static_call_Relocation : public CallRelocation {
};
class static_stub_Relocation : public Relocation {
relocInfo::relocType type() { return relocInfo::static_stub_type; }
public:
static RelocationHolder spec(address static_call, bool is_aot = false) {
RelocationHolder rh = newHolder();
@ -1127,13 +1118,12 @@ class static_stub_Relocation : public Relocation {
address _static_call; // location of corresponding static_call
bool _is_aot; // trampoline to aot code
static_stub_Relocation(address static_call, bool is_aot) {
_static_call = static_call;
_is_aot = is_aot;
}
static_stub_Relocation(address static_call, bool is_aot)
: Relocation(relocInfo::static_stub_type),
_static_call(static_call), _is_aot(is_aot) { }
friend class RelocIterator;
static_stub_Relocation() { }
static_stub_Relocation() : Relocation(relocInfo::static_stub_type) { }
public:
bool clear_inline_cache();
@ -1147,7 +1137,6 @@ class static_stub_Relocation : public Relocation {
};
class runtime_call_Relocation : public CallRelocation {
relocInfo::relocType type() { return relocInfo::runtime_call_type; }
public:
static RelocationHolder spec() {
@ -1158,15 +1147,13 @@ class runtime_call_Relocation : public CallRelocation {
private:
friend class RelocIterator;
runtime_call_Relocation() { }
runtime_call_Relocation() : CallRelocation(relocInfo::runtime_call_type) { }
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();
@ -1176,7 +1163,10 @@ class runtime_call_w_cp_Relocation : public CallRelocation {
private:
friend class RelocIterator;
runtime_call_w_cp_Relocation() { _offset = -4; /* <0 = invalid */ }
runtime_call_w_cp_Relocation()
: CallRelocation(relocInfo::runtime_call_w_cp_type),
_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
@ -1200,8 +1190,6 @@ class runtime_call_w_cp_Relocation : public CallRelocation {
// in the code, it can patch it to jump to the trampoline where is
// sufficient space for a far branch. Needed on PPC.
class trampoline_stub_Relocation : public Relocation {
relocInfo::relocType type() { return relocInfo::trampoline_stub_type; }
public:
static RelocationHolder spec(address static_call) {
RelocationHolder rh = newHolder();
@ -1211,12 +1199,12 @@ class trampoline_stub_Relocation : public Relocation {
private:
address _owner; // Address of the NativeCall that owns the trampoline.
trampoline_stub_Relocation(address owner) {
_owner = owner;
}
trampoline_stub_Relocation(address owner)
: Relocation(relocInfo::trampoline_stub_type),
_owner(owner) { }
friend class RelocIterator;
trampoline_stub_Relocation() { }
trampoline_stub_Relocation() : Relocation(relocInfo::trampoline_stub_type) { }
public:
@ -1231,8 +1219,6 @@ class trampoline_stub_Relocation : public Relocation {
};
class external_word_Relocation : public DataRelocation {
relocInfo::relocType type() { return relocInfo::external_word_type; }
public:
static RelocationHolder spec(address target) {
assert(target != NULL, "must not be null");
@ -1259,12 +1245,11 @@ class external_word_Relocation : public DataRelocation {
private:
address _target; // address in runtime
external_word_Relocation(address target) {
_target = target;
}
external_word_Relocation(address target)
: DataRelocation(relocInfo::external_word_type), _target(target) { }
friend class RelocIterator;
external_word_Relocation() { }
external_word_Relocation() : DataRelocation(relocInfo::external_word_type) { }
public:
// data is packed as a well-known address in "1_int" format: [a] or [Aa]
@ -1281,7 +1266,6 @@ class external_word_Relocation : public DataRelocation {
};
class internal_word_Relocation : public DataRelocation {
relocInfo::relocType type() { return relocInfo::internal_word_type; }
public:
static RelocationHolder spec(address target) {
@ -1298,17 +1282,18 @@ class internal_word_Relocation : public DataRelocation {
return rh;
}
internal_word_Relocation(address target) {
_target = target;
_section = -1; // self-relative
}
// default section -1 means self-relative
internal_word_Relocation(address target, int section = -1,
relocInfo::relocType type = relocInfo::internal_word_type)
: DataRelocation(type), _target(target), _section(section) { }
protected:
address _target; // address in CodeBlob
int _section; // section providing base address, if any
friend class RelocIterator;
internal_word_Relocation() { }
internal_word_Relocation(relocInfo::relocType type = relocInfo::internal_word_type)
: DataRelocation(type) { }
// bit-width of LSB field in packed offset, if section >= 0
enum { section_width = 2 }; // must equal CodeBuffer::sect_bits
@ -1328,8 +1313,6 @@ class internal_word_Relocation : public DataRelocation {
};
class section_word_Relocation : public internal_word_Relocation {
relocInfo::relocType type() { return relocInfo::section_word_type; }
public:
static RelocationHolder spec(address target, int section) {
RelocationHolder rh = newHolder();
@ -1337,11 +1320,10 @@ class section_word_Relocation : public internal_word_Relocation {
return rh;
}
section_word_Relocation(address target, int section) {
section_word_Relocation(address target, int section)
: internal_word_Relocation(target, section, relocInfo::section_word_type) {
assert(target != NULL, "must not be null");
assert(section >= 0, "must be a valid section");
_target = target;
_section = section;
assert(section >= 0 && section < RelocIterator::SECT_LIMIT, "must be a valid section");
}
//void pack_data_to -- inherited
@ -1349,18 +1331,20 @@ class section_word_Relocation : public internal_word_Relocation {
private:
friend class RelocIterator;
section_word_Relocation() { }
section_word_Relocation() : internal_word_Relocation(relocInfo::section_word_type) { }
};
class poll_Relocation : public Relocation {
bool is_data() { return true; }
relocInfo::relocType type() { return relocInfo::poll_type; }
void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest);
public:
poll_Relocation(relocInfo::relocType type = relocInfo::poll_type) : Relocation(type) { }
};
class poll_return_Relocation : public poll_Relocation {
relocInfo::relocType type() { return relocInfo::poll_return_type; }
public:
poll_return_Relocation() : poll_Relocation(relocInfo::relocInfo::poll_return_type) { }
};
// We know all the xxx_Relocation classes, so now we can define these: