1.1 --- a/src/share/vm/ci/ciInstanceKlass.cpp Fri Nov 09 08:36:17 2012 -0800 1.2 +++ b/src/share/vm/ci/ciInstanceKlass.cpp Mon Nov 12 14:03:53 2012 -0800 1.3 @@ -561,3 +561,114 @@ 1.4 } 1.5 return impl; 1.6 } 1.7 + 1.8 +// Utility class for printing of the contents of the static fields for 1.9 +// use by compilation replay. It only prints out the information that 1.10 +// could be consumed by the compiler, so for primitive types it prints 1.11 +// out the actual value. For Strings it's the actual string value. 1.12 +// For array types it it's first level array size since that's the 1.13 +// only value which statically unchangeable. For all other reference 1.14 +// types it simply prints out the dynamic type. 1.15 + 1.16 +class StaticFinalFieldPrinter : public FieldClosure { 1.17 + outputStream* _out; 1.18 + const char* _holder; 1.19 + public: 1.20 + StaticFinalFieldPrinter(outputStream* out, const char* holder) : 1.21 + _out(out), 1.22 + _holder(holder) { 1.23 + } 1.24 + void do_field(fieldDescriptor* fd) { 1.25 + if (fd->is_final() && !fd->has_initial_value()) { 1.26 + oop mirror = fd->field_holder()->java_mirror(); 1.27 + _out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii()); 1.28 + switch (fd->field_type()) { 1.29 + case T_BYTE: _out->print_cr("%d", mirror->byte_field(fd->offset())); break; 1.30 + case T_BOOLEAN: _out->print_cr("%d", mirror->bool_field(fd->offset())); break; 1.31 + case T_SHORT: _out->print_cr("%d", mirror->short_field(fd->offset())); break; 1.32 + case T_CHAR: _out->print_cr("%d", mirror->char_field(fd->offset())); break; 1.33 + case T_INT: _out->print_cr("%d", mirror->int_field(fd->offset())); break; 1.34 + case T_LONG: _out->print_cr(INT64_FORMAT, mirror->long_field(fd->offset())); break; 1.35 + case T_FLOAT: { 1.36 + float f = mirror->float_field(fd->offset()); 1.37 + _out->print_cr("%d", *(int*)&f); 1.38 + break; 1.39 + } 1.40 + case T_DOUBLE: { 1.41 + double d = mirror->double_field(fd->offset()); 1.42 + _out->print_cr(INT64_FORMAT, *(jlong*)&d); 1.43 + break; 1.44 + } 1.45 + case T_ARRAY: { 1.46 + oop value = mirror->obj_field_acquire(fd->offset()); 1.47 + if (value == NULL) { 1.48 + _out->print_cr("null"); 1.49 + } else { 1.50 + typeArrayOop ta = (typeArrayOop)value; 1.51 + _out->print("%d", ta->length()); 1.52 + if (value->is_objArray()) { 1.53 + objArrayOop oa = (objArrayOop)value; 1.54 + const char* klass_name = value->klass()->name()->as_quoted_ascii(); 1.55 + _out->print(" %s", klass_name); 1.56 + } 1.57 + _out->cr(); 1.58 + } 1.59 + break; 1.60 + } 1.61 + case T_OBJECT: { 1.62 + oop value = mirror->obj_field_acquire(fd->offset()); 1.63 + if (value == NULL) { 1.64 + _out->print_cr("null"); 1.65 + } else if (value->is_instance()) { 1.66 + if (value->is_a(SystemDictionary::String_klass())) { 1.67 + _out->print("\""); 1.68 + _out->print_raw(java_lang_String::as_quoted_ascii(value)); 1.69 + _out->print_cr("\""); 1.70 + } else { 1.71 + const char* klass_name = value->klass()->name()->as_quoted_ascii(); 1.72 + _out->print_cr(klass_name); 1.73 + } 1.74 + } else { 1.75 + ShouldNotReachHere(); 1.76 + } 1.77 + break; 1.78 + } 1.79 + default: 1.80 + ShouldNotReachHere(); 1.81 + } 1.82 + } 1.83 + } 1.84 +}; 1.85 + 1.86 + 1.87 +void ciInstanceKlass::dump_replay_data(outputStream* out) { 1.88 + ASSERT_IN_VM; 1.89 + InstanceKlass* ik = get_instanceKlass(); 1.90 + ConstantPool* cp = ik->constants(); 1.91 + 1.92 + // Try to record related loaded classes 1.93 + Klass* sub = ik->subklass(); 1.94 + while (sub != NULL) { 1.95 + if (sub->oop_is_instance()) { 1.96 + out->print_cr("instanceKlass %s", sub->name()->as_quoted_ascii()); 1.97 + } 1.98 + sub = sub->next_sibling(); 1.99 + } 1.100 + 1.101 + // Dump out the state of the constant pool tags. During replay the 1.102 + // tags will be validated for things which shouldn't change and 1.103 + // classes will be resolved if the tags indicate that they were 1.104 + // resolved at compile time. 1.105 + out->print("ciInstanceKlass %s %d %d %d", ik->name()->as_quoted_ascii(), 1.106 + is_linked(), is_initialized(), cp->length()); 1.107 + for (int index = 1; index < cp->length(); index++) { 1.108 + out->print(" %d", cp->tags()->at(index)); 1.109 + } 1.110 + out->cr(); 1.111 + if (is_initialized()) { 1.112 + // Dump out the static final fields in case the compilation relies 1.113 + // on their value for correct replay. 1.114 + StaticFinalFieldPrinter sffp(out, ik->name()->as_quoted_ascii()); 1.115 + ik->do_local_static_fields(&sffp); 1.116 + } 1.117 +}