< prev index next > src/hotspot/share/ci/ciReplay.cpp
Print this page
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "oops/constantPool.inline.hpp"
#include "oops/cpCache.inline.hpp"
#include "oops/fieldStreams.inline.hpp"
+ #include "oops/inlineKlass.inline.hpp"
#include "oops/klass.inline.hpp"
#include "oops/method.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/resolvedIndyEntry.hpp"
#include "prims/jvmtiExport.hpp"
tty->print_cr("Resolving klass %s at %d", cp->klass_name_at(i)->as_utf8(), i);
Klass* k = cp->klass_at(i, CHECK);
}
break;
}
+
case JVM_CONSTANT_Long:
case JVM_CONSTANT_Double:
parsed_two_word = i + 1;
case JVM_CONSTANT_ClassIndex:
}
}
}
! // staticfield <klass> <name> <signature> <value>
! //
! // 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
! // initializer.
! void process_staticfield(TRAPS) {
! InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK);
!
! if (k == nullptr || ReplaySuppressInitializers == 0 ||
! (ReplaySuppressInitializers == 2 && k->class_loader() == nullptr)) {
! skip_remaining();
! 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::new_symbol(field_name);
! Symbol* sig = SymbolTable::new_symbol(field_signature);
! 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 (field_signature[0] == JVM_SIGNATURE_ARRAY) {
int length = parse_int("array length");
oop value = nullptr;
if (field_signature[1] == JVM_SIGNATURE_ARRAY) {
// multi dimensional array
! ArrayKlass* kelem = (ArrayKlass *)parse_klass(CHECK);
! if (kelem == nullptr) {
- return;
- }
int rank = 0;
while (field_signature[rank] == JVM_SIGNATURE_ARRAY) {
rank++;
}
jint* dims = NEW_RESOURCE_ARRAY(jint, rank);
dims[0] = length;
for (int i = 1; i < rank; i++) {
dims[i] = 1; // These aren't relevant to the compiler
}
! value = kelem->multi_allocate(rank, dims, CHECK);
} else {
if (strcmp(field_signature, "[B") == 0) {
! value = oopFactory::new_byteArray(length, CHECK);
} else if (strcmp(field_signature, "[Z") == 0) {
! value = oopFactory::new_boolArray(length, CHECK);
} else if (strcmp(field_signature, "[C") == 0) {
! value = oopFactory::new_charArray(length, CHECK);
} else if (strcmp(field_signature, "[S") == 0) {
! value = oopFactory::new_shortArray(length, CHECK);
} else if (strcmp(field_signature, "[F") == 0) {
! value = oopFactory::new_floatArray(length, CHECK);
} else if (strcmp(field_signature, "[D") == 0) {
! value = oopFactory::new_doubleArray(length, CHECK);
} else if (strcmp(field_signature, "[I") == 0) {
! value = oopFactory::new_intArray(length, CHECK);
} else if (strcmp(field_signature, "[J") == 0) {
! value = oopFactory::new_longArray(length, CHECK);
} else if (field_signature[0] == JVM_SIGNATURE_ARRAY &&
field_signature[1] == JVM_SIGNATURE_CLASS) {
! parse_klass(CHECK); // eat up the array class name
! Klass* kelem = resolve_klass(field_signature + 1, CHECK);
! value = oopFactory::new_objArray(kelem, length, CHECK);
} else {
report_error("unhandled array staticfield");
}
}
java_mirror->obj_field_put(fd.offset(), value);
} else {
! const char* string_value = parse_escaped_string();
! 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] == JVM_SIGNATURE_CLASS) {
- Klass* k = resolve_klass(string_value, CHECK);
- oop value = InstanceKlass::cast(k)->allocate_instance(CHECK);
- java_mirror->obj_field_put(fd.offset(), value);
- } else {
report_error("unhandled staticfield");
}
}
}
}
}
}
! class InlineTypeFieldInitializer : public FieldClosure {
! oop _vt;
! CompileReplay* _replay;
! public:
! InlineTypeFieldInitializer(oop vt, CompileReplay* replay)
! : _vt(vt), _replay(replay) {}
!
! void do_field(fieldDescriptor* fd) {
! BasicType bt = fd->field_type();
! const char* string_value = fd->is_null_free_inline_type() ? nullptr : _replay->parse_escaped_string();
! switch (bt) {
! case T_BYTE: {
! int value = atoi(string_value);
! _vt->byte_field_put(fd->offset(), value);
! break;
! }
! case T_BOOLEAN: {
! int value = atoi(string_value);
! _vt->bool_field_put(fd->offset(), value);
! break;
! }
! case T_SHORT: {
! int value = atoi(string_value);
! _vt->short_field_put(fd->offset(), value);
! break;
! }
! case T_CHAR: {
+ int value = atoi(string_value);
+ _vt->char_field_put(fd->offset(), value);
+ break;
+ }
+ case T_INT: {
+ int value = atoi(string_value);
+ _vt->int_field_put(fd->offset(), value);
+ break;
+ }
+ case T_LONG: {
+ jlong value;
+ if (sscanf(string_value, JLONG_FORMAT, &value) != 1) {
+ fprintf(stderr, "Error parsing long: %s\n", string_value);
+ break;
+ }
+ _vt->long_field_put(fd->offset(), value);
+ break;
+ }
+ case T_FLOAT: {
+ float value = atof(string_value);
+ _vt->float_field_put(fd->offset(), value);
+ break;
+ }
+ case T_DOUBLE: {
+ double value = atof(string_value);
+ _vt->double_field_put(fd->offset(), value);
+ break;
+ }
+ case T_ARRAY:
+ case T_OBJECT:
+ if (!fd->is_null_free_inline_type()) {
+ JavaThread* THREAD = JavaThread::current();
+ bool res = _replay->process_staticfield_reference(string_value, _vt, fd, THREAD);
+ assert(res, "should succeed for arrays & objects");
+ break;
+ } else {
+ InlineKlass* vk = InlineKlass::cast(fd->field_holder()->get_inline_type_field_klass(fd->index()));
+ if (fd->is_flat()) {
+ int field_offset = fd->offset() - vk->first_field_offset();
+ oop obj = cast_to_oop(cast_from_oop<address>(_vt) + field_offset);
+ InlineTypeFieldInitializer init_fields(obj, _replay);
+ vk->do_nonstatic_fields(&init_fields);
+ } else {
+ oop value = vk->allocate_instance(JavaThread::current());
+ _vt->obj_field_put(fd->offset(), value);
+ }
+ break;
+ }
+ default: {
+ fatal("Unhandled type: %s", type2name(bt));
+ }
+ }
}
+ };
! bool process_staticfield_reference(const char* field_signature, oop java_mirror, fieldDescriptor* fd, TRAPS) {
if (field_signature[0] == JVM_SIGNATURE_ARRAY) {
int length = parse_int("array length");
oop value = nullptr;
if (field_signature[1] == JVM_SIGNATURE_ARRAY) {
// multi dimensional array
! Klass* k = resolve_klass(field_signature, CHECK_(true));
! ArrayKlass* kelem = (ArrayKlass *)k;
int rank = 0;
while (field_signature[rank] == JVM_SIGNATURE_ARRAY) {
rank++;
}
jint* dims = NEW_RESOURCE_ARRAY(jint, rank);
dims[0] = length;
for (int i = 1; i < rank; i++) {
dims[i] = 1; // These aren't relevant to the compiler
}
! value = kelem->multi_allocate(rank, dims, CHECK_(true));
} else {
if (strcmp(field_signature, "[B") == 0) {
! value = oopFactory::new_byteArray(length, CHECK_(true));
} else if (strcmp(field_signature, "[Z") == 0) {
! value = oopFactory::new_boolArray(length, CHECK_(true));
} else if (strcmp(field_signature, "[C") == 0) {
! value = oopFactory::new_charArray(length, CHECK_(true));
} else if (strcmp(field_signature, "[S") == 0) {
! value = oopFactory::new_shortArray(length, CHECK_(true));
} else if (strcmp(field_signature, "[F") == 0) {
! value = oopFactory::new_floatArray(length, CHECK_(true));
} else if (strcmp(field_signature, "[D") == 0) {
! value = oopFactory::new_doubleArray(length, CHECK_(true));
} else if (strcmp(field_signature, "[I") == 0) {
! value = oopFactory::new_intArray(length, CHECK_(true));
} else if (strcmp(field_signature, "[J") == 0) {
! value = oopFactory::new_longArray(length, CHECK_(true));
} else if (field_signature[0] == JVM_SIGNATURE_ARRAY &&
field_signature[1] == JVM_SIGNATURE_CLASS) {
! Klass* kelem = resolve_klass(field_signature + 1, CHECK_(true));
! parse_klass(CHECK_(true)); // eat up the array class name
! value = oopFactory::new_objArray(kelem, length, CHECK_(true));
+ } else if (field_signature[0] == JVM_SIGNATURE_ARRAY) {
+ Klass* kelem = resolve_klass(field_signature + 1, CHECK_(true));
+ parse_klass(CHECK_(true)); // eat up the array class name
+ value = oopFactory::new_valueArray(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') {
+ const char* instance = parse_escaped_string();
+ Klass* k = resolve_klass(instance, 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
+ // initializer.
+ void process_staticfield(TRAPS) {
+ InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK);
+
+ if (k == nullptr || ReplaySuppressInitializers == 0 ||
+ (ReplaySuppressInitializers == 2 && k->class_loader() == nullptr)) {
+ skip_remaining();
+ 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::new_symbol(field_name);
+ Symbol* sig = SymbolTable::new_symbol(field_signature);
+ 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 (fd.is_null_free_inline_type()) {
+ Klass* kelem = resolve_klass(field_signature, CHECK);
+ InlineKlass* vk = InlineKlass::cast(kelem);
+ oop value = vk->allocate_instance(CHECK);
+ InlineTypeFieldInitializer 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");
}
}
}
< prev index next >