src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp
changeset 52334 a181612f0715
parent 51334 cc2c79d22508
child 52671 600fca45232b
equal deleted inserted replaced
52333:c401c536cea1 52334:a181612f0715
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
    26 #include "jvm.h"
    26 #include "jvm.h"
    27 #include "classfile/classFileParser.hpp"
    27 #include "classfile/classFileParser.hpp"
    28 #include "classfile/classFileStream.hpp"
    28 #include "classfile/classFileStream.hpp"
    29 #include "classfile/javaClasses.inline.hpp"
    29 #include "classfile/javaClasses.inline.hpp"
       
    30 #include "classfile/moduleEntry.hpp"
       
    31 #include "classfile/modules.hpp"
    30 #include "classfile/stackMapTable.hpp"
    32 #include "classfile/stackMapTable.hpp"
    31 #include "classfile/verificationType.hpp"
    33 #include "classfile/verificationType.hpp"
    32 #include "interpreter/bytecodes.hpp"
    34 #include "interpreter/bytecodes.hpp"
    33 #include "jfr/instrumentation/jfrEventClassTransformer.hpp"
    35 #include "jfr/instrumentation/jfrEventClassTransformer.hpp"
    34 #include "jfr/jfr.hpp"
    36 #include "jfr/jfr.hpp"
    59 static const char* utf8_constants[] = {
    61 static const char* utf8_constants[] = {
    60   "Code",         // 0
    62   "Code",         // 0
    61   "J",            // 1
    63   "J",            // 1
    62   "commit",       // 2
    64   "commit",       // 2
    63   "eventHandler", // 3
    65   "eventHandler", // 3
    64   "Ljdk/jfr/internal/handlers/EventHandler;", // 4
    66   "duration",     // 4
    65   "duration",     // 5
    67   "begin",        // 5
    66   "begin",        // 6
    68   "()V",          // 6
    67   "()V",          // 7
    69   "isEnabled",    // 7
    68   "isEnabled",    // 8
    70   "()Z",          // 8
    69   "()Z",          // 9
    71   "end",          // 9
    70   "end",          // 10
    72   "shouldCommit", // 10
    71   "shouldCommit", // 11
    73   "startTime",    // 11 // LAST_REQUIRED_UTF8
    72   "startTime",    // 12
    74   "Ljdk/jfr/internal/handlers/EventHandler;", // 12
    73   "<clinit>",     // 13
    75   "Ljava/lang/Object;", // 13
    74   "jdk/jfr/FlightRecorder", // 14
    76   "<clinit>",     // 14
    75   "register", // 15
    77   "jdk/jfr/FlightRecorder", // 15
    76   "(Ljava/lang/Class;)V", // 16 // LAST_REQUIRED_UTF8
    78   "register",     // 16
    77   "StackMapTable", // 17
    79   "(Ljava/lang/Class;)V", // 17
    78   "Exceptions", // 18
    80   "StackMapTable", // 18
       
    81   "Exceptions", // 19
    79   "LineNumberTable", // 20
    82   "LineNumberTable", // 20
    80   "LocalVariableTable", // 21
    83   "LocalVariableTable", // 21
    81   "LocalVariableTypeTable", // 22
    84   "LocalVariableTypeTable", // 22
    82   "RuntimeVisibleAnnotation" // 23
    85   "RuntimeVisibleAnnotation", // 23
    83 };
    86 };
    84 
    87 
    85 enum utf8_req_symbols {
    88 enum utf8_req_symbols {
    86   UTF8_REQ_Code,
    89   UTF8_REQ_Code,
    87   UTF8_REQ_J_FIELD_DESC,
    90   UTF8_REQ_J_FIELD_DESC,
    88   UTF8_REQ_commit,
    91   UTF8_REQ_commit,
    89   UTF8_REQ_eventHandler,
    92   UTF8_REQ_eventHandler,
    90   UTF8_REQ_eventHandler_FIELD_DESC,
       
    91   UTF8_REQ_duration,
    93   UTF8_REQ_duration,
    92   UTF8_REQ_begin,
    94   UTF8_REQ_begin,
    93   UTF8_REQ_EMPTY_VOID_METHOD_DESC,
    95   UTF8_REQ_EMPTY_VOID_METHOD_DESC,
    94   UTF8_REQ_isEnabled,
    96   UTF8_REQ_isEnabled,
    95   UTF8_REQ_EMPTY_BOOLEAN_METHOD_DESC,
    97   UTF8_REQ_EMPTY_BOOLEAN_METHOD_DESC,
    96   UTF8_REQ_end,
    98   UTF8_REQ_end,
    97   UTF8_REQ_shouldCommit,
    99   UTF8_REQ_shouldCommit,
    98   UTF8_REQ_startTime,
   100   UTF8_REQ_startTime,
    99   UTF8_REQ_clinit,
       
   100   UTF8_REQ_FlightRecorder,
       
   101   UTF8_REQ_register,
       
   102   UTF8_REQ_CLASS_VOID_METHOD_DESC,
       
   103   NOF_UTF8_REQ_SYMBOLS
   101   NOF_UTF8_REQ_SYMBOLS
   104 };
   102 };
   105 
   103 
   106 enum utf8_opt_symbols {
   104 enum utf8_opt_symbols {
   107   UTF8_OPT_StackMapTable = NOF_UTF8_REQ_SYMBOLS,
   105   UTF8_OPT_eventHandler_FIELD_DESC = NOF_UTF8_REQ_SYMBOLS,
       
   106   UTF8_OPT_LjavaLangObject,
       
   107   UTF8_OPT_clinit,
       
   108   UTF8_OPT_FlightRecorder,
       
   109   UTF8_OPT_register,
       
   110   UTF8_OPT_CLASS_VOID_METHOD_DESC,
       
   111   UTF8_OPT_StackMapTable,
   108   UTF8_OPT_Exceptions,
   112   UTF8_OPT_Exceptions,
   109   UTF8_OPT_LineNumberTable,
   113   UTF8_OPT_LineNumberTable,
   110   UTF8_OPT_LocalVariableTable,
   114   UTF8_OPT_LocalVariableTable,
   111   UTF8_OPT_LocalVariableTypeTable,
   115   UTF8_OPT_LocalVariableTypeTable,
   112   UTF8_OPT_RuntimeVisibleAnnotation,
   116   UTF8_OPT_RuntimeVisibleAnnotation,
   351   }
   355   }
   352 };
   356 };
   353 
   357 
   354 static unsigned int unused_hash = 0;
   358 static unsigned int unused_hash = 0;
   355 static const char value_name[] = "value";
   359 static const char value_name[] = "value";
   356 static bool has_registered_annotation(const InstanceKlass* ik, const Symbol* annotation_type, bool& value) {
   360 static bool has_annotation(const InstanceKlass* ik, const Symbol* annotation_type, bool& value) {
   357   assert(annotation_type != NULL, "invariant");
   361   assert(annotation_type != NULL, "invariant");
   358   AnnotationArray* class_annotations = ik->class_annotations();
   362   AnnotationArray* class_annotations = ik->class_annotations();
   359   if (class_annotations == NULL) {
   363   if (class_annotations == NULL) {
   360     return false;
   364     return false;
   361   }
   365   }
   381     }
   385     }
   382   }
   386   }
   383   return false;
   387   return false;
   384 }
   388 }
   385 
   389 
   386 static bool registered_annotation_value(const InstanceKlass* ik, const Symbol* const registered_symbol) {
   390 // Evaluate to the value of the first found Symbol* annotation type.
   387   assert(registered_symbol != NULL, "invariant");
   391 // Searching moves upwards in the klass hierarchy in order to support
       
   392 // inherited annotations in addition to the ability to override.
       
   393 static bool annotation_value(const InstanceKlass* ik, const Symbol* annotation_type, bool& value) {
   388   assert(ik != NULL, "invariant");
   394   assert(ik != NULL, "invariant");
       
   395   assert(annotation_type != NULL, "invariant");
   389   assert(JdkJfrEvent::is_a(ik), "invariant");
   396   assert(JdkJfrEvent::is_a(ik), "invariant");
   390   bool registered_value = false;
   397   if (has_annotation(ik, annotation_type, value)) {
   391   if (has_registered_annotation(ik, registered_symbol, registered_value)) {
   398     return true;
   392     return registered_value;
   399   }
   393   }
   400   InstanceKlass* const super = InstanceKlass::cast(ik->super());
   394   InstanceKlass* super = InstanceKlass::cast(ik->super());
   401   return super != NULL && JdkJfrEvent::is_a(super) ? annotation_value(super, annotation_type, value) : false;
   395   return registered_annotation_value(super, registered_symbol);
   402 }
       
   403 
       
   404 static const char jdk_jfr_module_name[] = "jdk.jfr";
       
   405 
       
   406 static bool java_base_can_read_jdk_jfr() {
       
   407   static bool can_read = false;
       
   408   if (can_read) {
       
   409     return true;
       
   410   }
       
   411   static Symbol* jdk_jfr_module_symbol = NULL;
       
   412   if (jdk_jfr_module_symbol == NULL) {
       
   413     jdk_jfr_module_symbol = SymbolTable::lookup_only(jdk_jfr_module_name, sizeof jdk_jfr_module_name - 1, unused_hash);
       
   414     if (jdk_jfr_module_symbol == NULL) {
       
   415       return false;
       
   416     }
       
   417   }
       
   418   assert(jdk_jfr_module_symbol != NULL, "invariant");
       
   419   ModuleEntryTable* const table = Modules::get_module_entry_table(Handle());
       
   420   assert(table != NULL, "invariant");
       
   421   const ModuleEntry* const java_base_module = table->javabase_moduleEntry();
       
   422   if (java_base_module == NULL) {
       
   423     return false;
       
   424   }
       
   425   assert(java_base_module != NULL, "invariant");
       
   426   ModuleEntry* const jdk_jfr_module = table->lookup_only(jdk_jfr_module_symbol);
       
   427   if (jdk_jfr_module == NULL) {
       
   428     return false;
       
   429   }
       
   430   assert(jdk_jfr_module != NULL, "invariant");
       
   431   if (java_base_module->can_read(jdk_jfr_module)) {
       
   432     can_read = true;
       
   433   }
       
   434   return can_read;
   396 }
   435 }
   397 
   436 
   398 static const char registered_constant[] = "Ljdk/jfr/Registered;";
   437 static const char registered_constant[] = "Ljdk/jfr/Registered;";
   399 
   438 
   400 // Evaluate to the value of the first found "Ljdk/jfr/Registered;" annotation.
   439 // Evaluate to the value of the first found "Ljdk/jfr/Registered;" annotation.
   401 // Searching moves upwards in the klass hierarchy in order to support
   440 // Searching moves upwards in the klass hierarchy in order to support
   402 // inherited annotations in addition to the ability to override.
   441 // inherited annotations in addition to the ability to override.
   403 static bool should_register_klass(const InstanceKlass* ik) {
   442 static bool should_register_klass(const InstanceKlass* ik, bool& untypedEventHandler) {
   404   static const Symbol* const registered_symbol = SymbolTable::lookup_only(registered_constant,
   443   assert(ik != NULL, "invariant");
   405                                                                           sizeof registered_constant - 1,
   444   assert(JdkJfrEvent::is_a(ik), "invariant");
   406                                                                           unused_hash);
   445   assert(!untypedEventHandler, "invariant");
       
   446   static const Symbol* registered_symbol = NULL;
       
   447   if (registered_symbol == NULL) {
       
   448     registered_symbol = SymbolTable::lookup_only(registered_constant, sizeof registered_constant - 1, unused_hash);
       
   449     if (registered_symbol == NULL) {
       
   450       return false;
       
   451     }
       
   452   }
   407   assert(registered_symbol != NULL, "invariant");
   453   assert(registered_symbol != NULL, "invariant");
   408   return registered_annotation_value(ik, registered_symbol);
   454   bool value = false; // to be set by annotation_value
   409 }
   455   untypedEventHandler = !(annotation_value(ik, registered_symbol, value) || java_base_can_read_jdk_jfr());
       
   456   return value;
       
   457 }
       
   458 
   410 /*
   459 /*
   411  * Map an utf8 constant back to its CONSTANT_UTF8_INFO
   460  * Map an utf8 constant back to its CONSTANT_UTF8_INFO
   412  */
   461  */
   413 static u2 utf8_info_index(const InstanceKlass* ik, const Symbol* const target, TRAPS) {
   462 static u2 utf8_info_index(const InstanceKlass* ik, const Symbol* const target, TRAPS) {
   414   assert(target != NULL, "invariant");
   463   assert(target != NULL, "invariant");
   448                               u2 method_index,
   497                               u2 method_index,
   449                               u2 desc_index,
   498                               u2 desc_index,
   450                               u2 orig_cp_len,
   499                               u2 orig_cp_len,
   451                               u2& number_of_new_constants,
   500                               u2& number_of_new_constants,
   452                               TRAPS) {
   501                               TRAPS) {
       
   502   assert(cls_name_index != invalid_cp_index, "invariant");
       
   503   assert(method_index != invalid_cp_index, "invariant");
       
   504   assert(desc_index != invalid_cp_index, "invariant");
   453   assert(is_index_within_range(cls_name_index, orig_cp_len, number_of_new_constants), "invariant");
   505   assert(is_index_within_range(cls_name_index, orig_cp_len, number_of_new_constants), "invariant");
   454   assert(is_index_within_range(method_index, orig_cp_len, number_of_new_constants), "invariant");
   506   assert(is_index_within_range(method_index, orig_cp_len, number_of_new_constants), "invariant");
   455   assert(is_index_within_range(desc_index, orig_cp_len, number_of_new_constants), "invariant");
   507   assert(is_index_within_range(desc_index, orig_cp_len, number_of_new_constants), "invariant");
   456   writer.write<u1>(JVM_CONSTANT_Class);
   508   writer.write<u1>(JVM_CONSTANT_Class);
   457   writer.write<u2>(cls_name_index);
   509   writer.write<u2>(cls_name_index);
   475                                             u2 orig_cp_len,
   527                                             u2 orig_cp_len,
   476                                             u2& number_of_new_constants,
   528                                             u2& number_of_new_constants,
   477                                             TRAPS) {
   529                                             TRAPS) {
   478   assert(utf8_indexes != NULL, "invariant");
   530   assert(utf8_indexes != NULL, "invariant");
   479   return add_method_ref_info(writer,
   531   return add_method_ref_info(writer,
   480                              utf8_indexes[UTF8_REQ_FlightRecorder],
   532                              utf8_indexes[UTF8_OPT_FlightRecorder],
   481                              utf8_indexes[UTF8_REQ_register],
   533                              utf8_indexes[UTF8_OPT_register],
   482                              utf8_indexes[UTF8_REQ_CLASS_VOID_METHOD_DESC],
   534                              utf8_indexes[UTF8_OPT_CLASS_VOID_METHOD_DESC],
   483                              orig_cp_len,
   535                              orig_cp_len,
   484                              number_of_new_constants,
   536                              number_of_new_constants,
   485                              THREAD);
   537                              THREAD);
   486 }
   538 }
   487 
   539 
   493  *   u2             attributes_count;
   545  *   u2             attributes_count;
   494  *   attribute_info attributes[attributes_count];
   546  *   attribute_info attributes[attributes_count];
   495  * }
   547  * }
   496  */
   548  */
   497 static jlong add_field_info(JfrBigEndianWriter& writer, u2 name_index, u2 desc_index, bool is_static = false) {
   549 static jlong add_field_info(JfrBigEndianWriter& writer, u2 name_index, u2 desc_index, bool is_static = false) {
   498   assert(name_index > 0, "invariant");
   550   assert(name_index != invalid_cp_index, "invariant");
   499   assert(desc_index > 0, "invariant");
   551   assert(desc_index != invalid_cp_index, "invariant");
   500   DEBUG_ONLY(const jlong start_offset = writer.current_offset();)
   552   DEBUG_ONLY(const jlong start_offset = writer.current_offset();)
   501   writer.write<u2>(JVM_ACC_SYNTHETIC | JVM_ACC_PRIVATE | (is_static ? JVM_ACC_STATIC : JVM_ACC_TRANSIENT)); // flags
   553   writer.write<u2>(JVM_ACC_SYNTHETIC | JVM_ACC_PRIVATE | (is_static ? JVM_ACC_STATIC : JVM_ACC_TRANSIENT)); // flags
   502   writer.write(name_index);
   554   writer.write(name_index);
   503   writer.write(desc_index);
   555   writer.write(desc_index);
   504   writer.write((u2)0x0); // attributes_count
   556   writer.write((u2)0x0); // attributes_count
   505   assert(writer.is_valid(), "invariant");
   557   assert(writer.is_valid(), "invariant");
   506   DEBUG_ONLY(assert(start_offset + 8 == writer.current_offset(), "invariant");)
   558   DEBUG_ONLY(assert(start_offset + 8 == writer.current_offset(), "invariant");)
   507   return writer.current_offset();
   559   return writer.current_offset();
   508 }
   560 }
   509 
   561 
   510 static u2 add_field_infos(JfrBigEndianWriter& writer, const u2* utf8_indexes) {
   562 static u2 add_field_infos(JfrBigEndianWriter& writer, const u2* utf8_indexes, bool untypedEventHandler) {
   511   assert(utf8_indexes != NULL, "invariant");
   563   assert(utf8_indexes != NULL, "invariant");
   512   add_field_info(writer,
   564   add_field_info(writer,
   513                  utf8_indexes[UTF8_REQ_eventHandler],
   565                  utf8_indexes[UTF8_REQ_eventHandler],
   514                  utf8_indexes[UTF8_REQ_eventHandler_FIELD_DESC],
   566                  untypedEventHandler ? utf8_indexes[UTF8_OPT_LjavaLangObject] : utf8_indexes[UTF8_OPT_eventHandler_FIELD_DESC],
   515                  true); // static
   567                  true); // static
   516 
   568 
   517   add_field_info(writer,
   569   add_field_info(writer,
   518                  utf8_indexes[UTF8_REQ_startTime],
   570                  utf8_indexes[UTF8_REQ_startTime],
   519                  utf8_indexes[UTF8_REQ_J_FIELD_DESC]);
   571                  utf8_indexes[UTF8_REQ_J_FIELD_DESC]);
   987   assert(utf8_indexes != NULL, "invariant");
  1039   assert(utf8_indexes != NULL, "invariant");
   988   // The injected code length is always this value.
  1040   // The injected code length is always this value.
   989   // This is to ensure that padding can be done
  1041   // This is to ensure that padding can be done
   990   // where needed and to simplify size calculations.
  1042   // where needed and to simplify size calculations.
   991   static const u2 injected_code_length = 8;
  1043   static const u2 injected_code_length = 8;
   992   const u2 name_index = utf8_indexes[UTF8_REQ_clinit];
  1044   const u2 name_index = utf8_indexes[UTF8_OPT_clinit];
       
  1045   assert(name_index != invalid_cp_index, "invariant");
   993   const u2 desc_index = utf8_indexes[UTF8_REQ_EMPTY_VOID_METHOD_DESC];
  1046   const u2 desc_index = utf8_indexes[UTF8_REQ_EMPTY_VOID_METHOD_DESC];
   994   const u2 max_stack = MAX2(clinit_method != NULL ? clinit_method->verifier_max_stack() : 1, 1);
  1047   const u2 max_stack = MAX2(clinit_method != NULL ? clinit_method->verifier_max_stack() : 1, 1);
   995   const u2 max_locals = MAX2(clinit_method != NULL ? clinit_method->max_locals() : 0, 0);
  1048   const u2 max_locals = MAX2(clinit_method != NULL ? clinit_method->max_locals() : 0, 0);
   996   const u2 orig_bytecodes_length = clinit_method != NULL ? (u2)clinit_method->code_size() : 0;
  1049   const u2 orig_bytecodes_length = clinit_method != NULL ? (u2)clinit_method->code_size() : 0;
   997   const address orig_bytecodes = clinit_method != NULL ? clinit_method->code_base() : NULL;
  1050   const address orig_bytecodes = clinit_method != NULL ? clinit_method->code_base() : NULL;
  1136 static u2 resolve_utf8_indexes(JfrBigEndianWriter& writer,
  1189 static u2 resolve_utf8_indexes(JfrBigEndianWriter& writer,
  1137                                const InstanceKlass* ik,
  1190                                const InstanceKlass* ik,
  1138                                u2* const utf8_indexes,
  1191                                u2* const utf8_indexes,
  1139                                u2 orig_cp_len,
  1192                                u2 orig_cp_len,
  1140                                const Method* clinit_method,
  1193                                const Method* clinit_method,
       
  1194                                bool register_klass,
       
  1195                                bool untypedEventHandler,
  1141                                TRAPS) {
  1196                                TRAPS) {
  1142   assert(utf8_indexes != NULL, "invariant");
  1197   assert(utf8_indexes != NULL, "invariant");
  1143   u2 added_cp_entries = 0;
  1198   u2 added_cp_entries = 0;
  1144   // resolve all required symbols
  1199   // resolve all required symbols
  1145   for (u2 index = 0; index < NOF_UTF8_REQ_SYMBOLS; ++index) {
  1200   for (u2 index = 0; index < NOF_UTF8_REQ_SYMBOLS; ++index) {
  1146     utf8_indexes[index] = find_or_add_utf8_info(writer,
  1201     utf8_indexes[index] = find_or_add_utf8_info(writer, ik, utf8_constants[index], orig_cp_len, added_cp_entries, THREAD);
  1147                                                 ik,
  1202   }
  1148                                                 utf8_constants[index],
  1203 
  1149                                                 orig_cp_len,
  1204   // resolve optional constants
  1150                                                 added_cp_entries,
  1205   utf8_indexes[UTF8_OPT_eventHandler_FIELD_DESC] = untypedEventHandler ? invalid_cp_index :
  1151                                                 THREAD);
  1206     find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_eventHandler_FIELD_DESC], orig_cp_len, added_cp_entries, THREAD);
  1152   }
  1207 
  1153   // Now determine optional constants (mainly "Code" attributes)
  1208   utf8_indexes[UTF8_OPT_LjavaLangObject] = untypedEventHandler ?
       
  1209     find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_LjavaLangObject], orig_cp_len, added_cp_entries, THREAD) : invalid_cp_index;
       
  1210 
       
  1211   if (register_klass) {
       
  1212     utf8_indexes[UTF8_OPT_clinit] =
       
  1213       find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_clinit], orig_cp_len, added_cp_entries, THREAD);
       
  1214     utf8_indexes[UTF8_OPT_FlightRecorder] =
       
  1215       find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_FlightRecorder], orig_cp_len, added_cp_entries, THREAD);
       
  1216     utf8_indexes[UTF8_OPT_register] =
       
  1217       find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_register], orig_cp_len, added_cp_entries, THREAD);
       
  1218     utf8_indexes[UTF8_OPT_CLASS_VOID_METHOD_DESC] =
       
  1219       find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_CLASS_VOID_METHOD_DESC], orig_cp_len, added_cp_entries, THREAD);
       
  1220   } else {
       
  1221     utf8_indexes[UTF8_OPT_clinit] = invalid_cp_index;
       
  1222     utf8_indexes[UTF8_OPT_FlightRecorder] = invalid_cp_index;
       
  1223     utf8_indexes[UTF8_OPT_register] = invalid_cp_index;
       
  1224     utf8_indexes[UTF8_OPT_CLASS_VOID_METHOD_DESC] = invalid_cp_index;
       
  1225   }
       
  1226 
  1154   if (clinit_method != NULL && clinit_method->has_stackmap_table()) {
  1227   if (clinit_method != NULL && clinit_method->has_stackmap_table()) {
  1155     utf8_indexes[UTF8_OPT_StackMapTable] =
  1228     utf8_indexes[UTF8_OPT_StackMapTable] =
  1156       find_or_add_utf8_info(writer,
  1229       find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_StackMapTable], orig_cp_len, added_cp_entries, THREAD);
  1157                             ik,
       
  1158                             utf8_constants[UTF8_OPT_StackMapTable],
       
  1159                             orig_cp_len,
       
  1160                             added_cp_entries,
       
  1161                             THREAD);
       
  1162   } else {
  1230   } else {
  1163     utf8_indexes[UTF8_OPT_StackMapTable] = invalid_cp_index;
  1231     utf8_indexes[UTF8_OPT_StackMapTable] = invalid_cp_index;
  1164   }
  1232   }
  1165 
  1233 
  1166   if (clinit_method != NULL && clinit_method->has_linenumber_table()) {
  1234   if (clinit_method != NULL && clinit_method->has_linenumber_table()) {
  1167     utf8_indexes[UTF8_OPT_LineNumberTable] =
  1235     utf8_indexes[UTF8_OPT_LineNumberTable] =
  1168       find_or_add_utf8_info(writer,
  1236       find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_LineNumberTable], orig_cp_len, added_cp_entries, THREAD);
  1169                             ik,
       
  1170                             utf8_constants[UTF8_OPT_LineNumberTable],
       
  1171                             orig_cp_len,
       
  1172                             added_cp_entries,
       
  1173                             THREAD);
       
  1174   } else {
  1237   } else {
  1175     utf8_indexes[UTF8_OPT_LineNumberTable] = invalid_cp_index;
  1238     utf8_indexes[UTF8_OPT_LineNumberTable] = invalid_cp_index;
  1176   }
  1239   }
  1177 
  1240 
  1178   if (clinit_method != NULL && clinit_method->has_localvariable_table()) {
  1241   if (clinit_method != NULL && clinit_method->has_localvariable_table()) {
  1179     utf8_indexes[UTF8_OPT_LocalVariableTable] =
  1242     utf8_indexes[UTF8_OPT_LocalVariableTable] =
  1180       find_or_add_utf8_info(writer,
  1243       find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_LocalVariableTable], orig_cp_len, added_cp_entries, THREAD);
  1181                             ik,
       
  1182                             utf8_constants[UTF8_OPT_LocalVariableTable],
       
  1183                             orig_cp_len,
       
  1184                             added_cp_entries,
       
  1185                             THREAD);
       
  1186 
       
  1187     utf8_indexes[UTF8_OPT_LocalVariableTypeTable] =
  1244     utf8_indexes[UTF8_OPT_LocalVariableTypeTable] =
  1188       find_or_add_utf8_info(writer,
  1245       find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_LocalVariableTypeTable], orig_cp_len, added_cp_entries, THREAD);
  1189                             ik,
       
  1190                             utf8_constants[UTF8_OPT_LocalVariableTypeTable],
       
  1191                             orig_cp_len,
       
  1192                             added_cp_entries,
       
  1193                             THREAD);
       
  1194   } else {
  1246   } else {
  1195     utf8_indexes[UTF8_OPT_LocalVariableTable] = invalid_cp_index;
  1247     utf8_indexes[UTF8_OPT_LocalVariableTable] = invalid_cp_index;
  1196     utf8_indexes[UTF8_OPT_LocalVariableTypeTable] = invalid_cp_index;
  1248     utf8_indexes[UTF8_OPT_LocalVariableTypeTable] = invalid_cp_index;
  1197   }
  1249   }
  1198 
  1250 
  1205                                               TRAPS) {
  1257                                               TRAPS) {
  1206   assert(ik != NULL, "invariant");
  1258   assert(ik != NULL, "invariant");
  1207   // If the class already has a clinit method
  1259   // If the class already has a clinit method
  1208   // we need to take that into account
  1260   // we need to take that into account
  1209   const Method* clinit_method = ik->class_initializer();
  1261   const Method* clinit_method = ik->class_initializer();
  1210   const bool register_klass = should_register_klass(ik);
  1262   bool untypedEventHandler = false;
       
  1263   const bool register_klass = should_register_klass(ik, untypedEventHandler);
  1211   const ClassFileStream* const orig_stream = parser.clone_stream();
  1264   const ClassFileStream* const orig_stream = parser.clone_stream();
  1212   const int orig_stream_size = orig_stream->length();
  1265   const int orig_stream_size = orig_stream->length();
  1213   assert(orig_stream->current_offset() == 0, "invariant");
  1266   assert(orig_stream->current_offset() == 0, "invariant");
  1214   const u2 orig_cp_len = position_stream_after_cp(orig_stream);
  1267   const u2 orig_cp_len = position_stream_after_cp(orig_stream);
  1215   assert(orig_cp_len > 0, "invariant");
  1268   assert(orig_cp_len > 0, "invariant");
  1239   // in order to reference UTF8_INFO's needed
  1292   // in order to reference UTF8_INFO's needed
  1240   u2 utf8_indexes[NOF_UTF8_SYMBOLS];
  1293   u2 utf8_indexes[NOF_UTF8_SYMBOLS];
  1241   // Resolve_utf8_indexes will be conservative in attempting to
  1294   // Resolve_utf8_indexes will be conservative in attempting to
  1242   // locate an existing UTF8_INFO; it will only append constants
  1295   // locate an existing UTF8_INFO; it will only append constants
  1243   // that is absolutely required
  1296   // that is absolutely required
  1244   u2 number_of_new_constants = resolve_utf8_indexes(writer, ik, utf8_indexes, orig_cp_len, clinit_method, THREAD);
  1297   u2 number_of_new_constants =
       
  1298     resolve_utf8_indexes(writer, ik, utf8_indexes, orig_cp_len, clinit_method, register_klass, untypedEventHandler, THREAD);
  1245   // UTF8_INFO entries now added to the constant pool
  1299   // UTF8_INFO entries now added to the constant pool
  1246   // In order to invoke a method we would need additional
  1300   // In order to invoke a method we would need additional
  1247   // constants, JVM_CONSTANT_Class, JVM_CONSTANT_NameAndType
  1301   // constants, JVM_CONSTANT_Class, JVM_CONSTANT_NameAndType
  1248   // and JVM_CONSTANT_Methodref.
  1302   // and JVM_CONSTANT_Methodref.
  1249   const u2 flr_register_method_ref_index =
  1303   const u2 flr_register_method_ref_index =
  1272   // Copy up to and including fields
  1326   // Copy up to and including fields
  1273   writer.bytes(orig_stream->buffer() + orig_fields_len_offset, orig_method_len_offset - orig_fields_len_offset);
  1327   writer.bytes(orig_stream->buffer() + orig_fields_len_offset, orig_method_len_offset - orig_fields_len_offset);
  1274   assert(writer.is_valid(), "invariant");
  1328   assert(writer.is_valid(), "invariant");
  1275   // We are sitting just after the original number of field_infos
  1329   // We are sitting just after the original number of field_infos
  1276   // so this is a position where we can add (append) new field_infos
  1330   // so this is a position where we can add (append) new field_infos
  1277   const u2 number_of_new_fields = add_field_infos(writer, utf8_indexes);
  1331   const u2 number_of_new_fields = add_field_infos(writer, utf8_indexes, untypedEventHandler);
  1278   assert(writer.is_valid(), "invariant");
  1332   assert(writer.is_valid(), "invariant");
  1279   const jlong new_method_len_offset = writer.current_offset();
  1333   const jlong new_method_len_offset = writer.current_offset();
  1280   // Additional field_infos added, update classfile fields_count
  1334   // Additional field_infos added, update classfile fields_count
  1281   writer.write_at_offset<u2>(orig_fields_len + number_of_new_fields, new_fields_len_offset);
  1335   writer.write_at_offset<u2>(orig_fields_len + number_of_new_fields, new_fields_len_offset);
  1282   assert(writer.is_valid(), "invariant");
  1336   assert(writer.is_valid(), "invariant");