--- old/src/share/vm/ci/ciInstanceKlass.cpp 2017-06-01 17:15:35.035154274 +0200 +++ new/src/share/vm/ci/ciInstanceKlass.cpp 2017-06-01 17:15:30.903159524 +0200 @@ -704,7 +704,11 @@ ResourceMark rm; 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()); + _out->print("staticfield %s %s ", _holder, fd->name()->as_quoted_ascii()); + BasicType bt = fd->field_type(); + if (bt != T_OBJECT && bt != T_ARRAY) { + _out->print("%s ", fd->signature()->as_quoted_ascii()); + } do_field_helper(fd, mirror, false); _out->cr(); } @@ -724,8 +728,9 @@ }; void StaticFieldPrinter::do_field_helper(fieldDescriptor* fd, oop mirror, bool flattened) { - switch (fd->field_type()) { - case T_BYTE: _out->print_cr("%d", mirror->byte_field(fd->offset())); break; + BasicType bt = fd->field_type(); + switch (bt) { + 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; @@ -741,36 +746,23 @@ _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_ARRAY: 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 { + _out->print("%s", value->klass()->signature_name()); + if (value->is_array()) { + _out->print(" %d", ((arrayOop)value)->length()); } else { - const char* klass_name = value->klass()->name()->as_quoted_ascii(); - _out->print("%s", klass_name); + assert(value->is_instance() && bt == T_OBJECT, "what else?"); + if (value->is_a(SystemDictionary::String_klass())) { + _out->print(" \""); + _out->print_raw(java_lang_String::as_quoted_ascii(value)); + _out->print("\""); + } } - } else { - ShouldNotReachHere(); } break; } --- old/src/share/vm/ci/ciReplay.cpp 2017-06-01 17:15:39.347148659 +0200 +++ new/src/share/vm/ci/ciReplay.cpp 2017-06-01 17:15:35.093154199 +0200 @@ -794,11 +794,12 @@ break; } case T_ARRAY: - _replay->report_error("Array in value type unsupported"); - break; - case T_OBJECT: - _replay->report_error("Object in value type unsupported"); + case T_OBJECT: { + Thread* THREAD = Thread::current(); + bool res = _replay->process_staticfield_reference(string_value, _vt, fd, THREAD); + assert(res, "should succeed for arrays & objects"); break; + } case T_VALUETYPE: { Thread* THREAD = Thread::current(); SignatureStream ss(fd->signature(), false); @@ -818,40 +819,15 @@ } }; - // Initialize a class and fill in the value for a static field. - // This is useful when the compile was dependent on the value of - // static fields but it's impossible to properly rerun the static - // initiailizer. - void process_staticfield(TRAPS) { - InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK); - - if (ReplaySuppressInitializers == 0 || - ReplaySuppressInitializers == 2 && k->class_loader() == NULL) { - return; - } - - assert(k->is_initialized(), "must be"); - - const char* field_name = parse_escaped_string(); - const char* field_signature = parse_string(); - fieldDescriptor fd; - Symbol* name = SymbolTable::lookup(field_name, (int)strlen(field_name), CHECK); - Symbol* sig = SymbolTable::lookup(field_signature, (int)strlen(field_signature), CHECK); - if (!k->find_local_field(name, sig, &fd) || - !fd.is_static() || - fd.has_initial_value()) { - report_error(field_name); - return; - } - - oop java_mirror = k->java_mirror(); + bool process_staticfield_reference(const char* field_signature, oop java_mirror, fieldDescriptor* fd, TRAPS) { if (field_signature[0] == '[') { int length = parse_int("array length"); oop value = NULL; if (field_signature[1] == '[') { // multi dimensional array - ArrayKlass* kelem = (ArrayKlass *)parse_klass(CHECK); + Klass* k = resolve_klass(field_signature, CHECK_(true)); + ArrayKlass* kelem = (ArrayKlass *)k; int rank = 0; while (field_signature[rank] == '[') { rank++; @@ -861,86 +837,124 @@ for (int i = 1; i < rank; i++) { dims[i] = 1; // These aren't relevant to the compiler } - value = kelem->multi_allocate(rank, dims, CHECK); + value = kelem->multi_allocate(rank, dims, CHECK_(true)); } else { if (strcmp(field_signature, "[B") == 0) { - value = oopFactory::new_byteArray(length, CHECK); + value = oopFactory::new_byteArray(length, CHECK_(true)); } else if (strcmp(field_signature, "[Z") == 0) { - value = oopFactory::new_boolArray(length, CHECK); + value = oopFactory::new_boolArray(length, CHECK_(true)); } else if (strcmp(field_signature, "[C") == 0) { - value = oopFactory::new_charArray(length, CHECK); + value = oopFactory::new_charArray(length, CHECK_(true)); } else if (strcmp(field_signature, "[S") == 0) { - value = oopFactory::new_shortArray(length, CHECK); + value = oopFactory::new_shortArray(length, CHECK_(true)); } else if (strcmp(field_signature, "[F") == 0) { - value = oopFactory::new_singleArray(length, CHECK); + value = oopFactory::new_singleArray(length, CHECK_(true)); } else if (strcmp(field_signature, "[D") == 0) { - value = oopFactory::new_doubleArray(length, CHECK); + value = oopFactory::new_doubleArray(length, CHECK_(true)); } else if (strcmp(field_signature, "[I") == 0) { - value = oopFactory::new_intArray(length, CHECK); + value = oopFactory::new_intArray(length, CHECK_(true)); } else if (strcmp(field_signature, "[J") == 0) { - value = oopFactory::new_longArray(length, CHECK); + value = oopFactory::new_longArray(length, CHECK_(true)); } else if (field_signature[0] == '[' && field_signature[1] == 'L') { - Klass* kelem = resolve_klass(field_signature + 1, CHECK); - value = oopFactory::new_objArray(kelem, length, CHECK); + Klass* kelem = resolve_klass(field_signature + 1, CHECK_(true)); + value = oopFactory::new_objArray(kelem, length, CHECK_(true)); } else { report_error("unhandled array staticfield"); } } + java_mirror->obj_field_put(fd->offset(), value); + return true; + } else if (strcmp(field_signature, "Ljava/lang/String;") == 0) { + const char* string_value = parse_escaped_string(); + Handle value = java_lang_String::create_from_str(string_value, CHECK_(true)); + java_mirror->obj_field_put(fd->offset(), value()); + return true; + } else if (field_signature[0] == 'L') { + Klass* k = resolve_klass(field_signature, CHECK_(true)); + oop value = InstanceKlass::cast(k)->allocate_instance(CHECK_(true)); + java_mirror->obj_field_put(fd->offset(), value); + return true; + } + return false; + } + + // Initialize a class and fill in the value for a static field. + // This is useful when the compile was dependent on the value of + // static fields but it's impossible to properly rerun the static + // initiailizer. + void process_staticfield(TRAPS) { + InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK); + + if (ReplaySuppressInitializers == 0 || + ReplaySuppressInitializers == 2 && k->class_loader() == NULL) { + return; + } + + assert(k->is_initialized(), "must be"); + + const char* field_name = parse_escaped_string(); + const char* field_signature = parse_string(); + fieldDescriptor fd; + Symbol* name = SymbolTable::lookup(field_name, (int)strlen(field_name), CHECK); + Symbol* sig = SymbolTable::lookup(field_signature, (int)strlen(field_signature), CHECK); + if (!k->find_local_field(name, sig, &fd) || + !fd.is_static() || + fd.has_initial_value()) { + report_error(field_name); + return; + } + + oop java_mirror = k->java_mirror(); + if (strcmp(field_signature, "I") == 0) { + const char* string_value = parse_escaped_string(); + int value = atoi(string_value); + java_mirror->int_field_put(fd.offset(), value); + } else if (strcmp(field_signature, "B") == 0) { + const char* string_value = parse_escaped_string(); + int value = atoi(string_value); + java_mirror->byte_field_put(fd.offset(), value); + } else if (strcmp(field_signature, "C") == 0) { + const char* string_value = parse_escaped_string(); + int value = atoi(string_value); + java_mirror->char_field_put(fd.offset(), value); + } else if (strcmp(field_signature, "S") == 0) { + const char* string_value = parse_escaped_string(); + int value = atoi(string_value); + java_mirror->short_field_put(fd.offset(), value); + } else if (strcmp(field_signature, "Z") == 0) { + const char* string_value = parse_escaped_string(); + int value = atoi(string_value); + java_mirror->bool_field_put(fd.offset(), value); + } else if (strcmp(field_signature, "J") == 0) { + const char* string_value = parse_escaped_string(); + jlong value; + if (sscanf(string_value, JLONG_FORMAT, &value) != 1) { + fprintf(stderr, "Error parsing long: %s\n", string_value); + return; + } + java_mirror->long_field_put(fd.offset(), value); + } else if (strcmp(field_signature, "F") == 0) { + const char* string_value = parse_escaped_string(); + float value = atof(string_value); + java_mirror->float_field_put(fd.offset(), value); + } else if (strcmp(field_signature, "D") == 0) { + const char* string_value = parse_escaped_string(); + double value = atof(string_value); + java_mirror->double_field_put(fd.offset(), value); + } else if (field_signature[0] == 'Q') { + Symbol* klass_name = SymbolTable::lookup(field_signature, (int)strlen(field_signature), CHECK); + Klass* kelem = resolve_klass(field_signature, CHECK); + ValueKlass* vk = ValueKlass::cast(kelem); + oop value = vk->allocate_instance(CHECK); + ValueTypeFieldInitializer init_fields(value, this); + vk->do_nonstatic_fields(&init_fields); + if (HAS_PENDING_EXCEPTION) { + return; + } java_mirror->obj_field_put(fd.offset(), value); } else { - const char* string_value = field_signature[0] != 'Q' ? parse_escaped_string() : NULL; - if (strcmp(field_signature, "I") == 0) { - int value = atoi(string_value); - java_mirror->int_field_put(fd.offset(), value); - } else if (strcmp(field_signature, "B") == 0) { - int value = atoi(string_value); - java_mirror->byte_field_put(fd.offset(), value); - } else if (strcmp(field_signature, "C") == 0) { - int value = atoi(string_value); - java_mirror->char_field_put(fd.offset(), value); - } else if (strcmp(field_signature, "S") == 0) { - int value = atoi(string_value); - java_mirror->short_field_put(fd.offset(), value); - } else if (strcmp(field_signature, "Z") == 0) { - int value = atoi(string_value); - java_mirror->bool_field_put(fd.offset(), value); - } else if (strcmp(field_signature, "J") == 0) { - jlong value; - if (sscanf(string_value, JLONG_FORMAT, &value) != 1) { - fprintf(stderr, "Error parsing long: %s\n", string_value); - return; - } - java_mirror->long_field_put(fd.offset(), value); - } else if (strcmp(field_signature, "F") == 0) { - float value = atof(string_value); - java_mirror->float_field_put(fd.offset(), value); - } else if (strcmp(field_signature, "D") == 0) { - double value = atof(string_value); - java_mirror->double_field_put(fd.offset(), value); - } else if (strcmp(field_signature, "Ljava/lang/String;") == 0) { - Handle value = java_lang_String::create_from_str(string_value, CHECK); - java_mirror->obj_field_put(fd.offset(), value()); - } else if (field_signature[0] == 'L') { - Klass* k = resolve_klass(string_value, CHECK); - oop value = InstanceKlass::cast(k)->allocate_instance(CHECK); - java_mirror->obj_field_put(fd.offset(), value); - } else if (field_signature[0] == 'Q') { - Symbol* klass_name = SymbolTable::lookup(field_signature, (int)strlen(field_signature), CHECK); - Klass* kelem = resolve_klass(field_signature, CHECK); - ValueKlass* vk = ValueKlass::cast(kelem); - oop value = vk->allocate_instance(CHECK); - ValueTypeFieldInitializer init_fields(value, this); - vk->do_nonstatic_fields(&init_fields); - java_mirror->obj_field_put(fd.offset(), value); - } else if (field_signature[0] == 'Q') { - Symbol* klass_name = SymbolTable::lookup(field_signature, (int)strlen(field_signature), CHECK); - Klass* kelem = resolve_klass(field_signature, CHECK); - ValueKlass* vk = ValueKlass::cast(kelem); - oop value = vk->allocate_instance(CHECK); - ValueTypeFieldInitializer init_fields(value, this); - vk->do_nonstatic_fields(&init_fields); - java_mirror->obj_field_put(fd.offset(), value); - } else { + bool res = process_staticfield_reference(field_signature, java_mirror, &fd, CHECK); + if (!res) { report_error("unhandled staticfield"); } }