mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-17 09:34:38 +02:00
8276095: ciReplay: replay failure due to incomplete ciMethodData information
Reviewed-by: chagedorn, kvn
This commit is contained in:
parent
7a870418a3
commit
9326eb1461
8 changed files with 36 additions and 37 deletions
|
@ -1643,6 +1643,7 @@ void ciEnv::dump_replay_data_helper(outputStream* out) {
|
||||||
NoSafepointVerifier no_safepoint;
|
NoSafepointVerifier no_safepoint;
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
|
|
||||||
|
out->print_cr("version %d", REPLAY_VERSION);
|
||||||
#if INCLUDE_JVMTI
|
#if INCLUDE_JVMTI
|
||||||
out->print_cr("JvmtiExport can_access_local_variables %d", _jvmti_can_access_local_variables);
|
out->print_cr("JvmtiExport can_access_local_variables %d", _jvmti_can_access_local_variables);
|
||||||
out->print_cr("JvmtiExport can_hotswap_or_post_breakpoint %d", _jvmti_can_hotswap_or_post_breakpoint);
|
out->print_cr("JvmtiExport can_hotswap_or_post_breakpoint %d", _jvmti_can_hotswap_or_post_breakpoint);
|
||||||
|
|
|
@ -49,10 +49,7 @@ ciMethodData::ciMethodData(MethodData* md)
|
||||||
_saw_free_extra_data(false),
|
_saw_free_extra_data(false),
|
||||||
// Initialize the escape information (to "don't know.");
|
// Initialize the escape information (to "don't know.");
|
||||||
_eflags(0), _arg_local(0), _arg_stack(0), _arg_returned(0),
|
_eflags(0), _arg_local(0), _arg_stack(0), _arg_returned(0),
|
||||||
_creation_mileage(0),
|
|
||||||
_current_mileage(0),
|
|
||||||
_invocation_counter(0),
|
_invocation_counter(0),
|
||||||
_backedge_counter(0),
|
|
||||||
_orig(),
|
_orig(),
|
||||||
_parameters(NULL) {}
|
_parameters(NULL) {}
|
||||||
|
|
||||||
|
@ -250,10 +247,7 @@ bool ciMethodData::load_data() {
|
||||||
load_remaining_extra_data();
|
load_remaining_extra_data();
|
||||||
|
|
||||||
// Note: Extra data are all BitData, and do not need translation.
|
// Note: Extra data are all BitData, and do not need translation.
|
||||||
_creation_mileage = mdo->creation_mileage();
|
|
||||||
_current_mileage = MethodData::mileage_of(mdo->method());
|
|
||||||
_invocation_counter = mdo->invocation_count();
|
_invocation_counter = mdo->invocation_count();
|
||||||
_backedge_counter = mdo->backedge_count();
|
|
||||||
_state = mdo->is_mature()? mature_state: immature_state;
|
_state = mdo->is_mature()? mature_state: immature_state;
|
||||||
|
|
||||||
_eflags = mdo->eflags();
|
_eflags = mdo->eflags();
|
||||||
|
@ -706,7 +700,7 @@ void ciMethodData::dump_replay_data(outputStream* out) {
|
||||||
Method* method = mdo->method();
|
Method* method = mdo->method();
|
||||||
out->print("ciMethodData ");
|
out->print("ciMethodData ");
|
||||||
ciMethod::dump_name_as_ascii(out, method);
|
ciMethod::dump_name_as_ascii(out, method);
|
||||||
out->print(" %d %d", _state, current_mileage());
|
out->print(" %d %d", _state, _invocation_counter);
|
||||||
|
|
||||||
// dump the contents of the MDO header as raw data
|
// dump the contents of the MDO header as raw data
|
||||||
unsigned char* orig = (unsigned char*)&_orig;
|
unsigned char* orig = (unsigned char*)&_orig;
|
||||||
|
|
|
@ -395,16 +395,10 @@ private:
|
||||||
intx _arg_stack; // bit set of stack-allocatable arguments
|
intx _arg_stack; // bit set of stack-allocatable arguments
|
||||||
intx _arg_returned; // bit set of returned arguments
|
intx _arg_returned; // bit set of returned arguments
|
||||||
|
|
||||||
int _creation_mileage; // method mileage at MDO creation
|
|
||||||
|
|
||||||
// Maturity of the oop when the snapshot is taken.
|
|
||||||
int _current_mileage;
|
|
||||||
|
|
||||||
// These counters hold the age of MDO in tiered. In tiered we can have the same method
|
// These counters hold the age of MDO in tiered. In tiered we can have the same method
|
||||||
// running at different compilation levels concurrently. So, in order to precisely measure
|
// running at different compilation levels concurrently. So, in order to precisely measure
|
||||||
// its maturity we need separate counters.
|
// its maturity we need separate counters.
|
||||||
int _invocation_counter;
|
int _invocation_counter;
|
||||||
int _backedge_counter;
|
|
||||||
|
|
||||||
// Coherent snapshot of original header.
|
// Coherent snapshot of original header.
|
||||||
MethodData::CompilerCounters _orig;
|
MethodData::CompilerCounters _orig;
|
||||||
|
@ -477,11 +471,7 @@ public:
|
||||||
bool is_empty() { return _state == empty_state; }
|
bool is_empty() { return _state == empty_state; }
|
||||||
bool is_mature() { return _state == mature_state; }
|
bool is_mature() { return _state == mature_state; }
|
||||||
|
|
||||||
int creation_mileage() { return _creation_mileage; }
|
|
||||||
int current_mileage() { return _current_mileage; }
|
|
||||||
|
|
||||||
int invocation_count() { return _invocation_counter; }
|
int invocation_count() { return _invocation_counter; }
|
||||||
int backedge_count() { return _backedge_counter; }
|
|
||||||
|
|
||||||
#if INCLUDE_RTM_OPT
|
#if INCLUDE_RTM_OPT
|
||||||
// return cached value
|
// return cached value
|
||||||
|
|
|
@ -65,7 +65,7 @@ typedef struct _ciMethodDataRecord {
|
||||||
const char* _signature;
|
const char* _signature;
|
||||||
|
|
||||||
int _state;
|
int _state;
|
||||||
int _current_mileage;
|
int _invocation_counter;
|
||||||
|
|
||||||
intptr_t* _data;
|
intptr_t* _data;
|
||||||
char* _orig_data;
|
char* _orig_data;
|
||||||
|
@ -115,6 +115,7 @@ class CompileReplay : public StackObj {
|
||||||
Handle _protection_domain;
|
Handle _protection_domain;
|
||||||
bool _protection_domain_initialized;
|
bool _protection_domain_initialized;
|
||||||
Handle _loader;
|
Handle _loader;
|
||||||
|
int _version;
|
||||||
|
|
||||||
GrowableArray<ciMethodRecord*> _ci_method_records;
|
GrowableArray<ciMethodRecord*> _ci_method_records;
|
||||||
GrowableArray<ciMethodDataRecord*> _ci_method_data_records;
|
GrowableArray<ciMethodDataRecord*> _ci_method_data_records;
|
||||||
|
@ -159,6 +160,7 @@ class CompileReplay : public StackObj {
|
||||||
_iklass = NULL;
|
_iklass = NULL;
|
||||||
_entry_bci = 0;
|
_entry_bci = 0;
|
||||||
_comp_level = 0;
|
_comp_level = 0;
|
||||||
|
_version = 0;
|
||||||
|
|
||||||
test();
|
test();
|
||||||
}
|
}
|
||||||
|
@ -638,6 +640,11 @@ class CompileReplay : public StackObj {
|
||||||
tty->print_cr("# %s", _bufptr);
|
tty->print_cr("# %s", _bufptr);
|
||||||
}
|
}
|
||||||
skip_remaining();
|
skip_remaining();
|
||||||
|
} else if (strcmp("version", cmd) == 0) {
|
||||||
|
_version = parse_int("version");
|
||||||
|
if (_version < 0 || _version > REPLAY_VERSION) {
|
||||||
|
tty->print_cr("# unrecognized version %d, expected 0 <= version <= %d", _version, REPLAY_VERSION);
|
||||||
|
}
|
||||||
} else if (strcmp("compile", cmd) == 0) {
|
} else if (strcmp("compile", cmd) == 0) {
|
||||||
process_compile(CHECK);
|
process_compile(CHECK);
|
||||||
} else if (strcmp("ciMethod", cmd) == 0) {
|
} else if (strcmp("ciMethod", cmd) == 0) {
|
||||||
|
@ -802,7 +809,7 @@ class CompileReplay : public StackObj {
|
||||||
rec->_instructions_size = parse_int("instructions_size");
|
rec->_instructions_size = parse_int("instructions_size");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ciMethodData <klass> <name> <signature> <state> <current_mileage> orig <length> <byte>* data <length> <ptr>* oops <length> (<offset> <klass>)* methods <length> (<offset> <klass> <name> <signature>)*
|
// ciMethodData <klass> <name> <signature> <state> <invocation_counter> orig <length> <byte>* data <length> <ptr>* oops <length> (<offset> <klass>)* methods <length> (<offset> <klass> <name> <signature>)*
|
||||||
void process_ciMethodData(TRAPS) {
|
void process_ciMethodData(TRAPS) {
|
||||||
Method* method = parse_method(CHECK);
|
Method* method = parse_method(CHECK);
|
||||||
if (had_error()) return;
|
if (had_error()) return;
|
||||||
|
@ -827,7 +834,11 @@ class CompileReplay : public StackObj {
|
||||||
// collect and record all the needed information for later
|
// collect and record all the needed information for later
|
||||||
ciMethodDataRecord* rec = new_ciMethodData(method);
|
ciMethodDataRecord* rec = new_ciMethodData(method);
|
||||||
rec->_state = parse_int("state");
|
rec->_state = parse_int("state");
|
||||||
rec->_current_mileage = parse_int("current_mileage");
|
if (_version < 1) {
|
||||||
|
parse_int("current_mileage");
|
||||||
|
} else {
|
||||||
|
rec->_invocation_counter = parse_int("invocation_counter");
|
||||||
|
}
|
||||||
|
|
||||||
rec->_orig_data = parse_data("orig", rec->_orig_data_length);
|
rec->_orig_data = parse_data("orig", rec->_orig_data_length);
|
||||||
if (rec->_orig_data == NULL) {
|
if (rec->_orig_data == NULL) {
|
||||||
|
@ -876,6 +887,8 @@ class CompileReplay : public StackObj {
|
||||||
void process_instanceKlass(TRAPS) {
|
void process_instanceKlass(TRAPS) {
|
||||||
// just load the referenced class
|
// just load the referenced class
|
||||||
Klass* k = parse_klass(CHECK);
|
Klass* k = parse_klass(CHECK);
|
||||||
|
|
||||||
|
if (_version >= 1) {
|
||||||
if (!_protection_domain_initialized && k != NULL) {
|
if (!_protection_domain_initialized && k != NULL) {
|
||||||
assert(_protection_domain() == NULL, "must be uninitialized");
|
assert(_protection_domain() == NULL, "must be uninitialized");
|
||||||
// The first entry is the holder class of the method for which a replay compilation is requested.
|
// The first entry is the holder class of the method for which a replay compilation is requested.
|
||||||
|
@ -884,9 +897,8 @@ class CompileReplay : public StackObj {
|
||||||
_protection_domain = Handle(_thread, k->protection_domain());
|
_protection_domain = Handle(_thread, k->protection_domain());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only initialize the protection domain handle with the protection domain of the very first entry.
|
|
||||||
// This also ensures that older replay files work.
|
|
||||||
_protection_domain_initialized = true;
|
_protection_domain_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (k == NULL) {
|
if (k == NULL) {
|
||||||
return;
|
return;
|
||||||
|
@ -1413,7 +1425,7 @@ void ciReplay::initialize(ciMethodData* m) {
|
||||||
tty->cr();
|
tty->cr();
|
||||||
} else {
|
} else {
|
||||||
m->_state = rec->_state;
|
m->_state = rec->_state;
|
||||||
m->_current_mileage = rec->_current_mileage;
|
m->_invocation_counter = rec->_invocation_counter;
|
||||||
if (rec->_data_length != 0) {
|
if (rec->_data_length != 0) {
|
||||||
assert(m->_data_size + m->_extra_data_size == rec->_data_length * (int)sizeof(rec->_data[0]) ||
|
assert(m->_data_size + m->_extra_data_size == rec->_data_length * (int)sizeof(rec->_data[0]) ||
|
||||||
m->_data_size == rec->_data_length * (int)sizeof(rec->_data[0]), "must agree");
|
m->_data_size == rec->_data_length * (int)sizeof(rec->_data[0]), "must agree");
|
||||||
|
|
|
@ -131,4 +131,10 @@ class ciReplay {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Replay file format version history
|
||||||
|
// 0: legacy (no version number)
|
||||||
|
// 1: first instanceKlass sets protection domain (8275868)
|
||||||
|
// replace current_mileage with invocation_count (8276095)
|
||||||
|
#define REPLAY_VERSION 1 // current version, bump up for incompatible changes
|
||||||
|
|
||||||
#endif // SHARE_CI_CIREPLAY_HPP
|
#endif // SHARE_CI_CIREPLAY_HPP
|
||||||
|
|
|
@ -824,7 +824,6 @@
|
||||||
nonstatic_field(ciMethodData, _arg_local, intx) \
|
nonstatic_field(ciMethodData, _arg_local, intx) \
|
||||||
nonstatic_field(ciMethodData, _arg_stack, intx) \
|
nonstatic_field(ciMethodData, _arg_stack, intx) \
|
||||||
nonstatic_field(ciMethodData, _arg_returned, intx) \
|
nonstatic_field(ciMethodData, _arg_returned, intx) \
|
||||||
nonstatic_field(ciMethodData, _current_mileage, int) \
|
|
||||||
nonstatic_field(ciMethodData, _orig, MethodData::CompilerCounters) \
|
nonstatic_field(ciMethodData, _orig, MethodData::CompilerCounters) \
|
||||||
\
|
\
|
||||||
nonstatic_field(ciField, _holder, ciInstanceKlass*) \
|
nonstatic_field(ciField, _holder, ciInstanceKlass*) \
|
||||||
|
|
|
@ -46,13 +46,11 @@ public class ciMethodData extends ciMetadata implements MethodDataInterface<ciKl
|
||||||
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
|
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
|
||||||
Type type = db.lookupType("ciMethodData");
|
Type type = db.lookupType("ciMethodData");
|
||||||
origField = type.getField("_orig");
|
origField = type.getField("_orig");
|
||||||
currentMileageField = new CIntField(type.getCIntegerField("_current_mileage"), 0);
|
|
||||||
argReturnedField = new CIntField(type.getCIntegerField("_arg_returned"), 0);
|
argReturnedField = new CIntField(type.getCIntegerField("_arg_returned"), 0);
|
||||||
argStackField = new CIntField(type.getCIntegerField("_arg_stack"), 0);
|
argStackField = new CIntField(type.getCIntegerField("_arg_stack"), 0);
|
||||||
argLocalField = new CIntField(type.getCIntegerField("_arg_local"), 0);
|
argLocalField = new CIntField(type.getCIntegerField("_arg_local"), 0);
|
||||||
eflagsField = new CIntField(type.getCIntegerField("_eflags"), 0);
|
eflagsField = new CIntField(type.getCIntegerField("_eflags"), 0);
|
||||||
hintDiField = new CIntField(type.getCIntegerField("_hint_di"), 0);
|
hintDiField = new CIntField(type.getCIntegerField("_hint_di"), 0);
|
||||||
currentMileageField = new CIntField(type.getCIntegerField("_current_mileage"), 0);
|
|
||||||
dataField = type.getAddressField("_data");
|
dataField = type.getAddressField("_data");
|
||||||
extraDataSizeField = new CIntField(type.getCIntegerField("_extra_data_size"), 0);
|
extraDataSizeField = new CIntField(type.getCIntegerField("_extra_data_size"), 0);
|
||||||
dataSizeField = new CIntField(type.getCIntegerField("_data_size"), 0);
|
dataSizeField = new CIntField(type.getCIntegerField("_data_size"), 0);
|
||||||
|
@ -63,7 +61,6 @@ public class ciMethodData extends ciMetadata implements MethodDataInterface<ciKl
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Field origField;
|
private static Field origField;
|
||||||
private static CIntField currentMileageField;
|
|
||||||
private static CIntField argReturnedField;
|
private static CIntField argReturnedField;
|
||||||
private static CIntField argStackField;
|
private static CIntField argStackField;
|
||||||
private static CIntField argLocalField;
|
private static CIntField argLocalField;
|
||||||
|
@ -141,7 +138,7 @@ public class ciMethodData extends ciMetadata implements MethodDataInterface<ciKl
|
||||||
}
|
}
|
||||||
|
|
||||||
int currentMileage() {
|
int currentMileage() {
|
||||||
return (int)currentMileageField.getValue(getAddress());
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean outOfBounds(int dataIndex) {
|
boolean outOfBounds(int dataIndex) {
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
* @test
|
* @test
|
||||||
* @bug 8275670
|
* @bug 8275670
|
||||||
* @library / /test/lib
|
* @library / /test/lib
|
||||||
* @summary testing of ciReplay with inlining
|
* @summary testing of ciReplay with nested BoundMethodHandles
|
||||||
* @requires vm.flightRecorder != true & vm.compMode != "Xint" & vm.debug == true & vm.compiler2.enabled
|
* @requires vm.flightRecorder != true & vm.compMode != "Xint" & vm.debug == true & vm.compiler2.enabled
|
||||||
* @modules java.base/jdk.internal.misc
|
* @modules java.base/jdk.internal.misc
|
||||||
* @build sun.hotspot.WhiteBox
|
* @build sun.hotspot.WhiteBox
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue