4949#include " runtime/fieldDescriptor.inline.hpp"
5050#include " runtime/globals_extension.hpp"
5151#include " runtime/handles.inline.hpp"
52+ #include " runtime/jniHandles.inline.hpp"
5253#include " runtime/java.hpp"
5354#include " utilities/copy.hpp"
5455#include " utilities/macros.hpp"
@@ -90,6 +91,11 @@ typedef struct _ciMethodRecord {
9091int _backedge_counter;
9192} ciMethodRecord;
9293
94+ typedef struct _ciInstanceKlassRecord {
95+ const InstanceKlass* _klass;
96+ jobject _java_mirror;// Global handle to java mirror to prevent unloading
97+ } ciInstanceKlassRecord;
98+
9399typedef struct _ciInlineRecord {
94100const char * _klass_name;
95101const char * _method_name;
@@ -111,6 +117,7 @@ class CompileReplay : public StackObj {
111117
112118 GrowableArray<ciMethodRecord*> _ci_method_records;
113119 GrowableArray<ciMethodDataRecord*> _ci_method_data_records;
120+ GrowableArray<ciInstanceKlassRecord*> _ci_instance_klass_records;
114121
115122// Use pointer because we may need to return inline records
116123// without destroying them.
@@ -882,7 +889,7 @@ class CompileReplay : public StackObj {
882889// constant pool is the same length as 'length' and make sure the
883890// constant pool tags are in the same state.
884891void process_ciInstanceKlass (TRAPS) {
885- InstanceKlass* k = (InstanceKlass *)parse_klass (CHECK);
892+ InstanceKlass* k = (InstanceKlass*)parse_klass (CHECK);
886893if (k ==NULL ) {
887894return ;
888895 }
@@ -905,6 +912,7 @@ class CompileReplay : public StackObj {
905912 }else if (is_linked) {
906913 k->link_class (CHECK);
907914 }
915+ new_ciInstanceKlass (k);
908916 ConstantPool* cp = k->constants ();
909917if (length != cp->length ()) {
910918report_error (" constant pool length mismatch: wrong class files?" );
@@ -951,10 +959,10 @@ class CompileReplay : public StackObj {
951959break ;
952960
953961case JVM_CONSTANT_Class:
954- if (tag ==JVM_CONSTANT_Class ) {
955- } else if (tag == JVM_CONSTANT_UnresolvedClass) {
956- tty->print_cr (" Warning: entry was unresolved in the replay data" );
957- }else {
962+ if (tag ==JVM_CONSTANT_UnresolvedClass ) {
963+ Klass* k = cp-> klass_at (i, CHECK);
964+ tty->print_cr (" Warning: entry was unresolved in the replay data: %s " , k-> name ()-> as_utf8 () );
965+ }else if (tag != JVM_CONSTANT_Class) {
958966report_error (" Unexpected tag" );
959967return ;
960968 }
@@ -1132,6 +1140,28 @@ class CompileReplay : public StackObj {
11321140return NULL ;
11331141 }
11341142
1143+ // Create and initialize a record for a ciInstanceKlass which was present at replay dump time.
1144+ void new_ciInstanceKlass (const InstanceKlass* klass) {
1145+ ciInstanceKlassRecord* rec =NEW_RESOURCE_OBJ (ciInstanceKlassRecord);
1146+ rec->_klass = klass;
1147+ oop java_mirror = klass->java_mirror ();
1148+ Handleh_java_mirror (_thread, java_mirror);
1149+ rec->_java_mirror =JNIHandles::make_global (h_java_mirror);
1150+ _ci_instance_klass_records.append (rec);
1151+ }
1152+
1153+ // Check if a ciInstanceKlass was present at replay dump time for a klass.
1154+ ciInstanceKlassRecord*find_ciInstanceKlass (const InstanceKlass* klass) {
1155+ for (int i =0 ; i < _ci_instance_klass_records.length (); i++) {
1156+ ciInstanceKlassRecord* rec = _ci_instance_klass_records.at (i);
1157+ if (klass == rec->_klass ) {
1158+ // ciInstanceKlass for this klass was resolved.
1159+ return rec;
1160+ }
1161+ }
1162+ return NULL ;
1163+ }
1164+
11351165// Create and initialize a record for a ciMethodData
11361166 ciMethodDataRecord*new_ciMethodData (Method* method) {
11371167 ciMethodDataRecord* rec =NEW_RESOURCE_OBJ (ciMethodDataRecord);
@@ -1265,6 +1295,10 @@ void ciReplay::replay(TRAPS) {
12651295vm_exit (exit_code);
12661296}
12671297
1298+ bool ciReplay::no_replay_state () {
1299+ return replay_state ==NULL ;
1300+ }
1301+
12681302void *ciReplay::load_inline_data (ciMethod* method,int entry_bci,int comp_level) {
12691303if (FLAG_IS_DEFAULT (InlineDataFile)) {
12701304 tty->print_cr (" ERROR: no inline replay data file specified (use -XX:InlineDataFile=inline_pid12345.txt)." );
@@ -1336,7 +1370,7 @@ int ciReplay::replay_impl(TRAPS) {
13361370}
13371371
13381372void ciReplay::initialize (ciMethodData* m) {
1339- if (replay_state == NULL ) {
1373+ if (no_replay_state () ) {
13401374return ;
13411375 }
13421376
@@ -1390,7 +1424,7 @@ void ciReplay::initialize(ciMethodData* m) {
13901424
13911425
13921426bool ciReplay::should_not_inline (ciMethod* method) {
1393- if (replay_state == NULL ) {
1427+ if (no_replay_state () ) {
13941428return false ;
13951429 }
13961430 VM_ENTRY_MARK;
@@ -1427,7 +1461,7 @@ bool ciReplay::should_not_inline(void* data, ciMethod* method, int bci, int inli
14271461}
14281462
14291463void ciReplay::initialize (ciMethod* m) {
1430- if (replay_state == NULL ) {
1464+ if (no_replay_state () ) {
14311465return ;
14321466 }
14331467
@@ -1456,8 +1490,17 @@ void ciReplay::initialize(ciMethod* m) {
14561490 }
14571491}
14581492
1493+ void ciReplay::initialize (ciInstanceKlass* ci_ik, InstanceKlass* ik) {
1494+ assert (!no_replay_state ()," must have replay state" );
1495+
1496+ ASSERT_IN_VM;
1497+ ciInstanceKlassRecord* rec = replay_state->find_ciInstanceKlass (ik);
1498+ assert (rec !=NULL ," ciInstanceKlass must be whitelisted" );
1499+ ci_ik->_java_mirror = CURRENT_ENV->get_instance (JNIHandles::resolve (rec->_java_mirror ));
1500+ }
1501+
14591502bool ciReplay::is_loaded (Method* method) {
1460- if (replay_state == NULL ) {
1503+ if (no_replay_state () ) {
14611504return true ;
14621505 }
14631506
@@ -1467,6 +1510,16 @@ bool ciReplay::is_loaded(Method* method) {
14671510 ciMethodRecord* rec = replay_state->find_ciMethodRecord (method);
14681511return rec !=NULL ;
14691512}
1513+
1514+ bool ciReplay::is_klass_unresolved (const InstanceKlass* klass) {
1515+ if (no_replay_state ()) {
1516+ return false ;
1517+ }
1518+
1519+ // Check if klass is found on whitelist.
1520+ ciInstanceKlassRecord* rec = replay_state->find_ciInstanceKlass (klass);
1521+ return rec ==NULL ;
1522+ }
14701523#endif // PRODUCT
14711524
14721525oopciReplay::obj_field (oop obj, Symbol* name) {