8240669: Devirtualize Relocation::type
Reviewed-by: rbackman, thartmann
This commit is contained in:
parent
7fe46b2464
commit
d49cf17db0
@ -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;
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user