--- old/src/share/vm/ci/ciInstanceKlass.cpp 2017-03-09 09:43:58.286633083 +0100 +++ new/src/share/vm/ci/ciInstanceKlass.cpp 2017-03-09 09:43:54.909635208 +0100 @@ -33,6 +33,7 @@ #include "memory/allocation.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/fieldStreams.hpp" +#include "oops/valueKlass.hpp" #include "runtime/fieldDescriptor.hpp" // ciInstanceKlass @@ -655,77 +656,122 @@ // only value which statically unchangeable. For all other reference // types it simply prints out the dynamic type. -class StaticFinalFieldPrinter : public FieldClosure { +class StaticFieldPrinter : public FieldClosure { + protected: outputStream* _out; + public: + StaticFieldPrinter(outputStream* out) : + _out(out) { + } + void do_field_helper(fieldDescriptor* fd, oop obj, bool flattened); +}; + +class StaticFinalFieldPrinter : public StaticFieldPrinter { const char* _holder; public: StaticFinalFieldPrinter(outputStream* out, const char* holder) : - _out(out), - _holder(holder) { + StaticFieldPrinter(out), _holder(holder) { } void do_field(fieldDescriptor* fd) { if (fd->is_final() && !fd->has_initial_value()) { ResourceMark rm; - oop mirror = fd->field_holder()->java_mirror(); + InstanceKlass* holder = fd->field_holder(); + oop mirror = holder->java_mirror(); _out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii()); - switch (fd->field_type()) { - case T_BYTE: _out->print_cr("%d", mirror->byte_field(fd->offset())); break; - case T_BOOLEAN: _out->print_cr("%d", mirror->bool_field(fd->offset())); break; - case T_SHORT: _out->print_cr("%d", mirror->short_field(fd->offset())); break; - case T_CHAR: _out->print_cr("%d", mirror->char_field(fd->offset())); break; - case T_INT: _out->print_cr("%d", mirror->int_field(fd->offset())); break; - case T_LONG: _out->print_cr(INT64_FORMAT, (int64_t)(mirror->long_field(fd->offset()))); break; - case T_FLOAT: { - float f = mirror->float_field(fd->offset()); - _out->print_cr("%d", *(int*)&f); - break; - } - case T_DOUBLE: { - double d = mirror->double_field(fd->offset()); - _out->print_cr(INT64_FORMAT, *(int64_t*)&d); - break; - } - case T_ARRAY: { - oop value = mirror->obj_field_acquire(fd->offset()); - if (value == NULL) { - _out->print_cr("null"); - } else { - typeArrayOop ta = (typeArrayOop)value; - _out->print("%d", ta->length()); - if (value->is_objArray()) { - objArrayOop oa = (objArrayOop)value; - const char* klass_name = value->klass()->name()->as_quoted_ascii(); - _out->print(" %s", klass_name); - } - _out->cr(); - } - break; - } - case T_OBJECT: { - oop value = mirror->obj_field_acquire(fd->offset()); - if (value == NULL) { - _out->print_cr("null"); - } else if (value->is_instance()) { - if (value->is_a(SystemDictionary::String_klass())) { - _out->print("\""); - _out->print_raw(java_lang_String::as_quoted_ascii(value)); - _out->print_cr("\""); - } else { - const char* klass_name = value->klass()->name()->as_quoted_ascii(); - _out->print_cr("%s", klass_name); - } - } else { - ShouldNotReachHere(); - } - break; - } - default: - ShouldNotReachHere(); - } + do_field_helper(fd, mirror, false); + _out->cr(); } } }; +class ValueTypeFieldPrinter : public StaticFieldPrinter { + oop _obj; + public: + ValueTypeFieldPrinter(outputStream* out, oop obj) : + StaticFieldPrinter(out), _obj(obj) { + } + void do_field(fieldDescriptor* fd) { + do_field_helper(fd, _obj, true); + _out->print(" "); + } +}; + +void StaticFieldPrinter::do_field_helper(fieldDescriptor* fd, oop mirror, bool flattened) { + switch (fd->field_type()) { + case T_BYTE: _out->print("%d", mirror->byte_field(fd->offset())); break; + case T_BOOLEAN: _out->print("%d", mirror->bool_field(fd->offset())); break; + case T_SHORT: _out->print("%d", mirror->short_field(fd->offset())); break; + case T_CHAR: _out->print("%d", mirror->char_field(fd->offset())); break; + case T_INT: _out->print("%d", mirror->int_field(fd->offset())); break; + case T_LONG: _out->print(INT64_FORMAT, (int64_t)(mirror->long_field(fd->offset()))); break; + case T_FLOAT: { + float f = mirror->float_field(fd->offset()); + _out->print("%d", *(int*)&f); + break; + } + case T_DOUBLE: { + double d = mirror->double_field(fd->offset()); + _out->print(INT64_FORMAT, *(int64_t*)&d); + break; + } + case T_ARRAY: { + oop value = mirror->obj_field_acquire(fd->offset()); + if (value == NULL) { + _out->print("null"); + } else { + typeArrayOop ta = (typeArrayOop)value; + _out->print("%d", ta->length()); + if (value->is_objArray()) { + objArrayOop oa = (objArrayOop)value; + const char* klass_name = value->klass()->name()->as_quoted_ascii(); + _out->print(" %s", klass_name); + } + } + break; + } + case T_OBJECT: { + oop value = mirror->obj_field_acquire(fd->offset()); + if (value == NULL) { + _out->print("null"); + } else if (value->is_instance()) { + if (value->is_a(SystemDictionary::String_klass())) { + _out->print("\""); + _out->print_raw(java_lang_String::as_quoted_ascii(value)); + _out->print("\""); + } else { + const char* klass_name = value->klass()->name()->as_quoted_ascii(); + _out->print("%s", klass_name); + } + } else { + ShouldNotReachHere(); + } + break; + } + case T_VALUETYPE: { + ResetNoHandleMark rnhm; + Thread* THREAD = Thread::current(); + SignatureStream ss(fd->signature(), false); + Symbol* name = ss.as_symbol(THREAD); + assert(!HAS_PENDING_EXCEPTION, "can resolve klass?"); + InstanceKlass* holder = fd->field_holder(); + Klass* k = SystemDictionary::find(name, Handle(holder->class_loader()), Handle(holder->protection_domain()), THREAD); + assert(k != NULL && !HAS_PENDING_EXCEPTION, "can resolve klass?"); + ValueKlass* vk = ValueKlass::cast(k); + oop obj; + if (flattened) { + int field_offset = fd->offset() - vk->first_field_offset(); + obj = (oop)((address)mirror + field_offset); + } else { + obj = mirror->obj_field_acquire(fd->offset()); + } + ValueTypeFieldPrinter print_field(_out, obj); + vk->do_nonstatic_fields(&print_field); + break; + } + default: + ShouldNotReachHere(); + } +} void ciInstanceKlass::dump_replay_data(outputStream* out) { ResourceMark rm;