< prev index next >

src/hotspot/share/ci/ciReplay.cpp

Print this page

   1 /*
   2  * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  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;
  64   const char* _method_name;
  65   const char* _signature;
  66 

 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>
 535   // syntax: <constant pool ref>
 536   Klass* parse_klass(TRAPS) {

 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   }

   1 /*
   2  * Copyright (c) 2013, 2026, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  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/arrayProperties.hpp"
  42 #include "oops/constantPool.inline.hpp"
  43 #include "oops/cpCache.inline.hpp"
  44 #include "oops/fieldStreams.inline.hpp"
  45 #include "oops/inlineKlass.inline.hpp"
  46 #include "oops/klass.inline.hpp"
  47 #include "oops/method.inline.hpp"
  48 #include "oops/oop.inline.hpp"
  49 #include "oops/oopCast.inline.hpp"
  50 #include "oops/resolvedIndyEntry.hpp"
  51 #include "prims/jvmtiExport.hpp"
  52 #include "prims/methodHandles.hpp"
  53 #include "runtime/fieldDescriptor.inline.hpp"
  54 #include "runtime/globals_extension.hpp"
  55 #include "runtime/handles.inline.hpp"
  56 #include "runtime/java.hpp"
  57 #include "runtime/jniHandles.inline.hpp"
  58 #include "runtime/threads.hpp"
  59 #include "utilities/copy.hpp"
  60 #include "utilities/macros.hpp"
  61 #include "utilities/utf8.hpp"
  62 
  63 // ciReplay
  64 
  65 typedef struct _ciMethodDataRecord {
  66   const char* _klass_name;
  67   const char* _method_name;
  68   const char* _signature;
  69 

 497         return nullptr;
 498       }
 499       if (strcmp(field, ";") == 0) {
 500         break;
 501       }
 502       // raw Method*
 503       if (strcmp(field, "<vmtarget>") == 0) {
 504         Method* vmtarget = java_lang_invoke_MemberName::vmtarget(obj);
 505         k = (vmtarget == nullptr) ? nullptr : vmtarget->method_holder();
 506         if (k == nullptr) {
 507           report_error("null vmtarget found");
 508           return nullptr;
 509         }
 510         if (!parse_terminator()) {
 511           report_error("missing terminator");
 512           return nullptr;
 513         }
 514         return k;
 515       }
 516       obj = ciReplay::obj_field(obj, field);
 517       // TODO 8350865 I think we need to handle null-free/flat arrays here
 518       if (obj != nullptr && obj->is_refArray()) {
 519         refArrayOop arr = oop_cast<refArrayOop>(obj);
 520         int index = parse_int("index");
 521         if (index >= arr->length()) {
 522           report_error("bad array index");
 523           return nullptr;
 524         }
 525         obj = arr->obj_at(index);
 526       }
 527     } while (obj != nullptr);
 528     if (obj == nullptr) {
 529       report_error("null field found");
 530       return nullptr;
 531     }
 532     k = obj->klass();
 533     return k;
 534   }
 535 
 536   // Parse a valid klass name and look it up
 537   // syntax: <name>
 538   // syntax: <constant pool ref>
 539   Klass* parse_klass(TRAPS) {

 848 
 849     rec->_orig_data = parse_data("orig", rec->_orig_data_length);
 850     if (rec->_orig_data == nullptr) {
 851       return;
 852     }
 853     rec->_data = parse_intptr_data("data", rec->_data_length);
 854     if (rec->_data == nullptr) {
 855       return;
 856     }
 857     if (!parse_tag_and_count("oops", rec->_classes_length)) {
 858       return;
 859     }
 860     rec->_classes = NEW_RESOURCE_ARRAY(Klass*, rec->_classes_length);
 861     rec->_classes_offsets = NEW_RESOURCE_ARRAY(int, rec->_classes_length);
 862     for (int i = 0; i < rec->_classes_length; i++) {
 863       int offset = parse_int("offset");
 864       if (had_error()) {
 865         return;
 866       }
 867       Klass* k = parse_klass(CHECK);
 868       if (had_error()) {
 869         return;
 870       }
 871       if (_version >= 3 && k != nullptr && k->is_objArray_klass()) {
 872         k = create_concrete_object_array_klass(ObjArrayKlass::cast(k), THREAD);
 873       }
 874       rec->_classes_offsets[i] = offset;
 875       rec->_classes[i] = k;
 876     }
 877 
 878     if (!parse_tag_and_count("methods", rec->_methods_length)) {
 879       return;
 880     }
 881     rec->_methods = NEW_RESOURCE_ARRAY(Method*, rec->_methods_length);
 882     rec->_methods_offsets = NEW_RESOURCE_ARRAY(int, rec->_methods_length);
 883     for (int i = 0; i < rec->_methods_length; i++) {
 884       int offset = parse_int("offset");
 885       if (had_error()) {
 886         return;
 887       }
 888       Method* m = parse_method(CHECK);
 889       rec->_methods_offsets[i] = offset;
 890       rec->_methods[i] = m;
 891     }
 892   }
 893 
 894   ObjArrayKlass* create_concrete_object_array_klass(ObjArrayKlass* obj_array_klass, TRAPS) {
 895     const ArrayProperties array_properties(checked_cast<ArrayProperties::Type>(parse_int("array_properties")));
 896     if (!Arguments::is_valhalla_enabled()) {
 897       // Ignore array properties.
 898       return obj_array_klass;
 899     }
 900 
 901     guarantee(array_properties.is_valid(), "invalid array_properties: %d", array_properties.value());
 902 
 903     return obj_array_klass->klass_with_properties(array_properties, THREAD);
 904   }
 905 
 906   // instanceKlass <name>
 907   // instanceKlass <constant pool ref> # <original hidden class name>
 908   //
 909   // Loads and initializes the klass 'name'.  This can be used to
 910   // create particular class loading environments
 911   void process_instanceKlass(TRAPS) {
 912     // just load the referenced class
 913     Klass* k = parse_klass(CHECK);
 914 
 915     if (k == nullptr) {
 916       return;
 917     }
 918     const char* comment = parse_string();
 919     bool is_comment = comment != nullptr && strcmp(comment, "#") == 0;
 920     if (k->is_hidden() != is_comment) {
 921       report_error("hidden class with comment expected");
 922       return;
 923     }
 924     // comment, print or ignore
 925     if (is_comment) {

 965     ConstantPool* cp = k->constants();
 966     if (length != cp->length()) {
 967       report_error("constant pool length mismatch: wrong class files?");
 968       return;
 969     }
 970 
 971     int parsed_two_word = 0;
 972     for (int i = 1; i < length; i++) {
 973       int tag = parse_int("tag");
 974       if (had_error()) {
 975         return;
 976       }
 977       switch (cp->tag_at(i).value()) {
 978         case JVM_CONSTANT_UnresolvedClass: {
 979           if (tag == JVM_CONSTANT_Class) {
 980             tty->print_cr("Resolving klass %s at %d", cp->klass_name_at(i)->as_utf8(), i);
 981             Klass* k = cp->klass_at(i, CHECK);
 982           }
 983           break;
 984         }
 985 
 986         case JVM_CONSTANT_Long:
 987         case JVM_CONSTANT_Double:
 988           parsed_two_word = i + 1;
 989 
 990         case JVM_CONSTANT_ClassIndex:
 991         case JVM_CONSTANT_StringIndex:
 992         case JVM_CONSTANT_String:
 993         case JVM_CONSTANT_UnresolvedClassInError:
 994         case JVM_CONSTANT_Fieldref:
 995         case JVM_CONSTANT_Methodref:
 996         case JVM_CONSTANT_InterfaceMethodref:
 997         case JVM_CONSTANT_NameAndType:
 998         case JVM_CONSTANT_Utf8:
 999         case JVM_CONSTANT_Integer:
1000         case JVM_CONSTANT_Float:
1001         case JVM_CONSTANT_MethodHandle:
1002         case JVM_CONSTANT_MethodType:
1003         case JVM_CONSTANT_Dynamic:
1004         case JVM_CONSTANT_InvokeDynamic:
1005           if (tag != cp->tag_at(i).value()) {

1012           if (tag == JVM_CONSTANT_UnresolvedClass) {
1013             Klass* k = cp->klass_at(i, CHECK);
1014             tty->print_cr("Warning: entry was unresolved in the replay data: %s", k->name()->as_utf8());
1015           } else if (tag != JVM_CONSTANT_Class) {
1016             report_error("Unexpected tag");
1017             return;
1018           }
1019           break;
1020 
1021         case 0:
1022           if (parsed_two_word == i) continue;
1023 
1024         default:
1025           fatal("Unexpected tag: %d", cp->tag_at(i).value());
1026           break;
1027       }
1028 
1029     }
1030   }
1031 
1032   class InlineTypeFieldInitializer : public FieldClosure {
1033     oop _vt;
1034     CompileReplay* _replay;
1035   public:
1036     InlineTypeFieldInitializer(oop vt, CompileReplay* replay)
1037   : _vt(vt), _replay(replay) {}
1038 
1039     void do_field(fieldDescriptor* fd) {
1040       BasicType bt = fd->field_type();
1041       const char* string_value = fd->is_null_free_inline_type() ? nullptr : _replay->parse_escaped_string();
1042       switch (bt) {
1043       case T_BYTE: {
1044         int value = atoi(string_value);
1045         _vt->byte_field_put(fd->offset(), value);
1046         break;
1047       }
1048       case T_BOOLEAN: {
1049         int value = atoi(string_value);
1050         _vt->bool_field_put(fd->offset(), value);
1051         break;
1052       }
1053       case T_SHORT: {
1054         int value = atoi(string_value);
1055         _vt->short_field_put(fd->offset(), value);
1056         break;
1057       }
1058       case T_CHAR: {
1059         int value = atoi(string_value);
1060         _vt->char_field_put(fd->offset(), value);
1061         break;
1062       }
1063       case T_INT: {
1064         int value = atoi(string_value);
1065         _vt->int_field_put(fd->offset(), value);
1066         break;
1067       }
1068       case T_LONG: {
1069         jlong value;
1070         if (sscanf(string_value, JLONG_FORMAT, &value) != 1) {
1071           fprintf(stderr, "Error parsing long: %s\n", string_value);
1072           break;
1073         }
1074         _vt->long_field_put(fd->offset(), value);
1075         break;
1076       }
1077       case T_FLOAT: {
1078         float value = atof(string_value);
1079         _vt->float_field_put(fd->offset(), value);
1080         break;
1081       }
1082       case T_DOUBLE: {
1083         double value = atof(string_value);
1084         _vt->double_field_put(fd->offset(), value);
1085         break;
1086       }
1087       case T_ARRAY:
1088       case T_OBJECT:
1089         if (fd->is_null_free_inline_type() && fd->is_flat()) {
1090           InlineKlass* vk = InlineKlass::cast(fd->field_holder()->get_inline_type_field_klass(fd->index()));
1091           int field_offset = fd->offset() - vk->payload_offset();
1092           oop obj = cast_to_oop(cast_from_oop<address>(_vt) + field_offset);
1093           InlineTypeFieldInitializer init_fields(obj, _replay);
1094           vk->do_nonstatic_fields(&init_fields);
1095         } else {
1096           JavaThread* THREAD = JavaThread::current();
1097           bool res = _replay->process_staticfield_reference(string_value, _vt, fd, THREAD);
1098           assert(res, "should succeed for arrays & objects");
1099         }
1100       default: {
1101         fatal("Unhandled type: %s", type2name(bt));
1102       }
1103       }
1104     }
1105   };
1106 
1107   bool process_staticfield_reference(const char* field_signature, oop java_mirror, fieldDescriptor* fd, TRAPS) {
1108     if (field_signature[0] == JVM_SIGNATURE_ARRAY) {
1109       int length = parse_int("array length");
1110       oop value = nullptr;
1111 
1112       if (length != -1) {
1113         if (field_signature[1] == JVM_SIGNATURE_ARRAY) {
1114           // multi dimensional array
1115           Klass* k = resolve_klass(field_signature, CHECK_(true));
1116           ArrayKlass* kelem = (ArrayKlass *)k;


1117           int rank = 0;
1118           while (field_signature[rank] == JVM_SIGNATURE_ARRAY) {
1119             rank++;
1120           }
1121           jint* dims = NEW_RESOURCE_ARRAY(jint, rank);
1122           dims[0] = length;
1123           for (int i = 1; i < rank; i++) {
1124             dims[i] = 1; // These aren't relevant to the compiler
1125           }
1126           value = kelem->multi_allocate(rank, dims, CHECK_(true));
1127         } else {
1128           if (strcmp(field_signature, "[B") == 0) {
1129             value = oopFactory::new_byteArray(length, CHECK_(true));
1130           } else if (strcmp(field_signature, "[Z") == 0) {
1131             value = oopFactory::new_boolArray(length, CHECK_(true));
1132           } else if (strcmp(field_signature, "[C") == 0) {
1133             value = oopFactory::new_charArray(length, CHECK_(true));
1134           } else if (strcmp(field_signature, "[S") == 0) {
1135             value = oopFactory::new_shortArray(length, CHECK_(true));
1136           } else if (strcmp(field_signature, "[F") == 0) {
1137             value = oopFactory::new_floatArray(length, CHECK_(true));
1138           } else if (strcmp(field_signature, "[D") == 0) {
1139             value = oopFactory::new_doubleArray(length, CHECK_(true));
1140           } else if (strcmp(field_signature, "[I") == 0) {
1141             value = oopFactory::new_intArray(length, CHECK_(true));
1142           } else if (strcmp(field_signature, "[J") == 0) {
1143             value = oopFactory::new_longArray(length, CHECK_(true));
1144           } else if (field_signature[0] == JVM_SIGNATURE_ARRAY &&
1145                      field_signature[1] == JVM_SIGNATURE_CLASS) {
1146             Klass* actual_array_klass = parse_klass(CHECK_(true));
1147             // TODO 8350865 I think we need to handle null-free/flat arrays here
1148             // This handling will change the array property argument passed to the
1149             // factory below
1150             Klass* kelem = ObjArrayKlass::cast(actual_array_klass)->element_klass();
1151             value = oopFactory::new_objArray(kelem, length, CHECK_(true));
1152           } else {
1153             report_error("unhandled array staticfield");
1154           }
1155         }
1156         java_mirror->obj_field_put(fd->offset(), value);
1157         return true;
1158       }
1159     } else if (strcmp(field_signature, "Ljava/lang/String;") == 0) {
1160       const char* string_value = parse_escaped_string();
1161       Handle value = java_lang_String::create_from_str(string_value, CHECK_(true));
1162       java_mirror->obj_field_put(fd->offset(), value());
1163       return true;
1164     } else if (field_signature[0] == JVM_SIGNATURE_CLASS) {
1165       const char* instance = parse_escaped_string();
1166       oop value = nullptr;
1167       if (instance != nullptr) {
1168         Klass* k = resolve_klass(instance, CHECK_(true));
1169         value = InstanceKlass::cast(k)->allocate_instance(CHECK_(true));
1170       }
1171       java_mirror->obj_field_put(fd->offset(), value);
1172       return true;
1173     }
1174     return false;
1175   }
1176 
1177   // Initialize a class and fill in the value for a static field.
1178   // This is useful when the compile was dependent on the value of
1179   // static fields but it's impossible to properly rerun the static
1180   // initializer.
1181   void process_staticfield(TRAPS) {
1182     InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK);
1183 
1184     if (k == nullptr || ReplaySuppressInitializers == 0 ||
1185         (ReplaySuppressInitializers == 2 && k->class_loader() == nullptr)) {
1186         skip_remaining();
1187       return;
1188     }
1189 
1190     assert(k->is_initialized(), "must be");
1191 
1192     const char* field_name = parse_escaped_string();
1193     const char* field_signature = parse_string();
1194     fieldDescriptor fd;
1195     Symbol* name = SymbolTable::new_symbol(field_name);
1196     Symbol* sig = SymbolTable::new_symbol(field_signature);
1197     if (!k->find_local_field(name, sig, &fd) ||
1198         !fd.is_static() ||
1199         fd.has_initial_value()) {
1200       report_error(field_name);
1201       return;
1202     }
1203 
1204     oop java_mirror = k->java_mirror();
1205     if (strcmp(field_signature, "I") == 0) {
1206       const char* string_value = parse_escaped_string();
1207       int value = atoi(string_value);
1208       java_mirror->int_field_put(fd.offset(), value);
1209     } else if (strcmp(field_signature, "B") == 0) {
1210       const char* string_value = parse_escaped_string();
1211       int value = atoi(string_value);
1212       java_mirror->byte_field_put(fd.offset(), value);
1213     } else if (strcmp(field_signature, "C") == 0) {
1214       const char* string_value = parse_escaped_string();
1215       int value = atoi(string_value);
1216       java_mirror->char_field_put(fd.offset(), value);
1217     } else if (strcmp(field_signature, "S") == 0) {
1218       const char* string_value = parse_escaped_string();
1219       int value = atoi(string_value);
1220       java_mirror->short_field_put(fd.offset(), value);
1221     } else if (strcmp(field_signature, "Z") == 0) {
1222       const char* string_value = parse_escaped_string();
1223       int value = atoi(string_value);
1224       java_mirror->bool_field_put(fd.offset(), value);
1225     } else if (strcmp(field_signature, "J") == 0) {
1226       const char* string_value = parse_escaped_string();
1227       jlong value;
1228       if (sscanf(string_value, JLONG_FORMAT, &value) != 1) {
1229         fprintf(stderr, "Error parsing long: %s\n", string_value);
1230         return;
1231       }
1232       java_mirror->long_field_put(fd.offset(), value);
1233     } else if (strcmp(field_signature, "F") == 0) {
1234       const char* string_value = parse_escaped_string();
1235       float value = atof(string_value);
1236       java_mirror->float_field_put(fd.offset(), value);
1237     } else if (strcmp(field_signature, "D") == 0) {
1238       const char* string_value = parse_escaped_string();
1239       double value = atof(string_value);
1240       java_mirror->double_field_put(fd.offset(), value);
1241     } else if (fd.is_null_free_inline_type()) {
1242       Klass* kelem = resolve_klass(field_signature, CHECK);
1243       InlineKlass* vk = InlineKlass::cast(kelem);
1244       oop value = vk->allocate_instance(CHECK);
1245       InlineTypeFieldInitializer init_fields(value, this);
1246       vk->do_nonstatic_fields(&init_fields);
1247       java_mirror->obj_field_put(fd.offset(), value);
1248     } else {
1249       bool res = process_staticfield_reference(field_signature, java_mirror, &fd, CHECK);
1250       if (!res)  {






































1251         report_error("unhandled staticfield");
1252       }
1253     }
1254   }
1255 
1256 #if INCLUDE_JVMTI
1257   // JvmtiExport <field> <value>
1258   void process_JvmtiExport(TRAPS) {
1259     const char* field = parse_string();
1260     bool value = parse_int("JvmtiExport flag") != 0;
1261     if (strcmp(field, "can_access_local_variables") == 0) {
1262       JvmtiExport::set_can_access_local_variables(value);
1263     } else if (strcmp(field, "can_hotswap_or_post_breakpoint") == 0) {
1264       JvmtiExport::set_can_hotswap_or_post_breakpoint(value);
1265     } else if (strcmp(field, "can_post_on_exceptions") == 0) {
1266       JvmtiExport::set_can_post_on_exceptions(value);
1267     } else {
1268       report_error("Unrecognized JvmtiExport directive");
1269     }
1270   }
< prev index next >