24
25 #include "ci/ciKlass.hpp"
26 #include "ci/ciMethodData.hpp"
27 #include "ci/ciReplay.hpp"
28 #include "ci/ciSymbol.hpp"
29 #include "ci/ciUtilities.inline.hpp"
30 #include "classfile/javaClasses.hpp"
31 #include "classfile/symbolTable.hpp"
32 #include "classfile/systemDictionary.hpp"
33 #include "compiler/compilationPolicy.hpp"
34 #include "compiler/compileBroker.hpp"
35 #include "compiler/compilerDefinitions.inline.hpp"
36 #include "interpreter/linkResolver.hpp"
37 #include "jvm.h"
38 #include "memory/allocation.inline.hpp"
39 #include "memory/oopFactory.hpp"
40 #include "memory/resourceArea.hpp"
41 #include "oops/constantPool.inline.hpp"
42 #include "oops/cpCache.inline.hpp"
43 #include "oops/fieldStreams.inline.hpp"
44 #include "oops/klass.inline.hpp"
45 #include "oops/method.inline.hpp"
46 #include "oops/oop.inline.hpp"
47 #include "oops/resolvedIndyEntry.hpp"
48 #include "prims/jvmtiExport.hpp"
49 #include "prims/methodHandles.hpp"
50 #include "runtime/fieldDescriptor.inline.hpp"
51 #include "runtime/globals_extension.hpp"
52 #include "runtime/handles.inline.hpp"
53 #include "runtime/java.hpp"
54 #include "runtime/jniHandles.inline.hpp"
55 #include "runtime/threads.hpp"
56 #include "utilities/copy.hpp"
57 #include "utilities/macros.hpp"
58 #include "utilities/utf8.hpp"
59
60 // ciReplay
61
62 typedef struct _ciMethodDataRecord {
63 const char* _klass_name;
494 return nullptr;
495 }
496 if (strcmp(field, ";") == 0) {
497 break;
498 }
499 // raw Method*
500 if (strcmp(field, "<vmtarget>") == 0) {
501 Method* vmtarget = java_lang_invoke_MemberName::vmtarget(obj);
502 k = (vmtarget == nullptr) ? nullptr : vmtarget->method_holder();
503 if (k == nullptr) {
504 report_error("null vmtarget found");
505 return nullptr;
506 }
507 if (!parse_terminator()) {
508 report_error("missing terminator");
509 return nullptr;
510 }
511 return k;
512 }
513 obj = ciReplay::obj_field(obj, field);
514 // array
515 if (obj != nullptr && obj->is_objArray()) {
516 objArrayOop arr = (objArrayOop)obj;
517 int index = parse_int("index");
518 if (index >= arr->length()) {
519 report_error("bad array index");
520 return nullptr;
521 }
522 obj = arr->obj_at(index);
523 }
524 } while (obj != nullptr);
525 if (obj == nullptr) {
526 report_error("null field found");
527 return nullptr;
528 }
529 k = obj->klass();
530 return k;
531 }
532
533 // Parse a valid klass name and look it up
534 // syntax: <name>
845
846 rec->_orig_data = parse_data("orig", rec->_orig_data_length);
847 if (rec->_orig_data == nullptr) {
848 return;
849 }
850 rec->_data = parse_intptr_data("data", rec->_data_length);
851 if (rec->_data == nullptr) {
852 return;
853 }
854 if (!parse_tag_and_count("oops", rec->_classes_length)) {
855 return;
856 }
857 rec->_classes = NEW_RESOURCE_ARRAY(Klass*, rec->_classes_length);
858 rec->_classes_offsets = NEW_RESOURCE_ARRAY(int, rec->_classes_length);
859 for (int i = 0; i < rec->_classes_length; i++) {
860 int offset = parse_int("offset");
861 if (had_error()) {
862 return;
863 }
864 Klass* k = parse_klass(CHECK);
865 rec->_classes_offsets[i] = offset;
866 rec->_classes[i] = k;
867 }
868
869 if (!parse_tag_and_count("methods", rec->_methods_length)) {
870 return;
871 }
872 rec->_methods = NEW_RESOURCE_ARRAY(Method*, rec->_methods_length);
873 rec->_methods_offsets = NEW_RESOURCE_ARRAY(int, rec->_methods_length);
874 for (int i = 0; i < rec->_methods_length; i++) {
875 int offset = parse_int("offset");
876 if (had_error()) {
877 return;
878 }
879 Method* m = parse_method(CHECK);
880 rec->_methods_offsets[i] = offset;
881 rec->_methods[i] = m;
882 }
883 }
884
885 // instanceKlass <name>
886 // instanceKlass <constant pool ref> # <original hidden class name>
887 //
888 // Loads and initializes the klass 'name'. This can be used to
889 // create particular class loading environments
890 void process_instanceKlass(TRAPS) {
891 // just load the referenced class
892 Klass* k = parse_klass(CHECK);
893
894 if (k == nullptr) {
895 return;
896 }
897 const char* comment = parse_string();
898 bool is_comment = comment != nullptr && strcmp(comment, "#") == 0;
899 if (k->is_hidden() != is_comment) {
900 report_error("hidden class with comment expected");
901 return;
902 }
903 // comment, print or ignore
904 if (is_comment) {
944 ConstantPool* cp = k->constants();
945 if (length != cp->length()) {
946 report_error("constant pool length mismatch: wrong class files?");
947 return;
948 }
949
950 int parsed_two_word = 0;
951 for (int i = 1; i < length; i++) {
952 int tag = parse_int("tag");
953 if (had_error()) {
954 return;
955 }
956 switch (cp->tag_at(i).value()) {
957 case JVM_CONSTANT_UnresolvedClass: {
958 if (tag == JVM_CONSTANT_Class) {
959 tty->print_cr("Resolving klass %s at %d", cp->klass_name_at(i)->as_utf8(), i);
960 Klass* k = cp->klass_at(i, CHECK);
961 }
962 break;
963 }
964 case JVM_CONSTANT_Long:
965 case JVM_CONSTANT_Double:
966 parsed_two_word = i + 1;
967
968 case JVM_CONSTANT_ClassIndex:
969 case JVM_CONSTANT_StringIndex:
970 case JVM_CONSTANT_String:
971 case JVM_CONSTANT_UnresolvedClassInError:
972 case JVM_CONSTANT_Fieldref:
973 case JVM_CONSTANT_Methodref:
974 case JVM_CONSTANT_InterfaceMethodref:
975 case JVM_CONSTANT_NameAndType:
976 case JVM_CONSTANT_Utf8:
977 case JVM_CONSTANT_Integer:
978 case JVM_CONSTANT_Float:
979 case JVM_CONSTANT_MethodHandle:
980 case JVM_CONSTANT_MethodType:
981 case JVM_CONSTANT_Dynamic:
982 case JVM_CONSTANT_InvokeDynamic:
983 if (tag != cp->tag_at(i).value()) {
990 if (tag == JVM_CONSTANT_UnresolvedClass) {
991 Klass* k = cp->klass_at(i, CHECK);
992 tty->print_cr("Warning: entry was unresolved in the replay data: %s", k->name()->as_utf8());
993 } else if (tag != JVM_CONSTANT_Class) {
994 report_error("Unexpected tag");
995 return;
996 }
997 break;
998
999 case 0:
1000 if (parsed_two_word == i) continue;
1001
1002 default:
1003 fatal("Unexpected tag: %d", cp->tag_at(i).value());
1004 break;
1005 }
1006
1007 }
1008 }
1009
1010 // staticfield <klass> <name> <signature> <value>
1011 //
1012 // Initialize a class and fill in the value for a static field.
1013 // This is useful when the compile was dependent on the value of
1014 // static fields but it's impossible to properly rerun the static
1015 // initializer.
1016 void process_staticfield(TRAPS) {
1017 InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK);
1018
1019 if (k == nullptr || ReplaySuppressInitializers == 0 ||
1020 (ReplaySuppressInitializers == 2 && k->class_loader() == nullptr)) {
1021 skip_remaining();
1022 return;
1023 }
1024
1025 assert(k->is_initialized(), "must be");
1026
1027 const char* field_name = parse_escaped_string();
1028 const char* field_signature = parse_string();
1029 fieldDescriptor fd;
1030 Symbol* name = SymbolTable::new_symbol(field_name);
1031 Symbol* sig = SymbolTable::new_symbol(field_signature);
1032 if (!k->find_local_field(name, sig, &fd) ||
1033 !fd.is_static() ||
1034 fd.has_initial_value()) {
1035 report_error(field_name);
1036 return;
1037 }
1038
1039 oop java_mirror = k->java_mirror();
1040 if (field_signature[0] == JVM_SIGNATURE_ARRAY) {
1041 int length = parse_int("array length");
1042 oop value = nullptr;
1043
1044 if (length != -1) {
1045 if (field_signature[1] == JVM_SIGNATURE_ARRAY) {
1046 // multi dimensional array
1047 ArrayKlass* kelem = (ArrayKlass *)parse_klass(CHECK);
1048 if (kelem == nullptr) {
1049 return;
1050 }
1051 int rank = 0;
1052 while (field_signature[rank] == JVM_SIGNATURE_ARRAY) {
1053 rank++;
1054 }
1055 jint* dims = NEW_RESOURCE_ARRAY(jint, rank);
1056 dims[0] = length;
1057 for (int i = 1; i < rank; i++) {
1058 dims[i] = 1; // These aren't relevant to the compiler
1059 }
1060 value = kelem->multi_allocate(rank, dims, CHECK);
1061 } else {
1062 if (strcmp(field_signature, "[B") == 0) {
1063 value = oopFactory::new_byteArray(length, CHECK);
1064 } else if (strcmp(field_signature, "[Z") == 0) {
1065 value = oopFactory::new_boolArray(length, CHECK);
1066 } else if (strcmp(field_signature, "[C") == 0) {
1067 value = oopFactory::new_charArray(length, CHECK);
1068 } else if (strcmp(field_signature, "[S") == 0) {
1069 value = oopFactory::new_shortArray(length, CHECK);
1070 } else if (strcmp(field_signature, "[F") == 0) {
1071 value = oopFactory::new_floatArray(length, CHECK);
1072 } else if (strcmp(field_signature, "[D") == 0) {
1073 value = oopFactory::new_doubleArray(length, CHECK);
1074 } else if (strcmp(field_signature, "[I") == 0) {
1075 value = oopFactory::new_intArray(length, CHECK);
1076 } else if (strcmp(field_signature, "[J") == 0) {
1077 value = oopFactory::new_longArray(length, CHECK);
1078 } else if (field_signature[0] == JVM_SIGNATURE_ARRAY &&
1079 field_signature[1] == JVM_SIGNATURE_CLASS) {
1080 Klass* actual_array_klass = parse_klass(CHECK);
1081 Klass* kelem = ObjArrayKlass::cast(actual_array_klass)->element_klass();
1082 value = oopFactory::new_objArray(kelem, length, CHECK);
1083 } else {
1084 report_error("unhandled array staticfield");
1085 }
1086 }
1087 }
1088 java_mirror->obj_field_put(fd.offset(), value);
1089 } else {
1090 const char* string_value = parse_escaped_string();
1091 if (strcmp(field_signature, "I") == 0) {
1092 int value = atoi(string_value);
1093 java_mirror->int_field_put(fd.offset(), value);
1094 } else if (strcmp(field_signature, "B") == 0) {
1095 int value = atoi(string_value);
1096 java_mirror->byte_field_put(fd.offset(), value);
1097 } else if (strcmp(field_signature, "C") == 0) {
1098 int value = atoi(string_value);
1099 java_mirror->char_field_put(fd.offset(), value);
1100 } else if (strcmp(field_signature, "S") == 0) {
1101 int value = atoi(string_value);
1102 java_mirror->short_field_put(fd.offset(), value);
1103 } else if (strcmp(field_signature, "Z") == 0) {
1104 int value = atoi(string_value);
1105 java_mirror->bool_field_put(fd.offset(), value);
1106 } else if (strcmp(field_signature, "J") == 0) {
1107 jlong value;
1108 if (sscanf(string_value, JLONG_FORMAT, &value) != 1) {
1109 fprintf(stderr, "Error parsing long: %s\n", string_value);
1110 return;
1111 }
1112 java_mirror->long_field_put(fd.offset(), value);
1113 } else if (strcmp(field_signature, "F") == 0) {
1114 float value = atof(string_value);
1115 java_mirror->float_field_put(fd.offset(), value);
1116 } else if (strcmp(field_signature, "D") == 0) {
1117 double value = atof(string_value);
1118 java_mirror->double_field_put(fd.offset(), value);
1119 } else if (strcmp(field_signature, "Ljava/lang/String;") == 0) {
1120 Handle value = java_lang_String::create_from_str(string_value, CHECK);
1121 java_mirror->obj_field_put(fd.offset(), value());
1122 } else if (field_signature[0] == JVM_SIGNATURE_CLASS) {
1123 oop value = nullptr;
1124 if (string_value != nullptr) {
1125 Klass* k = resolve_klass(string_value, CHECK);
1126 value = InstanceKlass::cast(k)->allocate_instance(CHECK);
1127 }
1128 java_mirror->obj_field_put(fd.offset(), value);
1129 } else {
1130 report_error("unhandled staticfield");
1131 }
1132 }
1133 }
1134
1135 #if INCLUDE_JVMTI
1136 // JvmtiExport <field> <value>
1137 void process_JvmtiExport(TRAPS) {
1138 const char* field = parse_string();
1139 bool value = parse_int("JvmtiExport flag") != 0;
1140 if (strcmp(field, "can_access_local_variables") == 0) {
1141 JvmtiExport::set_can_access_local_variables(value);
1142 } else if (strcmp(field, "can_hotswap_or_post_breakpoint") == 0) {
1143 JvmtiExport::set_can_hotswap_or_post_breakpoint(value);
1144 } else if (strcmp(field, "can_post_on_exceptions") == 0) {
1145 JvmtiExport::set_can_post_on_exceptions(value);
1146 } else {
1147 report_error("Unrecognized JvmtiExport directive");
1148 }
1149 }
|
24
25 #include "ci/ciKlass.hpp"
26 #include "ci/ciMethodData.hpp"
27 #include "ci/ciReplay.hpp"
28 #include "ci/ciSymbol.hpp"
29 #include "ci/ciUtilities.inline.hpp"
30 #include "classfile/javaClasses.hpp"
31 #include "classfile/symbolTable.hpp"
32 #include "classfile/systemDictionary.hpp"
33 #include "compiler/compilationPolicy.hpp"
34 #include "compiler/compileBroker.hpp"
35 #include "compiler/compilerDefinitions.inline.hpp"
36 #include "interpreter/linkResolver.hpp"
37 #include "jvm.h"
38 #include "memory/allocation.inline.hpp"
39 #include "memory/oopFactory.hpp"
40 #include "memory/resourceArea.hpp"
41 #include "oops/constantPool.inline.hpp"
42 #include "oops/cpCache.inline.hpp"
43 #include "oops/fieldStreams.inline.hpp"
44 #include "oops/inlineKlass.inline.hpp"
45 #include "oops/klass.inline.hpp"
46 #include "oops/method.inline.hpp"
47 #include "oops/oop.inline.hpp"
48 #include "oops/resolvedIndyEntry.hpp"
49 #include "prims/jvmtiExport.hpp"
50 #include "prims/methodHandles.hpp"
51 #include "runtime/fieldDescriptor.inline.hpp"
52 #include "runtime/globals_extension.hpp"
53 #include "runtime/handles.inline.hpp"
54 #include "runtime/java.hpp"
55 #include "runtime/jniHandles.inline.hpp"
56 #include "runtime/threads.hpp"
57 #include "utilities/copy.hpp"
58 #include "utilities/macros.hpp"
59 #include "utilities/utf8.hpp"
60
61 // ciReplay
62
63 typedef struct _ciMethodDataRecord {
64 const char* _klass_name;
495 return nullptr;
496 }
497 if (strcmp(field, ";") == 0) {
498 break;
499 }
500 // raw Method*
501 if (strcmp(field, "<vmtarget>") == 0) {
502 Method* vmtarget = java_lang_invoke_MemberName::vmtarget(obj);
503 k = (vmtarget == nullptr) ? nullptr : vmtarget->method_holder();
504 if (k == nullptr) {
505 report_error("null vmtarget found");
506 return nullptr;
507 }
508 if (!parse_terminator()) {
509 report_error("missing terminator");
510 return nullptr;
511 }
512 return k;
513 }
514 obj = ciReplay::obj_field(obj, field);
515 // TODO 8350865 I think we need to handle null-free/flat arrays here
516 if (obj != nullptr && obj->is_objArray()) {
517 objArrayOop arr = (objArrayOop)obj;
518 int index = parse_int("index");
519 if (index >= arr->length()) {
520 report_error("bad array index");
521 return nullptr;
522 }
523 obj = arr->obj_at(index);
524 }
525 } while (obj != nullptr);
526 if (obj == nullptr) {
527 report_error("null field found");
528 return nullptr;
529 }
530 k = obj->klass();
531 return k;
532 }
533
534 // Parse a valid klass name and look it up
535 // syntax: <name>
846
847 rec->_orig_data = parse_data("orig", rec->_orig_data_length);
848 if (rec->_orig_data == nullptr) {
849 return;
850 }
851 rec->_data = parse_intptr_data("data", rec->_data_length);
852 if (rec->_data == nullptr) {
853 return;
854 }
855 if (!parse_tag_and_count("oops", rec->_classes_length)) {
856 return;
857 }
858 rec->_classes = NEW_RESOURCE_ARRAY(Klass*, rec->_classes_length);
859 rec->_classes_offsets = NEW_RESOURCE_ARRAY(int, rec->_classes_length);
860 for (int i = 0; i < rec->_classes_length; i++) {
861 int offset = parse_int("offset");
862 if (had_error()) {
863 return;
864 }
865 Klass* k = parse_klass(CHECK);
866 if (had_error()) {
867 return;
868 }
869 if (Arguments::is_valhalla_enabled() && _version >= 3 && k != nullptr && k->is_objArray_klass()) {
870 k = create_concrete_object_array_klass(ObjArrayKlass::cast(k), THREAD);
871 }
872 rec->_classes_offsets[i] = offset;
873 rec->_classes[i] = k;
874 }
875
876 if (!parse_tag_and_count("methods", rec->_methods_length)) {
877 return;
878 }
879 rec->_methods = NEW_RESOURCE_ARRAY(Method*, rec->_methods_length);
880 rec->_methods_offsets = NEW_RESOURCE_ARRAY(int, rec->_methods_length);
881 for (int i = 0; i < rec->_methods_length; i++) {
882 int offset = parse_int("offset");
883 if (had_error()) {
884 return;
885 }
886 Method* m = parse_method(CHECK);
887 rec->_methods_offsets[i] = offset;
888 rec->_methods[i] = m;
889 }
890 }
891
892 ObjArrayKlass* create_concrete_object_array_klass(ObjArrayKlass* obj_array_klass, TRAPS) {
893 ArrayKlass::ArrayProperties array_properties =
894 static_cast<ArrayKlass::ArrayProperties>(parse_int("array_properties"));
895 if (array_properties != ArrayKlass::DEFAULT &&
896 array_properties != ArrayKlass::NULL_RESTRICTED &&
897 array_properties != ArrayKlass::NON_ATOMIC &&
898 array_properties != (ArrayKlass::NULL_RESTRICTED | ArrayKlass::NON_ATOMIC)) {
899 guarantee(false, "invalid array_properties: %d, fall back to DEFAULT", array_properties);
900 }
901
902 return obj_array_klass->klass_with_properties(array_properties, THREAD);
903 }
904
905 // instanceKlass <name>
906 // instanceKlass <constant pool ref> # <original hidden class name>
907 //
908 // Loads and initializes the klass 'name'. This can be used to
909 // create particular class loading environments
910 void process_instanceKlass(TRAPS) {
911 // just load the referenced class
912 Klass* k = parse_klass(CHECK);
913
914 if (k == nullptr) {
915 return;
916 }
917 const char* comment = parse_string();
918 bool is_comment = comment != nullptr && strcmp(comment, "#") == 0;
919 if (k->is_hidden() != is_comment) {
920 report_error("hidden class with comment expected");
921 return;
922 }
923 // comment, print or ignore
924 if (is_comment) {
964 ConstantPool* cp = k->constants();
965 if (length != cp->length()) {
966 report_error("constant pool length mismatch: wrong class files?");
967 return;
968 }
969
970 int parsed_two_word = 0;
971 for (int i = 1; i < length; i++) {
972 int tag = parse_int("tag");
973 if (had_error()) {
974 return;
975 }
976 switch (cp->tag_at(i).value()) {
977 case JVM_CONSTANT_UnresolvedClass: {
978 if (tag == JVM_CONSTANT_Class) {
979 tty->print_cr("Resolving klass %s at %d", cp->klass_name_at(i)->as_utf8(), i);
980 Klass* k = cp->klass_at(i, CHECK);
981 }
982 break;
983 }
984
985 case JVM_CONSTANT_Long:
986 case JVM_CONSTANT_Double:
987 parsed_two_word = i + 1;
988
989 case JVM_CONSTANT_ClassIndex:
990 case JVM_CONSTANT_StringIndex:
991 case JVM_CONSTANT_String:
992 case JVM_CONSTANT_UnresolvedClassInError:
993 case JVM_CONSTANT_Fieldref:
994 case JVM_CONSTANT_Methodref:
995 case JVM_CONSTANT_InterfaceMethodref:
996 case JVM_CONSTANT_NameAndType:
997 case JVM_CONSTANT_Utf8:
998 case JVM_CONSTANT_Integer:
999 case JVM_CONSTANT_Float:
1000 case JVM_CONSTANT_MethodHandle:
1001 case JVM_CONSTANT_MethodType:
1002 case JVM_CONSTANT_Dynamic:
1003 case JVM_CONSTANT_InvokeDynamic:
1004 if (tag != cp->tag_at(i).value()) {
1011 if (tag == JVM_CONSTANT_UnresolvedClass) {
1012 Klass* k = cp->klass_at(i, CHECK);
1013 tty->print_cr("Warning: entry was unresolved in the replay data: %s", k->name()->as_utf8());
1014 } else if (tag != JVM_CONSTANT_Class) {
1015 report_error("Unexpected tag");
1016 return;
1017 }
1018 break;
1019
1020 case 0:
1021 if (parsed_two_word == i) continue;
1022
1023 default:
1024 fatal("Unexpected tag: %d", cp->tag_at(i).value());
1025 break;
1026 }
1027
1028 }
1029 }
1030
1031 class InlineTypeFieldInitializer : public FieldClosure {
1032 oop _vt;
1033 CompileReplay* _replay;
1034 public:
1035 InlineTypeFieldInitializer(oop vt, CompileReplay* replay)
1036 : _vt(vt), _replay(replay) {}
1037
1038 void do_field(fieldDescriptor* fd) {
1039 BasicType bt = fd->field_type();
1040 const char* string_value = fd->is_null_free_inline_type() ? nullptr : _replay->parse_escaped_string();
1041 switch (bt) {
1042 case T_BYTE: {
1043 int value = atoi(string_value);
1044 _vt->byte_field_put(fd->offset(), value);
1045 break;
1046 }
1047 case T_BOOLEAN: {
1048 int value = atoi(string_value);
1049 _vt->bool_field_put(fd->offset(), value);
1050 break;
1051 }
1052 case T_SHORT: {
1053 int value = atoi(string_value);
1054 _vt->short_field_put(fd->offset(), value);
1055 break;
1056 }
1057 case T_CHAR: {
1058 int value = atoi(string_value);
1059 _vt->char_field_put(fd->offset(), value);
1060 break;
1061 }
1062 case T_INT: {
1063 int value = atoi(string_value);
1064 _vt->int_field_put(fd->offset(), value);
1065 break;
1066 }
1067 case T_LONG: {
1068 jlong value;
1069 if (sscanf(string_value, JLONG_FORMAT, &value) != 1) {
1070 fprintf(stderr, "Error parsing long: %s\n", string_value);
1071 break;
1072 }
1073 _vt->long_field_put(fd->offset(), value);
1074 break;
1075 }
1076 case T_FLOAT: {
1077 float value = atof(string_value);
1078 _vt->float_field_put(fd->offset(), value);
1079 break;
1080 }
1081 case T_DOUBLE: {
1082 double value = atof(string_value);
1083 _vt->double_field_put(fd->offset(), value);
1084 break;
1085 }
1086 case T_ARRAY:
1087 case T_OBJECT:
1088 if (fd->is_null_free_inline_type() && fd->is_flat()) {
1089 InlineKlass* vk = InlineKlass::cast(fd->field_holder()->get_inline_type_field_klass(fd->index()));
1090 int field_offset = fd->offset() - vk->payload_offset();
1091 oop obj = cast_to_oop(cast_from_oop<address>(_vt) + field_offset);
1092 InlineTypeFieldInitializer init_fields(obj, _replay);
1093 vk->do_nonstatic_fields(&init_fields);
1094 } else {
1095 JavaThread* THREAD = JavaThread::current();
1096 bool res = _replay->process_staticfield_reference(string_value, _vt, fd, THREAD);
1097 assert(res, "should succeed for arrays & objects");
1098 }
1099 default: {
1100 fatal("Unhandled type: %s", type2name(bt));
1101 }
1102 }
1103 }
1104 };
1105
1106 bool process_staticfield_reference(const char* field_signature, oop java_mirror, fieldDescriptor* fd, TRAPS) {
1107 if (field_signature[0] == JVM_SIGNATURE_ARRAY) {
1108 int length = parse_int("array length");
1109 oop value = nullptr;
1110
1111 if (length != -1) {
1112 if (field_signature[1] == JVM_SIGNATURE_ARRAY) {
1113 // multi dimensional array
1114 Klass* k = resolve_klass(field_signature, CHECK_(true));
1115 ArrayKlass* kelem = (ArrayKlass *)k;
1116 int rank = 0;
1117 while (field_signature[rank] == JVM_SIGNATURE_ARRAY) {
1118 rank++;
1119 }
1120 jint* dims = NEW_RESOURCE_ARRAY(jint, rank);
1121 dims[0] = length;
1122 for (int i = 1; i < rank; i++) {
1123 dims[i] = 1; // These aren't relevant to the compiler
1124 }
1125 value = kelem->multi_allocate(rank, dims, CHECK_(true));
1126 } else {
1127 if (strcmp(field_signature, "[B") == 0) {
1128 value = oopFactory::new_byteArray(length, CHECK_(true));
1129 } else if (strcmp(field_signature, "[Z") == 0) {
1130 value = oopFactory::new_boolArray(length, CHECK_(true));
1131 } else if (strcmp(field_signature, "[C") == 0) {
1132 value = oopFactory::new_charArray(length, CHECK_(true));
1133 } else if (strcmp(field_signature, "[S") == 0) {
1134 value = oopFactory::new_shortArray(length, CHECK_(true));
1135 } else if (strcmp(field_signature, "[F") == 0) {
1136 value = oopFactory::new_floatArray(length, CHECK_(true));
1137 } else if (strcmp(field_signature, "[D") == 0) {
1138 value = oopFactory::new_doubleArray(length, CHECK_(true));
1139 } else if (strcmp(field_signature, "[I") == 0) {
1140 value = oopFactory::new_intArray(length, CHECK_(true));
1141 } else if (strcmp(field_signature, "[J") == 0) {
1142 value = oopFactory::new_longArray(length, CHECK_(true));
1143 } else if (field_signature[0] == JVM_SIGNATURE_ARRAY &&
1144 field_signature[1] == JVM_SIGNATURE_CLASS) {
1145 Klass* actual_array_klass = parse_klass(CHECK_(true));
1146 // TODO 8350865 I think we need to handle null-free/flat arrays here
1147 // This handling will change the array property argument passed to the
1148 // factory below
1149 Klass* kelem = ObjArrayKlass::cast(actual_array_klass)->element_klass();
1150 value = oopFactory::new_objArray(kelem, length, CHECK_(true));
1151 } else {
1152 report_error("unhandled array staticfield");
1153 }
1154 }
1155 java_mirror->obj_field_put(fd->offset(), value);
1156 return true;
1157 }
1158 } else if (strcmp(field_signature, "Ljava/lang/String;") == 0) {
1159 const char* string_value = parse_escaped_string();
1160 Handle value = java_lang_String::create_from_str(string_value, CHECK_(true));
1161 java_mirror->obj_field_put(fd->offset(), value());
1162 return true;
1163 } else if (field_signature[0] == JVM_SIGNATURE_CLASS) {
1164 const char* instance = parse_escaped_string();
1165 oop value = nullptr;
1166 if (instance != nullptr) {
1167 Klass* k = resolve_klass(instance, CHECK_(true));
1168 value = InstanceKlass::cast(k)->allocate_instance(CHECK_(true));
1169 }
1170 java_mirror->obj_field_put(fd->offset(), value);
1171 return true;
1172 }
1173 return false;
1174 }
1175
1176 // Initialize a class and fill in the value for a static field.
1177 // This is useful when the compile was dependent on the value of
1178 // static fields but it's impossible to properly rerun the static
1179 // initializer.
1180 void process_staticfield(TRAPS) {
1181 InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK);
1182
1183 if (k == nullptr || ReplaySuppressInitializers == 0 ||
1184 (ReplaySuppressInitializers == 2 && k->class_loader() == nullptr)) {
1185 skip_remaining();
1186 return;
1187 }
1188
1189 assert(k->is_initialized(), "must be");
1190
1191 const char* field_name = parse_escaped_string();
1192 const char* field_signature = parse_string();
1193 fieldDescriptor fd;
1194 Symbol* name = SymbolTable::new_symbol(field_name);
1195 Symbol* sig = SymbolTable::new_symbol(field_signature);
1196 if (!k->find_local_field(name, sig, &fd) ||
1197 !fd.is_static() ||
1198 fd.has_initial_value()) {
1199 report_error(field_name);
1200 return;
1201 }
1202
1203 oop java_mirror = k->java_mirror();
1204 if (strcmp(field_signature, "I") == 0) {
1205 const char* string_value = parse_escaped_string();
1206 int value = atoi(string_value);
1207 java_mirror->int_field_put(fd.offset(), value);
1208 } else if (strcmp(field_signature, "B") == 0) {
1209 const char* string_value = parse_escaped_string();
1210 int value = atoi(string_value);
1211 java_mirror->byte_field_put(fd.offset(), value);
1212 } else if (strcmp(field_signature, "C") == 0) {
1213 const char* string_value = parse_escaped_string();
1214 int value = atoi(string_value);
1215 java_mirror->char_field_put(fd.offset(), value);
1216 } else if (strcmp(field_signature, "S") == 0) {
1217 const char* string_value = parse_escaped_string();
1218 int value = atoi(string_value);
1219 java_mirror->short_field_put(fd.offset(), value);
1220 } else if (strcmp(field_signature, "Z") == 0) {
1221 const char* string_value = parse_escaped_string();
1222 int value = atoi(string_value);
1223 java_mirror->bool_field_put(fd.offset(), value);
1224 } else if (strcmp(field_signature, "J") == 0) {
1225 const char* string_value = parse_escaped_string();
1226 jlong value;
1227 if (sscanf(string_value, JLONG_FORMAT, &value) != 1) {
1228 fprintf(stderr, "Error parsing long: %s\n", string_value);
1229 return;
1230 }
1231 java_mirror->long_field_put(fd.offset(), value);
1232 } else if (strcmp(field_signature, "F") == 0) {
1233 const char* string_value = parse_escaped_string();
1234 float value = atof(string_value);
1235 java_mirror->float_field_put(fd.offset(), value);
1236 } else if (strcmp(field_signature, "D") == 0) {
1237 const char* string_value = parse_escaped_string();
1238 double value = atof(string_value);
1239 java_mirror->double_field_put(fd.offset(), value);
1240 } else if (fd.is_null_free_inline_type()) {
1241 Klass* kelem = resolve_klass(field_signature, CHECK);
1242 InlineKlass* vk = InlineKlass::cast(kelem);
1243 oop value = vk->allocate_instance(CHECK);
1244 InlineTypeFieldInitializer init_fields(value, this);
1245 vk->do_nonstatic_fields(&init_fields);
1246 java_mirror->obj_field_put(fd.offset(), value);
1247 } else {
1248 bool res = process_staticfield_reference(field_signature, java_mirror, &fd, CHECK);
1249 if (!res) {
1250 report_error("unhandled staticfield");
1251 }
1252 }
1253 }
1254
1255 #if INCLUDE_JVMTI
1256 // JvmtiExport <field> <value>
1257 void process_JvmtiExport(TRAPS) {
1258 const char* field = parse_string();
1259 bool value = parse_int("JvmtiExport flag") != 0;
1260 if (strcmp(field, "can_access_local_variables") == 0) {
1261 JvmtiExport::set_can_access_local_variables(value);
1262 } else if (strcmp(field, "can_hotswap_or_post_breakpoint") == 0) {
1263 JvmtiExport::set_can_hotswap_or_post_breakpoint(value);
1264 } else if (strcmp(field, "can_post_on_exceptions") == 0) {
1265 JvmtiExport::set_can_post_on_exceptions(value);
1266 } else {
1267 report_error("Unrecognized JvmtiExport directive");
1268 }
1269 }
|