< prev index next >

src/hotspot/share/ci/ciReplay.cpp

Print this page

  24 
  25 #include "precompiled.hpp"
  26 #include "jvm.h"
  27 #include "ci/ciMethodData.hpp"
  28 #include "ci/ciReplay.hpp"
  29 #include "ci/ciSymbol.hpp"
  30 #include "ci/ciKlass.hpp"
  31 #include "ci/ciUtilities.inline.hpp"
  32 #include "classfile/javaClasses.hpp"
  33 #include "classfile/symbolTable.hpp"
  34 #include "classfile/systemDictionary.hpp"
  35 #include "compiler/compilationPolicy.hpp"
  36 #include "compiler/compileBroker.hpp"
  37 #include "interpreter/linkResolver.hpp"
  38 #include "memory/allocation.inline.hpp"
  39 #include "memory/oopFactory.hpp"
  40 #include "memory/resourceArea.hpp"
  41 #include "oops/constantPool.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 "prims/jvmtiExport.hpp"
  48 #include "prims/methodHandles.hpp"
  49 #include "runtime/fieldDescriptor.inline.hpp"
  50 #include "runtime/globals_extension.hpp"
  51 #include "runtime/handles.inline.hpp"
  52 #include "runtime/java.hpp"
  53 #include "utilities/copy.hpp"
  54 #include "utilities/macros.hpp"
  55 #include "utilities/utf8.hpp"
  56 
  57 #ifndef PRODUCT
  58 
  59 // ciReplay
  60 
  61 typedef struct _ciMethodDataRecord {
  62   const char* _klass_name;
  63   const char* _method_name;

 908     ConstantPool* cp = k->constants();
 909     if (length != cp->length()) {
 910       report_error("constant pool length mismatch: wrong class files?");
 911       return;
 912     }
 913 
 914     int parsed_two_word = 0;
 915     for (int i = 1; i < length; i++) {
 916       int tag = parse_int("tag");
 917       if (had_error()) {
 918         return;
 919       }
 920       switch (cp->tag_at(i).value()) {
 921         case JVM_CONSTANT_UnresolvedClass: {
 922           if (tag == JVM_CONSTANT_Class) {
 923             tty->print_cr("Resolving klass %s at %d", cp->klass_name_at(i)->as_utf8(), i);
 924             Klass* k = cp->klass_at(i, CHECK);
 925           }
 926           break;
 927         }

 928         case JVM_CONSTANT_Long:
 929         case JVM_CONSTANT_Double:
 930           parsed_two_word = i + 1;
 931 
 932         case JVM_CONSTANT_ClassIndex:
 933         case JVM_CONSTANT_StringIndex:
 934         case JVM_CONSTANT_String:
 935         case JVM_CONSTANT_UnresolvedClassInError:
 936         case JVM_CONSTANT_Fieldref:
 937         case JVM_CONSTANT_Methodref:
 938         case JVM_CONSTANT_InterfaceMethodref:
 939         case JVM_CONSTANT_NameAndType:
 940         case JVM_CONSTANT_Utf8:
 941         case JVM_CONSTANT_Integer:
 942         case JVM_CONSTANT_Float:
 943         case JVM_CONSTANT_MethodHandle:
 944         case JVM_CONSTANT_MethodType:
 945         case JVM_CONSTANT_Dynamic:
 946         case JVM_CONSTANT_InvokeDynamic:
 947           if (tag != cp->tag_at(i).value()) {

 954           if (tag == JVM_CONSTANT_Class) {
 955           } else if (tag == JVM_CONSTANT_UnresolvedClass) {
 956             tty->print_cr("Warning: entry was unresolved in the replay data");
 957           } else {
 958             report_error("Unexpected tag");
 959             return;
 960           }
 961           break;
 962 
 963         case 0:
 964           if (parsed_two_word == i) continue;
 965 
 966         default:
 967           fatal("Unexpected tag: %d", cp->tag_at(i).value());
 968           break;
 969       }
 970 
 971     }
 972   }
 973 
 974   // staticfield <klass> <name> <signature> <value>
 975   //
 976   // Initialize a class and fill in the value for a static field.
 977   // This is useful when the compile was dependent on the value of
 978   // static fields but it's impossible to properly rerun the static
 979   // initializer.
 980   void process_staticfield(TRAPS) {
 981     InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK);
 982 
 983     if (k == NULL || ReplaySuppressInitializers == 0 ||
 984         (ReplaySuppressInitializers == 2 && k->class_loader() == NULL)) {
 985       return;
 986     }
 987 
 988     assert(k->is_initialized(), "must be");
 989 
 990     const char* field_name = parse_escaped_string();
 991     const char* field_signature = parse_string();
 992     fieldDescriptor fd;
 993     Symbol* name = SymbolTable::new_symbol(field_name);
 994     Symbol* sig = SymbolTable::new_symbol(field_signature);
 995     if (!k->find_local_field(name, sig, &fd) ||
 996         !fd.is_static() ||
 997         fd.has_initial_value()) {
 998       report_error(field_name);
 999       return;





















































1000     }

1001 
1002     oop java_mirror = k->java_mirror();
1003     if (field_signature[0] == JVM_SIGNATURE_ARRAY) {
1004       int length = parse_int("array length");
1005       oop value = NULL;
1006 
1007       if (field_signature[1] == JVM_SIGNATURE_ARRAY) {
1008         // multi dimensional array
1009         ArrayKlass* kelem = (ArrayKlass *)parse_klass(CHECK);
1010         if (kelem == NULL) {
1011           return;
1012         }
1013         int rank = 0;
1014         while (field_signature[rank] == JVM_SIGNATURE_ARRAY) {
1015           rank++;
1016         }
1017         jint* dims = NEW_RESOURCE_ARRAY(jint, rank);
1018         dims[0] = length;
1019         for (int i = 1; i < rank; i++) {
1020           dims[i] = 1; // These aren't relevant to the compiler
1021         }
1022         value = kelem->multi_allocate(rank, dims, CHECK);
1023       } else {
1024         if (strcmp(field_signature, "[B") == 0) {
1025           value = oopFactory::new_byteArray(length, CHECK);
1026         } else if (strcmp(field_signature, "[Z") == 0) {
1027           value = oopFactory::new_boolArray(length, CHECK);
1028         } else if (strcmp(field_signature, "[C") == 0) {
1029           value = oopFactory::new_charArray(length, CHECK);
1030         } else if (strcmp(field_signature, "[S") == 0) {
1031           value = oopFactory::new_shortArray(length, CHECK);
1032         } else if (strcmp(field_signature, "[F") == 0) {
1033           value = oopFactory::new_floatArray(length, CHECK);
1034         } else if (strcmp(field_signature, "[D") == 0) {
1035           value = oopFactory::new_doubleArray(length, CHECK);
1036         } else if (strcmp(field_signature, "[I") == 0) {
1037           value = oopFactory::new_intArray(length, CHECK);
1038         } else if (strcmp(field_signature, "[J") == 0) {
1039           value = oopFactory::new_longArray(length, CHECK);
1040         } else if (field_signature[0] == JVM_SIGNATURE_ARRAY &&
1041                    field_signature[1] == JVM_SIGNATURE_CLASS) {
1042           Klass* kelem = resolve_klass(field_signature + 1, CHECK);
1043           value = oopFactory::new_objArray(kelem, length, CHECK);




1044         } else {
1045           report_error("unhandled array staticfield");
1046         }
1047       }






















































































1048       java_mirror->obj_field_put(fd.offset(), value);
1049     } else {
1050       const char* string_value = parse_escaped_string();
1051       if (strcmp(field_signature, "I") == 0) {
1052         int value = atoi(string_value);
1053         java_mirror->int_field_put(fd.offset(), value);
1054       } else if (strcmp(field_signature, "B") == 0) {
1055         int value = atoi(string_value);
1056         java_mirror->byte_field_put(fd.offset(), value);
1057       } else if (strcmp(field_signature, "C") == 0) {
1058         int value = atoi(string_value);
1059         java_mirror->char_field_put(fd.offset(), value);
1060       } else if (strcmp(field_signature, "S") == 0) {
1061         int value = atoi(string_value);
1062         java_mirror->short_field_put(fd.offset(), value);
1063       } else if (strcmp(field_signature, "Z") == 0) {
1064         int value = atoi(string_value);
1065         java_mirror->bool_field_put(fd.offset(), value);
1066       } else if (strcmp(field_signature, "J") == 0) {
1067         jlong value;
1068         if (sscanf(string_value, JLONG_FORMAT, &value) != 1) {
1069           fprintf(stderr, "Error parsing long: %s\n", string_value);
1070           return;
1071         }
1072         java_mirror->long_field_put(fd.offset(), value);
1073       } else if (strcmp(field_signature, "F") == 0) {
1074         float value = atof(string_value);
1075         java_mirror->float_field_put(fd.offset(), value);
1076       } else if (strcmp(field_signature, "D") == 0) {
1077         double value = atof(string_value);
1078         java_mirror->double_field_put(fd.offset(), value);
1079       } else if (strcmp(field_signature, "Ljava/lang/String;") == 0) {
1080         Handle value = java_lang_String::create_from_str(string_value, CHECK);
1081         java_mirror->obj_field_put(fd.offset(), value());
1082       } else if (field_signature[0] == JVM_SIGNATURE_CLASS) {
1083         Klass* k = resolve_klass(string_value, CHECK);
1084         oop value = InstanceKlass::cast(k)->allocate_instance(CHECK);
1085         java_mirror->obj_field_put(fd.offset(), value);
1086       } else {
1087         report_error("unhandled staticfield");
1088       }
1089     }
1090   }
1091 
1092 #if INCLUDE_JVMTI
1093   // JvmtiExport <field> <value>
1094   void process_JvmtiExport(TRAPS) {
1095     const char* field = parse_string();
1096     bool value = parse_int("JvmtiExport flag") != 0;
1097     if (strcmp(field, "can_access_local_variables") == 0) {
1098       JvmtiExport::set_can_access_local_variables(value);
1099     } else if (strcmp(field, "can_hotswap_or_post_breakpoint") == 0) {
1100       JvmtiExport::set_can_hotswap_or_post_breakpoint(value);
1101     } else if (strcmp(field, "can_post_on_exceptions") == 0) {
1102       JvmtiExport::set_can_post_on_exceptions(value);
1103     } else {
1104       report_error("Unrecognized JvmtiExport directive");
1105     }
1106   }

  24 
  25 #include "precompiled.hpp"
  26 #include "jvm.h"
  27 #include "ci/ciMethodData.hpp"
  28 #include "ci/ciReplay.hpp"
  29 #include "ci/ciSymbol.hpp"
  30 #include "ci/ciKlass.hpp"
  31 #include "ci/ciUtilities.inline.hpp"
  32 #include "classfile/javaClasses.hpp"
  33 #include "classfile/symbolTable.hpp"
  34 #include "classfile/systemDictionary.hpp"
  35 #include "compiler/compilationPolicy.hpp"
  36 #include "compiler/compileBroker.hpp"
  37 #include "interpreter/linkResolver.hpp"
  38 #include "memory/allocation.inline.hpp"
  39 #include "memory/oopFactory.hpp"
  40 #include "memory/resourceArea.hpp"
  41 #include "oops/constantPool.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 "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 "utilities/copy.hpp"
  55 #include "utilities/macros.hpp"
  56 #include "utilities/utf8.hpp"
  57 
  58 #ifndef PRODUCT
  59 
  60 // ciReplay
  61 
  62 typedef struct _ciMethodDataRecord {
  63   const char* _klass_name;
  64   const char* _method_name;

 909     ConstantPool* cp = k->constants();
 910     if (length != cp->length()) {
 911       report_error("constant pool length mismatch: wrong class files?");
 912       return;
 913     }
 914 
 915     int parsed_two_word = 0;
 916     for (int i = 1; i < length; i++) {
 917       int tag = parse_int("tag");
 918       if (had_error()) {
 919         return;
 920       }
 921       switch (cp->tag_at(i).value()) {
 922         case JVM_CONSTANT_UnresolvedClass: {
 923           if (tag == JVM_CONSTANT_Class) {
 924             tty->print_cr("Resolving klass %s at %d", cp->klass_name_at(i)->as_utf8(), i);
 925             Klass* k = cp->klass_at(i, CHECK);
 926           }
 927           break;
 928         }
 929 
 930         case JVM_CONSTANT_Long:
 931         case JVM_CONSTANT_Double:
 932           parsed_two_word = i + 1;
 933 
 934         case JVM_CONSTANT_ClassIndex:
 935         case JVM_CONSTANT_StringIndex:
 936         case JVM_CONSTANT_String:
 937         case JVM_CONSTANT_UnresolvedClassInError:
 938         case JVM_CONSTANT_Fieldref:
 939         case JVM_CONSTANT_Methodref:
 940         case JVM_CONSTANT_InterfaceMethodref:
 941         case JVM_CONSTANT_NameAndType:
 942         case JVM_CONSTANT_Utf8:
 943         case JVM_CONSTANT_Integer:
 944         case JVM_CONSTANT_Float:
 945         case JVM_CONSTANT_MethodHandle:
 946         case JVM_CONSTANT_MethodType:
 947         case JVM_CONSTANT_Dynamic:
 948         case JVM_CONSTANT_InvokeDynamic:
 949           if (tag != cp->tag_at(i).value()) {

 956           if (tag == JVM_CONSTANT_Class) {
 957           } else if (tag == JVM_CONSTANT_UnresolvedClass) {
 958             tty->print_cr("Warning: entry was unresolved in the replay data");
 959           } else {
 960             report_error("Unexpected tag");
 961             return;
 962           }
 963           break;
 964 
 965         case 0:
 966           if (parsed_two_word == i) continue;
 967 
 968         default:
 969           fatal("Unexpected tag: %d", cp->tag_at(i).value());
 970           break;
 971       }
 972 
 973     }
 974   }
 975 
 976   class InlineTypeFieldInitializer : public FieldClosure {
 977     oop _vt;
 978     CompileReplay* _replay;
 979   public:
 980     InlineTypeFieldInitializer(oop vt, CompileReplay* replay)
 981   : _vt(vt), _replay(replay) {}
 982 
 983     void do_field(fieldDescriptor* fd) {
 984       BasicType bt = fd->field_type();
 985       const char* string_value = bt != T_INLINE_TYPE ? _replay->parse_escaped_string() : NULL;
 986       switch (bt) {
 987       case T_BYTE: {
 988         int value = atoi(string_value);
 989         _vt->byte_field_put(fd->offset(), value);
 990         break;
 991       }
 992       case T_BOOLEAN: {
 993         int value = atoi(string_value);
 994         _vt->bool_field_put(fd->offset(), value);
 995         break;
 996       }
 997       case T_SHORT: {
 998         int value = atoi(string_value);
 999         _vt->short_field_put(fd->offset(), value);
1000         break;
1001       }
1002       case T_CHAR: {
1003         int value = atoi(string_value);
1004         _vt->char_field_put(fd->offset(), value);
1005         break;
1006       }
1007       case T_INT: {
1008         int value = atoi(string_value);
1009         _vt->int_field_put(fd->offset(), value);
1010         break;
1011       }
1012       case T_LONG: {
1013         jlong value;
1014         if (sscanf(string_value, JLONG_FORMAT, &value) != 1) {
1015           fprintf(stderr, "Error parsing long: %s\n", string_value);
1016           break;
1017         }
1018         _vt->long_field_put(fd->offset(), value);
1019         break;
1020       }
1021       case T_FLOAT: {
1022         float value = atof(string_value);
1023         _vt->float_field_put(fd->offset(), value);
1024         break;
1025       }
1026       case T_DOUBLE: {
1027         double value = atof(string_value);
1028         _vt->double_field_put(fd->offset(), value);
1029         break;
1030       }
1031       case T_ARRAY:
1032       case T_OBJECT: {
1033         JavaThread* THREAD = JavaThread::current();
1034         bool res = _replay->process_staticfield_reference(string_value, _vt, fd, THREAD);
1035         assert(res, "should succeed for arrays & objects");
1036         break;
1037       }
1038       case T_INLINE_TYPE: {
1039         InlineKlass* vk = InlineKlass::cast(fd->field_holder()->get_inline_type_field_klass(fd->index()));
1040         if (fd->is_inlined()) {
1041           int field_offset = fd->offset() - vk->first_field_offset();
1042           oop obj = cast_to_oop(cast_from_oop<address>(_vt) + field_offset);
1043           InlineTypeFieldInitializer init_fields(obj, _replay);
1044           vk->do_nonstatic_fields(&init_fields);
1045         } else {
1046           oop value = vk->allocate_instance(JavaThread::current());
1047           _vt->obj_field_put(fd->offset(), value);
1048         }
1049         break;
1050       }
1051       default: {
1052         fatal("Unhandled type: %s", type2name(bt));
1053       }
1054       }
1055     }
1056   };
1057 
1058   bool process_staticfield_reference(const char* field_signature, oop java_mirror, fieldDescriptor* fd, TRAPS) {
1059     if (field_signature[0] == JVM_SIGNATURE_ARRAY) {
1060       int length = parse_int("array length");
1061       oop value = NULL;
1062 
1063       if (field_signature[1] == JVM_SIGNATURE_ARRAY) {
1064         // multi dimensional array
1065         Klass* k = resolve_klass(field_signature, CHECK_(true));
1066         ArrayKlass* kelem = (ArrayKlass *)k;


1067         int rank = 0;
1068         while (field_signature[rank] == JVM_SIGNATURE_ARRAY) {
1069           rank++;
1070         }
1071         jint* dims = NEW_RESOURCE_ARRAY(jint, rank);
1072         dims[0] = length;
1073         for (int i = 1; i < rank; i++) {
1074           dims[i] = 1; // These aren't relevant to the compiler
1075         }
1076         value = kelem->multi_allocate(rank, dims, CHECK_(true));
1077       } else {
1078         if (strcmp(field_signature, "[B") == 0) {
1079           value = oopFactory::new_byteArray(length, CHECK_(true));
1080         } else if (strcmp(field_signature, "[Z") == 0) {
1081           value = oopFactory::new_boolArray(length, CHECK_(true));
1082         } else if (strcmp(field_signature, "[C") == 0) {
1083           value = oopFactory::new_charArray(length, CHECK_(true));
1084         } else if (strcmp(field_signature, "[S") == 0) {
1085           value = oopFactory::new_shortArray(length, CHECK_(true));
1086         } else if (strcmp(field_signature, "[F") == 0) {
1087           value = oopFactory::new_floatArray(length, CHECK_(true));
1088         } else if (strcmp(field_signature, "[D") == 0) {
1089           value = oopFactory::new_doubleArray(length, CHECK_(true));
1090         } else if (strcmp(field_signature, "[I") == 0) {
1091           value = oopFactory::new_intArray(length, CHECK_(true));
1092         } else if (strcmp(field_signature, "[J") == 0) {
1093           value = oopFactory::new_longArray(length, CHECK_(true));
1094         } else if (field_signature[0] == JVM_SIGNATURE_ARRAY &&
1095                    field_signature[1] == JVM_SIGNATURE_CLASS) {
1096           Klass* kelem = resolve_klass(field_signature + 1, CHECK_(true));
1097           value = oopFactory::new_objArray(kelem, length, CHECK_(true));
1098         } else if (field_signature[0] == JVM_SIGNATURE_ARRAY &&
1099                    field_signature[1] == JVM_SIGNATURE_INLINE_TYPE) {
1100           Klass* kelem = resolve_klass(field_signature + 1, CHECK_(true));
1101           value = oopFactory::new_flatArray(kelem, length, CHECK_(true));
1102         } else {
1103           report_error("unhandled array staticfield");
1104         }
1105       }
1106       java_mirror->obj_field_put(fd->offset(), value);
1107       return true;
1108     } else if (strcmp(field_signature, "Ljava/lang/String;") == 0) {
1109       const char* string_value = parse_escaped_string();
1110       Handle value = java_lang_String::create_from_str(string_value, CHECK_(true));
1111       java_mirror->obj_field_put(fd->offset(), value());
1112       return true;
1113     } else if (field_signature[0] == 'L') {
1114       const char* instance = parse_escaped_string();
1115       Klass* k = resolve_klass(instance, CHECK_(true));
1116       oop value = InstanceKlass::cast(k)->allocate_instance(CHECK_(true));
1117       java_mirror->obj_field_put(fd->offset(), value);
1118       return true;
1119     }
1120     return false;
1121   }
1122 
1123   // Initialize a class and fill in the value for a static field.
1124   // This is useful when the compile was dependent on the value of
1125   // static fields but it's impossible to properly rerun the static
1126   // initializer.
1127   void process_staticfield(TRAPS) {
1128     InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK);
1129 
1130     if (k == NULL || ReplaySuppressInitializers == 0 ||
1131         (ReplaySuppressInitializers == 2 && k->class_loader() == NULL)) {
1132       return;
1133     }
1134 
1135     assert(k->is_initialized(), "must be");
1136 
1137     const char* field_name = parse_escaped_string();
1138     const char* field_signature = parse_string();
1139     fieldDescriptor fd;
1140     Symbol* name = SymbolTable::new_symbol(field_name);
1141     Symbol* sig = SymbolTable::new_symbol(field_signature);
1142     if (!k->find_local_field(name, sig, &fd) ||
1143         !fd.is_static() ||
1144         fd.has_initial_value()) {
1145       report_error(field_name);
1146       return;
1147     }
1148 
1149     oop java_mirror = k->java_mirror();
1150     if (strcmp(field_signature, "I") == 0) {
1151       const char* string_value = parse_escaped_string();
1152       int value = atoi(string_value);
1153       java_mirror->int_field_put(fd.offset(), value);
1154     } else if (strcmp(field_signature, "B") == 0) {
1155       const char* string_value = parse_escaped_string();
1156       int value = atoi(string_value);
1157       java_mirror->byte_field_put(fd.offset(), value);
1158     } else if (strcmp(field_signature, "C") == 0) {
1159       const char* string_value = parse_escaped_string();
1160       int value = atoi(string_value);
1161       java_mirror->char_field_put(fd.offset(), value);
1162     } else if (strcmp(field_signature, "S") == 0) {
1163       const char* string_value = parse_escaped_string();
1164       int value = atoi(string_value);
1165       java_mirror->short_field_put(fd.offset(), value);
1166     } else if (strcmp(field_signature, "Z") == 0) {
1167       const char* string_value = parse_escaped_string();
1168       int value = atoi(string_value);
1169       java_mirror->bool_field_put(fd.offset(), value);
1170     } else if (strcmp(field_signature, "J") == 0) {
1171       const char* string_value = parse_escaped_string();
1172       jlong value;
1173       if (sscanf(string_value, JLONG_FORMAT, &value) != 1) {
1174         fprintf(stderr, "Error parsing long: %s\n", string_value);
1175         return;
1176       }
1177       java_mirror->long_field_put(fd.offset(), value);
1178     } else if (strcmp(field_signature, "F") == 0) {
1179       const char* string_value = parse_escaped_string();
1180       float value = atof(string_value);
1181       java_mirror->float_field_put(fd.offset(), value);
1182     } else if (strcmp(field_signature, "D") == 0) {
1183       const char* string_value = parse_escaped_string();
1184       double value = atof(string_value);
1185       java_mirror->double_field_put(fd.offset(), value);
1186     } else if (field_signature[0] == JVM_SIGNATURE_INLINE_TYPE) {
1187       Klass* kelem = resolve_klass(field_signature, CHECK);
1188       InlineKlass* vk = InlineKlass::cast(kelem);
1189       oop value = vk->allocate_instance(CHECK);
1190       InlineTypeFieldInitializer init_fields(value, this);
1191       vk->do_nonstatic_fields(&init_fields);
1192       java_mirror->obj_field_put(fd.offset(), value);
1193     } else {
1194       bool res = process_staticfield_reference(field_signature, java_mirror, &fd, CHECK);
1195       if (!res)  {



































1196         report_error("unhandled staticfield");
1197       }
1198     }
1199   }
1200 
1201 #if INCLUDE_JVMTI
1202   // JvmtiExport <field> <value>
1203   void process_JvmtiExport(TRAPS) {
1204     const char* field = parse_string();
1205     bool value = parse_int("JvmtiExport flag") != 0;
1206     if (strcmp(field, "can_access_local_variables") == 0) {
1207       JvmtiExport::set_can_access_local_variables(value);
1208     } else if (strcmp(field, "can_hotswap_or_post_breakpoint") == 0) {
1209       JvmtiExport::set_can_hotswap_or_post_breakpoint(value);
1210     } else if (strcmp(field, "can_post_on_exceptions") == 0) {
1211       JvmtiExport::set_can_post_on_exceptions(value);
1212     } else {
1213       report_error("Unrecognized JvmtiExport directive");
1214     }
1215   }
< prev index next >