1 /* 2 * Copyright (c) 2016, 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 "classfile/classFileParser.hpp" 26 #include "classfile/classFileStream.hpp" 27 #include "classfile/classLoadInfo.hpp" 28 #include "classfile/javaClasses.inline.hpp" 29 #include "classfile/moduleEntry.hpp" 30 #include "classfile/modules.hpp" 31 #include "classfile/stackMapTable.hpp" 32 #include "classfile/symbolTable.hpp" 33 #include "classfile/verificationType.hpp" 34 #include "interpreter/bytecodes.hpp" 35 #include "jvm.h" 36 #include "jfr/instrumentation/jfrEventClassTransformer.hpp" 37 #include "jfr/jfr.hpp" 38 #include "jfr/jni/jfrJavaSupport.hpp" 39 #include "jfr/jni/jfrUpcalls.hpp" 40 #include "jfr/recorder/jfrRecorder.hpp" 41 #include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp" 42 #include "jfr/support/jfrJdkJfrEvent.hpp" 43 #include "jfr/utilities/jfrBigEndian.hpp" 44 #include "jfr/writers/jfrBigEndianWriter.hpp" 45 #include "logging/log.hpp" 46 #include "memory/allocation.inline.hpp" 47 #include "memory/resourceArea.hpp" 48 #include "oops/array.hpp" 49 #include "oops/constMethod.hpp" 50 #include "oops/instanceKlass.hpp" 51 #include "oops/klass.inline.hpp" 52 #include "oops/method.hpp" 53 #include "prims/jvmtiRedefineClasses.hpp" 54 #include "prims/jvmtiThreadState.hpp" 55 #include "runtime/handles.inline.hpp" 56 #include "runtime/javaThread.hpp" 57 #include "runtime/jniHandles.hpp" 58 #include "runtime/os.hpp" 59 #include "utilities/exceptions.hpp" 60 #include "utilities/globalDefinitions.hpp" 61 #include "utilities/growableArray.hpp" 62 #include "utilities/macros.hpp" 63 64 static const u2 number_of_new_methods = 5; 65 static const u2 number_of_new_fields = 3; 66 static const int extra_stream_bytes = 0x280; 67 static const u2 invalid_cp_index = 0; 68 69 static const char* utf8_constants[] = { 70 "Code", // 0 71 "J", // 1 72 "commit", // 2 73 "eventConfiguration", // 3 74 "duration", // 4 75 "begin", // 5 76 "()V", // 6 77 "isEnabled", // 7 78 "()Z", // 8 79 "end", // 9 80 "shouldCommit", // 10 81 "startTime", // 11 // LAST_REQUIRED_UTF8 82 "Ljdk/jfr/internal/event/EventConfiguration;", // 12 83 "Ljava/lang/Object;", // 13 84 "<clinit>", // 14 85 "jdk/jfr/FlightRecorder", // 15 86 "register", // 16 87 "(Ljava/lang/Class;)V", // 17 88 "StackMapTable", // 18 89 "Exceptions", // 19 90 "LineNumberTable", // 20 91 "LocalVariableTable", // 21 92 "LocalVariableTypeTable", // 22 93 "RuntimeVisibleAnnotation", // 23 94 }; 95 96 enum utf8_req_symbols { 97 UTF8_REQ_Code, 98 UTF8_REQ_J_FIELD_DESC, 99 UTF8_REQ_commit, 100 UTF8_REQ_eventConfiguration, 101 UTF8_REQ_duration, 102 UTF8_REQ_begin, 103 UTF8_REQ_EMPTY_VOID_METHOD_DESC, 104 UTF8_REQ_isEnabled, 105 UTF8_REQ_EMPTY_BOOLEAN_METHOD_DESC, 106 UTF8_REQ_end, 107 UTF8_REQ_shouldCommit, 108 UTF8_REQ_startTime, 109 NOF_UTF8_REQ_SYMBOLS 110 }; 111 112 enum utf8_opt_symbols { 113 UTF8_OPT_eventConfiguration_FIELD_DESC = NOF_UTF8_REQ_SYMBOLS, 114 UTF8_OPT_LjavaLangObject, 115 UTF8_OPT_clinit, 116 UTF8_OPT_FlightRecorder, 117 UTF8_OPT_register, 118 UTF8_OPT_CLASS_VOID_METHOD_DESC, 119 UTF8_OPT_StackMapTable, 120 UTF8_OPT_Exceptions, 121 UTF8_OPT_LineNumberTable, 122 UTF8_OPT_LocalVariableTable, 123 UTF8_OPT_LocalVariableTypeTable, 124 UTF8_OPT_RuntimeVisibleAnnotation, 125 NOF_UTF8_SYMBOLS 126 }; 127 128 static u1 empty_void_method_code_attribute[] = { 129 0x0, 130 0x0, 131 0x0, 132 0xd, // attribute len 133 0x0, 134 0x0, // max stack 135 0x0, 136 0x1, // max locals 137 0x0, 138 0x0, 139 0x0, 140 0x1, // code length 141 Bytecodes::_return, 142 0x0, 143 0x0, // ex table len 144 0x0, 145 0x0 // attributes_count 146 }; 147 148 static u1 boolean_method_code_attribute[] = { 149 0x0, 150 0x0, 151 0x0, 152 0xe, 153 0x0, 154 0x1, // max stack 155 0x0, 156 0x1, // max locals 157 0x0, 158 0x0, 159 0x0, 160 0x2, 161 Bytecodes::_iconst_0, 162 Bytecodes::_ireturn, 163 0x0, 164 0x0, // ex table len 165 0x0, 166 0x0, // attributes_count 167 }; 168 169 /* 170 Annotation layout. 171 172 enum { // initial annotation layout 173 atype_off = 0, // utf8 such as 'Ljava/lang/annotation/Retention;' 174 count_off = 2, // u2 such as 1 (one value) 175 member_off = 4, // utf8 such as 'value' 176 tag_off = 6, // u1 such as 'c' (type) or 'e' (enum) 177 e_tag_val = 'e', 178 e_type_off = 7, // utf8 such as 'Ljava/lang/annotation/RetentionPolicy;' 179 e_con_off = 9, // utf8 payload, such as 'SOURCE', 'CLASS', 'RUNTIME' 180 e_size = 11, // end of 'e' annotation 181 c_tag_val = 'c', // payload is type 182 c_con_off = 7, // utf8 payload, such as 'I' 183 c_size = 9, // end of 'c' annotation 184 s_tag_val = 's', // payload is String 185 s_con_off = 7, // utf8 payload, such as 'Ljava/lang/String;' 186 s_size = 9, 187 min_size = 6 // smallest possible size (zero members) 188 }; 189 */ 190 191 static int skip_annotation_value(const address, int, int); // fwd decl 192 193 // Skip an annotation. Return >=limit if there is any problem. 194 static int next_annotation_index(const address buffer, int limit, int index) { 195 assert(buffer != nullptr, "invariant"); 196 index += 2; // skip atype 197 if ((index += 2) >= limit) { 198 return limit; 199 } 200 int nof_members = JfrBigEndian::read<int, u2>(buffer + index - 2); 201 while (--nof_members >= 0 && index < limit) { 202 index += 2; // skip member 203 index = skip_annotation_value(buffer, limit, index); 204 } 205 return index; 206 } 207 208 // Skip an annotation value. Return >=limit if there is any problem. 209 static int skip_annotation_value(const address buffer, int limit, int index) { 210 assert(buffer != nullptr, "invariant"); 211 // value := switch (tag:u1) { 212 // case B, C, I, S, Z, D, F, J, c: con:u2; 213 // case e: e_class:u2 e_name:u2; 214 // case s: s_con:u2; 215 // case [: do(nval:u2) {value}; 216 // case @: annotation; 217 // case s: s_con:u2; 218 // } 219 if ((index += 1) >= limit) { 220 return limit; 221 } 222 const u1 tag = buffer[index - 1]; 223 switch (tag) { 224 case 'B': 225 case 'C': 226 case 'I': 227 case 'S': 228 case 'Z': 229 case 'D': 230 case 'F': 231 case 'J': 232 case 'c': 233 case 's': 234 index += 2; // skip con or s_con 235 break; 236 case 'e': 237 index += 4; // skip e_class, e_name 238 break; 239 case '[': 240 { 241 if ((index += 2) >= limit) { 242 return limit; 243 } 244 int nof_values = JfrBigEndian::read<int, u2>(buffer + index - 2); 245 while (--nof_values >= 0 && index < limit) { 246 index = skip_annotation_value(buffer, limit, index); 247 } 248 } 249 break; 250 case '@': 251 index = next_annotation_index(buffer, limit, index); 252 break; 253 default: 254 return limit; // bad tag byte 255 } 256 return index; 257 } 258 259 static constexpr const int number_of_elements_offset = 2; 260 static constexpr const int element_name_offset = number_of_elements_offset + 2; 261 static constexpr const int element_name_size = 2; 262 static constexpr const int value_type_relative_offset = 2; 263 static constexpr const int value_relative_offset = value_type_relative_offset + 1; 264 265 // see JVMS - 4.7.16. The RuntimeVisibleAnnotations Attribute 266 267 class AnnotationElementIterator : public StackObj { 268 private: 269 const InstanceKlass* _ik; 270 const address _buffer; 271 const int _limit; // length of annotation 272 mutable int _current; // element 273 mutable int _next; // element 274 275 int value_index() const { 276 return JfrBigEndian::read<int, u2>(_buffer + _current + value_relative_offset); 277 } 278 279 public: 280 AnnotationElementIterator(const InstanceKlass* ik, address buffer, int limit) : _ik(ik), 281 _buffer(buffer), 282 _limit(limit), 283 _current(element_name_offset), 284 _next(element_name_offset) { 285 assert(_buffer != nullptr, "invariant"); 286 assert(_next == element_name_offset, "invariant"); 287 assert(_current == element_name_offset, "invariant"); 288 } 289 290 bool has_next() const { 291 return _next < _limit; 292 } 293 294 void move_to_next() const { 295 assert(has_next(), "invariant"); 296 _current = _next; 297 if (_next < _limit) { 298 _next = skip_annotation_value(_buffer, _limit, _next + element_name_size); 299 } 300 assert(_next <= _limit, "invariant"); 301 assert(_current <= _limit, "invariant"); 302 } 303 304 int number_of_elements() const { 305 return JfrBigEndian::read<int, u2>(_buffer + number_of_elements_offset); 306 } 307 308 const Symbol* name() const { 309 assert(_current < _next, "invariant"); 310 return _ik->constants()->symbol_at(JfrBigEndian::read<int, u2>(_buffer + _current)); 311 } 312 313 char value_type() const { 314 return JfrBigEndian::read<char, u1>(_buffer + _current + value_type_relative_offset); 315 } 316 317 jint read_int() const { 318 return _ik->constants()->int_at(value_index()); 319 } 320 321 bool read_bool() const { 322 return read_int() != 0; 323 } 324 }; 325 326 class AnnotationIterator : public StackObj { 327 private: 328 const InstanceKlass* _ik; 329 // ensure _limit field is declared before _buffer 330 int _limit; // length of annotations array 331 const address _buffer; 332 mutable int _current; // annotation 333 mutable int _next; // annotation 334 335 public: 336 AnnotationIterator(const InstanceKlass* ik, AnnotationArray* ar) : _ik(ik), 337 _limit(ar != nullptr ? ar->length() : 0), 338 _buffer(_limit > 2 ? ar->adr_at(2) : nullptr), 339 _current(0), 340 _next(0) { 341 if (_buffer != nullptr) { 342 _limit -= 2; // subtract sizeof(u2) number of annotations field 343 } 344 } 345 bool has_next() const { 346 return _next < _limit; 347 } 348 349 void move_to_next() const { 350 assert(has_next(), "invariant"); 351 _current = _next; 352 if (_next < _limit) { 353 _next = next_annotation_index(_buffer, _limit, _next); 354 } 355 assert(_next <= _limit, "invariant"); 356 assert(_current <= _limit, "invariant"); 357 } 358 359 const AnnotationElementIterator elements() const { 360 assert(_current < _next, "invariant"); 361 return AnnotationElementIterator(_ik, _buffer + _current, _next - _current); 362 } 363 364 const Symbol* type() const { 365 assert(_buffer != nullptr, "invariant"); 366 assert(_current < _limit, "invariant"); 367 return _ik->constants()->symbol_at(JfrBigEndian::read<int, u2>(_buffer + _current)); 368 } 369 }; 370 371 static const char value_name[] = "value"; 372 static bool has_annotation(const InstanceKlass* ik, const Symbol* annotation_type, bool& value) { 373 assert(annotation_type != nullptr, "invariant"); 374 AnnotationArray* class_annotations = ik->class_annotations(); 375 if (class_annotations == nullptr) { 376 return false; 377 } 378 379 const AnnotationIterator annotation_iterator(ik, class_annotations); 380 while (annotation_iterator.has_next()) { 381 annotation_iterator.move_to_next(); 382 if (annotation_iterator.type() == annotation_type) { 383 // target annotation found 384 static const Symbol* value_symbol = 385 SymbolTable::probe(value_name, sizeof value_name - 1); 386 assert(value_symbol != nullptr, "invariant"); 387 const AnnotationElementIterator element_iterator = annotation_iterator.elements(); 388 while (element_iterator.has_next()) { 389 element_iterator.move_to_next(); 390 if (value_symbol == element_iterator.name()) { 391 // "value" element 392 assert('Z' == element_iterator.value_type(), "invariant"); 393 value = element_iterator.read_bool(); 394 return true; 395 } 396 } 397 } 398 } 399 return false; 400 } 401 402 // Evaluate to the value of the first found Symbol* annotation type. 403 // Searching moves upwards in the klass hierarchy in order to support 404 // inherited annotations in addition to the ability to override. 405 static bool annotation_value(const InstanceKlass* ik, const Symbol* annotation_type, bool& value) { 406 assert(ik != nullptr, "invariant"); 407 assert(annotation_type != nullptr, "invariant"); 408 assert(JdkJfrEvent::is_a(ik), "invariant"); 409 if (has_annotation(ik, annotation_type, value)) { 410 return true; 411 } 412 InstanceKlass* const super = InstanceKlass::cast(ik->super()); 413 return super != nullptr && JdkJfrEvent::is_a(super) ? annotation_value(super, annotation_type, value) : false; 414 } 415 416 static const char jdk_jfr_module_name[] = "jdk.jfr"; 417 418 static bool java_base_can_read_jdk_jfr() { 419 static bool can_read = false; 420 if (can_read) { 421 return true; 422 } 423 static Symbol* jdk_jfr_module_symbol = nullptr; 424 if (jdk_jfr_module_symbol == nullptr) { 425 jdk_jfr_module_symbol = SymbolTable::probe(jdk_jfr_module_name, sizeof jdk_jfr_module_name - 1); 426 if (jdk_jfr_module_symbol == nullptr) { 427 return false; 428 } 429 } 430 assert(jdk_jfr_module_symbol != nullptr, "invariant"); 431 ModuleEntryTable* const table = Modules::get_module_entry_table(Handle()); 432 assert(table != nullptr, "invariant"); 433 const ModuleEntry* const java_base_module = table->javabase_moduleEntry(); 434 if (java_base_module == nullptr) { 435 return false; 436 } 437 assert(java_base_module != nullptr, "invariant"); 438 ModuleEntry* jdk_jfr_module; 439 { 440 MutexLocker ml(Module_lock); 441 jdk_jfr_module = table->lookup_only(jdk_jfr_module_symbol); 442 if (jdk_jfr_module == nullptr) { 443 return false; 444 } 445 } 446 assert(jdk_jfr_module != nullptr, "invariant"); 447 if (java_base_module->can_read(jdk_jfr_module)) { 448 can_read = true; 449 } 450 return can_read; 451 } 452 453 static const char registered_constant[] = "Ljdk/jfr/Registered;"; 454 455 // Evaluate to the value of the first found "Ljdk/jfr/Registered;" annotation. 456 // Searching moves upwards in the klass hierarchy in order to support 457 // inherited annotations in addition to the ability to override. 458 static bool should_register_klass(const InstanceKlass* ik, bool& untypedEventHandler) { 459 assert(ik != nullptr, "invariant"); 460 assert(JdkJfrEvent::is_a(ik), "invariant"); 461 assert(!untypedEventHandler, "invariant"); 462 static const Symbol* registered_symbol = nullptr; 463 if (registered_symbol == nullptr) { 464 registered_symbol = SymbolTable::probe(registered_constant, sizeof registered_constant - 1); 465 if (registered_symbol == nullptr) { 466 untypedEventHandler = true; 467 return false; 468 } 469 } 470 assert(registered_symbol != nullptr, "invariant"); 471 bool value = false; // to be set by annotation_value 472 untypedEventHandler = !(annotation_value(ik, registered_symbol, value) || java_base_can_read_jdk_jfr()); 473 return value; 474 } 475 476 /* 477 * Map an utf8 constant back to its CONSTANT_UTF8_INFO 478 */ 479 static u2 utf8_info_index(const InstanceKlass* ik, const Symbol* const target, TRAPS) { 480 assert(target != nullptr, "invariant"); 481 const ConstantPool* cp = ik->constants(); 482 const int cp_len = cp->length(); 483 for (int index = 1; index < cp_len; ++index) { 484 const constantTag tag = cp->tag_at(index); 485 if (tag.is_utf8()) { 486 const Symbol* const utf8_sym = cp->symbol_at(index); 487 assert(utf8_sym != nullptr, "invariant"); 488 if (utf8_sym == target) { 489 return static_cast<u2>(index); 490 } 491 } 492 } 493 // not in constant pool 494 return invalid_cp_index; 495 } 496 497 #ifdef ASSERT 498 static bool is_index_within_range(u2 index, u2 orig_cp_len, u2 new_cp_entries_len) { 499 return index > 0 && index < orig_cp_len + new_cp_entries_len; 500 } 501 #endif 502 503 static u2 add_utf8_info(JfrBigEndianWriter& writer, const char* utf8_constant, u2 orig_cp_len, u2& new_cp_entries_len) { 504 assert(utf8_constant != nullptr, "invariant"); 505 writer.write<u1>(JVM_CONSTANT_Utf8); 506 writer.write_utf8_u2_len(utf8_constant); 507 assert(writer.is_valid(), "invariant"); 508 // return index for the added utf8 info 509 return orig_cp_len + new_cp_entries_len++; 510 } 511 512 static u2 add_method_ref_info(JfrBigEndianWriter& writer, 513 u2 cls_name_index, 514 u2 method_index, 515 u2 desc_index, 516 u2 orig_cp_len, 517 u2& number_of_new_constants, 518 TRAPS) { 519 assert(cls_name_index != invalid_cp_index, "invariant"); 520 assert(method_index != invalid_cp_index, "invariant"); 521 assert(desc_index != invalid_cp_index, "invariant"); 522 assert(is_index_within_range(cls_name_index, orig_cp_len, number_of_new_constants), "invariant"); 523 assert(is_index_within_range(method_index, orig_cp_len, number_of_new_constants), "invariant"); 524 assert(is_index_within_range(desc_index, orig_cp_len, number_of_new_constants), "invariant"); 525 writer.write<u1>(JVM_CONSTANT_Class); 526 writer.write<u2>(cls_name_index); 527 const u2 cls_entry_index = orig_cp_len + number_of_new_constants; 528 ++number_of_new_constants; 529 writer.write<u1>(JVM_CONSTANT_NameAndType); 530 writer.write<u2>(method_index); 531 writer.write<u2>(desc_index); 532 const u2 nat_entry_index = orig_cp_len + number_of_new_constants; 533 ++number_of_new_constants; 534 writer.write<u1>(JVM_CONSTANT_Methodref); 535 writer.write<u2>(cls_entry_index); 536 writer.write<u2>(nat_entry_index); 537 // post-increment number_of_new_constants 538 // value returned is the index to the added method_ref 539 return orig_cp_len + number_of_new_constants++; 540 } 541 542 static u2 add_flr_register_method_constants(JfrBigEndianWriter& writer, 543 const u2* utf8_indexes, 544 u2 orig_cp_len, 545 u2& number_of_new_constants, 546 TRAPS) { 547 assert(utf8_indexes != nullptr, "invariant"); 548 return add_method_ref_info(writer, 549 utf8_indexes[UTF8_OPT_FlightRecorder], 550 utf8_indexes[UTF8_OPT_register], 551 utf8_indexes[UTF8_OPT_CLASS_VOID_METHOD_DESC], 552 orig_cp_len, 553 number_of_new_constants, 554 THREAD); 555 } 556 557 /* 558 * field_info { 559 * u2 access_flags; 560 * u2 name_index; 561 * u2 descriptor_index; 562 * u2 attributes_count; 563 * attribute_info attributes[attributes_count]; 564 * } 565 */ 566 static jlong add_field_info(JfrBigEndianWriter& writer, u2 name_index, u2 desc_index, bool is_static = false) { 567 assert(name_index != invalid_cp_index, "invariant"); 568 assert(desc_index != invalid_cp_index, "invariant"); 569 DEBUG_ONLY(const jlong start_offset = writer.current_offset();) 570 writer.write<u2>(JVM_ACC_SYNTHETIC | JVM_ACC_PRIVATE | (is_static ? JVM_ACC_STATIC : JVM_ACC_TRANSIENT)); // flags 571 writer.write(name_index); 572 writer.write(desc_index); 573 writer.write((u2)0x0); // attributes_count 574 assert(writer.is_valid(), "invariant"); 575 DEBUG_ONLY(assert(start_offset + 8 == writer.current_offset(), "invariant");) 576 return writer.current_offset(); 577 } 578 579 static u2 add_field_infos(JfrBigEndianWriter& writer, const u2* utf8_indexes, bool untypedEventConfiguration) { 580 assert(utf8_indexes != nullptr, "invariant"); 581 add_field_info(writer, 582 utf8_indexes[UTF8_REQ_eventConfiguration], 583 untypedEventConfiguration ? utf8_indexes[UTF8_OPT_LjavaLangObject] : utf8_indexes[UTF8_OPT_eventConfiguration_FIELD_DESC], 584 true); // static 585 586 add_field_info(writer, 587 utf8_indexes[UTF8_REQ_startTime], 588 utf8_indexes[UTF8_REQ_J_FIELD_DESC]); 589 590 add_field_info(writer, 591 utf8_indexes[UTF8_REQ_duration], 592 utf8_indexes[UTF8_REQ_J_FIELD_DESC]); 593 594 return number_of_new_fields; 595 } 596 597 /* 598 * method_info { 599 * u2 access_flags; 600 * u2 name_index; 601 * u2 descriptor_index; 602 * u2 attributes_count; 603 * attribute_info attributes[attributes_count]; 604 * } 605 * 606 * Code_attribute { 607 * u2 attribute_name_index; 608 * u4 attribute_length; 609 * u2 max_stack; 610 * u2 max_locals; 611 * u4 code_length; 612 * u1 code[code_length]; 613 * u2 exception_table_length; 614 * { u2 start_pc; 615 * u2 end_pc; 616 * u2 handler_pc; 617 * u2 catch_type; 618 * } exception_table[exception_table_length]; 619 * u2 attributes_count; 620 * attribute_info attributes[attributes_count]; 621 * } 622 */ 623 624 static jlong add_method_info(JfrBigEndianWriter& writer, 625 u2 name_index, 626 u2 desc_index, 627 u2 code_index, 628 const u1* const code, 629 const size_t code_len) { 630 assert(name_index > 0, "invariant"); 631 assert(desc_index > 0, "invariant"); 632 assert(code_index > 0, "invariant"); 633 DEBUG_ONLY(const jlong start_offset = writer.current_offset();) 634 writer.write<u2>(JVM_ACC_SYNTHETIC | JVM_ACC_PUBLIC); // flags 635 writer.write(name_index); 636 writer.write(desc_index); 637 writer.write<u2>(0x1); // attributes_count ; 1 for "Code" attribute 638 assert(writer.is_valid(), "invariant"); 639 DEBUG_ONLY(assert(start_offset + 8 == writer.current_offset(), "invariant");) 640 // Code attribute 641 writer.write(code_index); // "Code" 642 writer.write_bytes(code, code_len); 643 DEBUG_ONLY(assert((start_offset + 8 + 2 + (jlong)code_len) == writer.current_offset(), "invariant");) 644 return writer.current_offset(); 645 } 646 647 /* 648 * On return, the passed stream will be positioned 649 * just after the constant pool section in the classfile 650 * and the cp length is returned. 651 * 652 * Stream should come in at the start position. 653 */ 654 static u2 position_stream_after_cp(const ClassFileStream* stream) { 655 assert(stream != nullptr, "invariant"); 656 assert(stream->current_offset() == 0, "invariant"); 657 stream->skip_u4_fast(2); // 8 bytes skipped 658 const u2 cp_len = stream->get_u2_fast(); 659 assert(cp_len > 0, "invariant"); 660 // now spin the stream position to just after the constant pool 661 for (u2 index = 1; index < cp_len; ++index) { 662 const u1 tag = stream->get_u1_fast(); // cp tag 663 switch (tag) { 664 case JVM_CONSTANT_Class: 665 case JVM_CONSTANT_String: { 666 stream->skip_u2_fast(1); // skip 2 bytes 667 continue; 668 } 669 case JVM_CONSTANT_Fieldref: 670 case JVM_CONSTANT_Methodref: 671 case JVM_CONSTANT_InterfaceMethodref: 672 case JVM_CONSTANT_Integer: 673 case JVM_CONSTANT_Float: 674 case JVM_CONSTANT_NameAndType: 675 case JVM_CONSTANT_InvokeDynamic: { 676 stream->skip_u4_fast(1); // skip 4 bytes 677 continue; 678 } 679 case JVM_CONSTANT_Long: 680 case JVM_CONSTANT_Double: { 681 stream->skip_u4_fast(2); // skip 8 bytes 682 // Skip entry following eigth-byte constant, see JVM book p. 98 683 ++index; 684 continue; 685 } 686 case JVM_CONSTANT_Utf8: { 687 int utf8_length = static_cast<int>(stream->get_u2_fast()); 688 stream->skip_u1_fast(utf8_length); // skip 2 + len bytes 689 continue; 690 } 691 case JVM_CONSTANT_MethodHandle: 692 case JVM_CONSTANT_MethodType: { 693 if (tag == JVM_CONSTANT_MethodHandle) { 694 stream->skip_u1_fast(1); 695 stream->skip_u2_fast(1); // skip 3 bytes 696 } 697 else if (tag == JVM_CONSTANT_MethodType) { 698 stream->skip_u2_fast(1); // skip 3 bytes 699 } 700 } 701 continue; 702 case JVM_CONSTANT_Dynamic: 703 stream->skip_u2_fast(1); 704 stream->skip_u2_fast(1); 705 continue; 706 default: 707 assert(false, "error in skip logic!"); 708 break; 709 } // end switch(tag) 710 } 711 return cp_len; 712 } 713 714 /* 715 * On return, the passed stream will be positioned 716 * just after the fields section in the classfile 717 * and the number of fields will be returned. 718 * 719 * Stream should come in positioned just before fields_count 720 */ 721 static u2 position_stream_after_fields(const ClassFileStream* stream) { 722 assert(stream != nullptr, "invariant"); 723 assert(stream->current_offset() > 0, "invariant"); 724 // fields len 725 const u2 orig_fields_len = stream->get_u2_fast(); 726 // fields 727 for (u2 i = 0; i < orig_fields_len; ++i) { 728 stream->skip_u2_fast(3); 729 const u2 attrib_info_len = stream->get_u2_fast(); 730 for (u2 j = 0; j < attrib_info_len; ++j) { 731 stream->skip_u2_fast(1); 732 stream->skip_u1_fast(static_cast<int>(stream->get_u4_fast())); 733 } 734 } 735 return orig_fields_len; 736 } 737 738 /* 739 * On return, the passed stream will be positioned 740 * just after the methods section in the classfile 741 * and the number of methods will be returned. 742 * 743 * Stream should come in positioned just before methods_count 744 */ 745 static u2 position_stream_after_methods(JfrBigEndianWriter& writer, 746 const ClassFileStream* stream, 747 const u2* utf8_indexes, 748 bool register_klass, 749 const Method* clinit_method, 750 u4& orig_method_len_offset) { 751 assert(stream != nullptr, "invariant"); 752 assert(stream->current_offset() > 0, "invariant"); 753 assert(utf8_indexes != nullptr, "invariant"); 754 // We will come back to this location when we 755 // know how many methods there will be. 756 writer.reserve(sizeof(u2)); 757 const u2 orig_methods_len = stream->get_u2_fast(); 758 // Move copy position past original method_count 759 // in order to not copy the original count 760 orig_method_len_offset += 2; 761 for (u2 i = 0; i < orig_methods_len; ++i) { 762 const u4 method_offset = stream->current_offset(); 763 stream->skip_u2_fast(1); // Access Flags 764 const u2 name_index = stream->get_u2_fast(); // Name index 765 stream->skip_u2_fast(1); // Descriptor index 766 const u2 attributes_count = stream->get_u2_fast(); 767 for (u2 j = 0; j < attributes_count; ++j) { 768 stream->skip_u2_fast(1); 769 stream->skip_u1_fast(static_cast<int>(stream->get_u4_fast())); 770 } 771 if (clinit_method != nullptr && name_index == clinit_method->name_index()) { 772 // The method just parsed is an existing <clinit> method. 773 // If the class has the @Registered(false) annotation, i.e. marking a class 774 // for opting out from automatic registration, then we do not need to do anything. 775 if (!register_klass) { 776 continue; 777 } 778 // Automatic registration with the jfr system is acccomplished 779 // by pre-pending code to the <clinit> method of the class. 780 // We will need to re-create a new <clinit> in a later step. 781 // For now, ensure that this method is excluded from the methods 782 // being copied. 783 writer.write_bytes(stream->buffer() + orig_method_len_offset, 784 method_offset - orig_method_len_offset); 785 assert(writer.is_valid(), "invariant"); 786 787 // Update copy position to skip copy of <clinit> method 788 orig_method_len_offset = stream->current_offset(); 789 } 790 } 791 return orig_methods_len; 792 } 793 794 static u2 add_method_infos(JfrBigEndianWriter& writer, const u2* utf8_indexes) { 795 assert(utf8_indexes != nullptr, "invariant"); 796 add_method_info(writer, 797 utf8_indexes[UTF8_REQ_begin], 798 utf8_indexes[UTF8_REQ_EMPTY_VOID_METHOD_DESC], 799 utf8_indexes[UTF8_REQ_Code], 800 empty_void_method_code_attribute, 801 sizeof(empty_void_method_code_attribute)); 802 803 assert(writer.is_valid(), "invariant"); 804 805 add_method_info(writer, 806 utf8_indexes[UTF8_REQ_end], 807 utf8_indexes[UTF8_REQ_EMPTY_VOID_METHOD_DESC], 808 utf8_indexes[UTF8_REQ_Code], 809 empty_void_method_code_attribute, 810 sizeof(empty_void_method_code_attribute)); 811 812 assert(writer.is_valid(), "invariant"); 813 814 add_method_info(writer, 815 utf8_indexes[UTF8_REQ_commit], 816 utf8_indexes[UTF8_REQ_EMPTY_VOID_METHOD_DESC], 817 utf8_indexes[UTF8_REQ_Code], 818 empty_void_method_code_attribute, 819 sizeof(empty_void_method_code_attribute)); 820 821 assert(writer.is_valid(), "invariant"); 822 823 add_method_info(writer, 824 utf8_indexes[UTF8_REQ_isEnabled], 825 utf8_indexes[UTF8_REQ_EMPTY_BOOLEAN_METHOD_DESC], 826 utf8_indexes[UTF8_REQ_Code], 827 boolean_method_code_attribute, 828 sizeof(boolean_method_code_attribute)); 829 830 assert(writer.is_valid(), "invariant"); 831 832 add_method_info(writer, 833 utf8_indexes[UTF8_REQ_shouldCommit], 834 utf8_indexes[UTF8_REQ_EMPTY_BOOLEAN_METHOD_DESC], 835 utf8_indexes[UTF8_REQ_Code], 836 boolean_method_code_attribute, 837 sizeof(boolean_method_code_attribute)); 838 assert(writer.is_valid(), "invariant"); 839 return number_of_new_methods; 840 } 841 842 static void adjust_exception_table(JfrBigEndianWriter& writer, u2 bci_adjustment_offset, const Method* method, TRAPS) { 843 const u2 ex_table_length = method != nullptr ? (u2)method->exception_table_length() : 0; 844 writer.write<u2>(ex_table_length); // Exception table length 845 if (ex_table_length > 0) { 846 assert(method != nullptr, "invariant"); 847 const ExceptionTableElement* const ex_elements = method->exception_table_start(); 848 for (int i = 0; i < ex_table_length; ++i) { 849 assert(ex_elements != nullptr, "invariant"); 850 writer.write<u2>(ex_elements[i].start_pc + bci_adjustment_offset); 851 writer.write<u2>(ex_elements[i].end_pc + bci_adjustment_offset); 852 writer.write<u2>(ex_elements[i].handler_pc + bci_adjustment_offset); 853 writer.write<u2>(ex_elements[i].catch_type_index); // no adjustment 854 } 855 } 856 } 857 858 enum StackMapFrameTypes : u1 { 859 SAME_FRAME_BEGIN = 0, 860 SAME_FRAME_END = 63, 861 SAME_LOCALS_1_STACK_ITEM_FRAME_BEGIN = 64, 862 SAME_LOCALS_1_STACK_ITEM_FRAME_END = 127, 863 SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED = 247, 864 CHOP_FRAME_BEGIN = 248, 865 CHOP_FRAME_END = 250, 866 SAME_FRAME_EXTENDED = 251, 867 APPEND_FRAME_BEGIN = 252, 868 APPEND_FRAME_END = 254, 869 FULL_FRAME = 255 870 }; 871 872 static void adjust_stack_map(JfrBigEndianWriter& writer, 873 Array<u1>* stack_map, 874 const u2* utf8_indexes, 875 u2 bci_adjustment_offset, 876 TRAPS) { 877 assert(stack_map != nullptr, "invariant"); 878 assert(utf8_indexes != nullptr, "invariant"); 879 writer.write<u2>(utf8_indexes[UTF8_OPT_StackMapTable]); 880 const jlong stack_map_attrib_len_offset = writer.current_offset(); 881 writer.reserve(sizeof(u4)); 882 StackMapStream stream(stack_map); 883 const u2 stack_map_entries = stream.get_u2(THREAD); 884 // number of entries 885 writer.write<u2>(stack_map_entries); // new stack map entry added 886 const u1 frame_type = stream.get_u1(THREAD); 887 // SAME_FRAME and SAME_LOCALS_1_STACK_ITEM_FRAME encode 888 // their offset_delta into the actual frame type itself. 889 // If such a frame type is the first frame, then we transform 890 // it to a SAME_FRAME_EXTENDED or a SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED frame. 891 // This is done in order to not overflow frame types accidentally 892 // when adjusting the offset_delta. In changing the frame types, 893 // we can work with an explicit u2 offset_delta field (like the other frame types) 894 if (frame_type <= SAME_FRAME_END) { 895 writer.write<u1>(SAME_FRAME_EXTENDED); 896 writer.write<u2>(frame_type + bci_adjustment_offset); 897 } else if (frame_type >= SAME_LOCALS_1_STACK_ITEM_FRAME_BEGIN && 898 frame_type <= SAME_LOCALS_1_STACK_ITEM_FRAME_END) { 899 writer.write<u1>(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED); 900 const u2 value = frame_type - SAME_LOCALS_1_STACK_ITEM_FRAME_BEGIN; 901 writer.write<u2>(value + bci_adjustment_offset); 902 } else if (frame_type >= SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { 903 // SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED to FULL_FRAME 904 // has a u2 offset_delta field 905 writer.write<u1>(frame_type); 906 writer.write<u2>(stream.get_u2(THREAD) + bci_adjustment_offset); 907 } else { 908 assert(false, "stackMapFrame type is invalid"); 909 } 910 911 while (!stream.at_end()) { 912 writer.write<u1>(stream.get_u1(THREAD)); 913 } 914 915 u4 stack_map_attrib_len = static_cast<u4>(writer.current_offset() - stack_map_attrib_len_offset); 916 // the stack_map_table_attributes_length value is exclusive 917 stack_map_attrib_len -= 4; 918 writer.write_at_offset(stack_map_attrib_len, stack_map_attrib_len_offset); 919 } 920 921 static void adjust_line_number_table(JfrBigEndianWriter& writer, 922 const u2* utf8_indexes, 923 u4 bci_adjustement_offset, 924 const Method* method, 925 TRAPS) { 926 assert(utf8_indexes != nullptr, "invariant"); 927 assert(method != nullptr, "invariant"); 928 assert(method->has_linenumber_table(), "invariant"); 929 writer.write(utf8_indexes[UTF8_OPT_LineNumberTable]); 930 const jlong lnt_attributes_length_offset = writer.current_offset(); 931 writer.reserve(sizeof(u4)); 932 const jlong lnt_attributes_entries_offset = writer.current_offset(); 933 writer.reserve(sizeof(u2)); 934 u1* lnt = method->compressed_linenumber_table(); 935 CompressedLineNumberReadStream lnt_stream(lnt); 936 u2 line_number_table_entries = 0; 937 while (lnt_stream.read_pair()) { 938 ++line_number_table_entries; 939 const u2 bci = (u2)lnt_stream.bci(); 940 writer.write<u2>(bci + (u2)bci_adjustement_offset); 941 writer.write<u2>((u2)lnt_stream.line()); 942 } 943 writer.write_at_offset(line_number_table_entries, lnt_attributes_entries_offset); 944 u4 lnt_table_attributes_len = static_cast<u4>(writer.current_offset() - lnt_attributes_length_offset); 945 // the line_number_table_attributes_length value is exclusive 946 lnt_table_attributes_len -= 4; 947 writer.write_at_offset(lnt_table_attributes_len, lnt_attributes_length_offset); 948 } 949 950 // returns the number of lvtt entries 951 static u2 adjust_local_variable_table(JfrBigEndianWriter& writer, 952 const u2* utf8_indexes, 953 u2 bci_adjustment_offset, 954 const Method* method, 955 TRAPS) { 956 assert(utf8_indexes != nullptr, "invariant"); 957 assert(method != nullptr, "invariant"); 958 assert(method->has_localvariable_table(), "invariant"); 959 writer.write<u2>(utf8_indexes[UTF8_OPT_LocalVariableTable]); 960 const jlong lvt_attributes_length_offset = writer.current_offset(); 961 writer.reserve(sizeof(u4)); 962 const int lvt_len = method->localvariable_table_length(); 963 writer.write<u2>((u2)lvt_len); 964 const LocalVariableTableElement* table = method->localvariable_table_start(); 965 assert(table != nullptr, "invariant"); 966 u2 num_lvtt_entries = 0; 967 for (int i = 0; i < lvt_len; ++i) { 968 writer.write<u2>(table[i].start_bci + bci_adjustment_offset); 969 writer.write<u2>(table[i].length); 970 writer.write<u2>(table[i].name_cp_index); 971 writer.write<u2>(table[i].descriptor_cp_index); 972 writer.write<u2>(table[i].slot); 973 if (table[i].signature_cp_index > 0) { 974 ++num_lvtt_entries; 975 } 976 } 977 u4 lvt_table_attributes_len = static_cast<u4>(writer.current_offset() - lvt_attributes_length_offset); 978 // the lvt_table_attributes_length value is exclusive 979 lvt_table_attributes_len -= 4; 980 writer.write_at_offset(lvt_table_attributes_len, lvt_attributes_length_offset); 981 return num_lvtt_entries; 982 } 983 984 static void adjust_local_variable_type_table(JfrBigEndianWriter& writer, 985 const u2* utf8_indexes, 986 u2 bci_adjustment_offset, 987 u2 num_lvtt_entries, 988 const Method* method, 989 TRAPS) { 990 assert(num_lvtt_entries > 0, "invariant"); 991 writer.write<u2>(utf8_indexes[UTF8_OPT_LocalVariableTypeTable]); 992 const jlong lvtt_attributes_length_offset = writer.current_offset(); 993 writer.reserve(sizeof(u4)); 994 writer.write<u2>(num_lvtt_entries); 995 const LocalVariableTableElement* table = method->localvariable_table_start(); 996 assert(table != nullptr, "invariant"); 997 const int lvt_len = method->localvariable_table_length(); 998 for (int i = 0; i < lvt_len; ++i) { 999 if (table[i].signature_cp_index > 0) { 1000 writer.write<u2>(table[i].start_bci + bci_adjustment_offset); 1001 writer.write<u2>(table[i].length); 1002 writer.write<u2>(table[i].name_cp_index); 1003 writer.write<u2>(table[i].signature_cp_index); 1004 writer.write<u2>(table[i].slot); 1005 } 1006 } 1007 u4 lvtt_table_attributes_len = static_cast<u4>(writer.current_offset() - lvtt_attributes_length_offset); 1008 // the lvtt_table_attributes_length value is exclusive 1009 lvtt_table_attributes_len -= 4; 1010 writer.write_at_offset(lvtt_table_attributes_len, lvtt_attributes_length_offset); 1011 } 1012 1013 static void adjust_code_attributes(JfrBigEndianWriter& writer, 1014 const u2* utf8_indexes, 1015 u2 bci_adjustment_offset, 1016 const Method* clinit_method, 1017 TRAPS) { 1018 // "Code" attributes 1019 assert(utf8_indexes != nullptr, "invariant"); 1020 const jlong code_attributes_offset = writer.current_offset(); 1021 writer.reserve(sizeof(u2)); 1022 u2 number_of_code_attributes = 0; 1023 if (clinit_method != nullptr) { 1024 Array<u1>* stack_map = clinit_method->stackmap_data(); 1025 if (stack_map != nullptr) { 1026 ++number_of_code_attributes; 1027 adjust_stack_map(writer, stack_map, utf8_indexes, bci_adjustment_offset, THREAD); 1028 assert(writer.is_valid(), "invariant"); 1029 } 1030 if (clinit_method != nullptr && clinit_method->has_linenumber_table()) { 1031 ++number_of_code_attributes; 1032 adjust_line_number_table(writer, utf8_indexes, bci_adjustment_offset, clinit_method, THREAD); 1033 assert(writer.is_valid(), "invariant"); 1034 } 1035 if (clinit_method != nullptr && clinit_method->has_localvariable_table()) { 1036 ++number_of_code_attributes; 1037 const u2 num_of_lvtt_entries = adjust_local_variable_table(writer, utf8_indexes, bci_adjustment_offset, clinit_method, THREAD); 1038 assert(writer.is_valid(), "invariant"); 1039 if (num_of_lvtt_entries > 0) { 1040 ++number_of_code_attributes; 1041 adjust_local_variable_type_table(writer, utf8_indexes, bci_adjustment_offset, num_of_lvtt_entries, clinit_method, THREAD); 1042 assert(writer.is_valid(), "invariant"); 1043 } 1044 } 1045 } 1046 1047 // Store the number of code_attributes 1048 writer.write_at_offset(number_of_code_attributes, code_attributes_offset); 1049 } 1050 1051 static jlong insert_clinit_method(const InstanceKlass* ik, 1052 const ClassFileParser& parser, 1053 JfrBigEndianWriter& writer, 1054 u2 orig_constant_pool_len, 1055 const u2* utf8_indexes, 1056 const u2 register_method_ref_index, 1057 const Method* clinit_method, 1058 TRAPS) { 1059 assert(utf8_indexes != nullptr, "invariant"); 1060 // The injected code length is always this value. 1061 // This is to ensure that padding can be done 1062 // where needed and to simplify size calculations. 1063 static const u2 injected_code_length = 8; 1064 const u2 name_index = utf8_indexes[UTF8_OPT_clinit]; 1065 assert(name_index != invalid_cp_index, "invariant"); 1066 const u2 desc_index = utf8_indexes[UTF8_REQ_EMPTY_VOID_METHOD_DESC]; 1067 const u2 max_stack = MAX2<u2>(clinit_method != nullptr ? clinit_method->verifier_max_stack() : 1, 1); 1068 const u2 max_locals = MAX2<u2>(clinit_method != nullptr ? clinit_method->max_locals() : 0, 0); 1069 const u2 orig_bytecodes_length = clinit_method != nullptr ? (u2)clinit_method->code_size() : 0; 1070 const address orig_bytecodes = clinit_method != nullptr ? clinit_method->code_base() : nullptr; 1071 const u2 new_code_length = injected_code_length + orig_bytecodes_length; 1072 DEBUG_ONLY(const jlong start_offset = writer.current_offset();) 1073 writer.write<u2>(JVM_ACC_STATIC); // flags 1074 writer.write<u2>(name_index); 1075 writer.write<u2>(desc_index); 1076 writer.write<u2>((u2)0x1); // attributes_count // "Code" 1077 assert(writer.is_valid(), "invariant"); 1078 DEBUG_ONLY(assert(start_offset + 8 == writer.current_offset(), "invariant");) 1079 // "Code" attribute 1080 writer.write<u2>(utf8_indexes[UTF8_REQ_Code]); // "Code" 1081 const jlong code_attribute_length_offset = writer.current_offset(); 1082 writer.reserve(sizeof(u4)); 1083 writer.write<u2>(max_stack); // max stack 1084 writer.write<u2>(max_locals); // max locals 1085 writer.write<u4>((u4)new_code_length); // code length 1086 1087 /* BEGIN CLINIT CODE */ 1088 1089 // Note the use of ldc_w here instead of ldc. 1090 // This is to handle all values of "this_class_index" 1091 writer.write<u1>((u1)Bytecodes::_ldc_w); 1092 writer.write<u2>((u2)parser.this_class_index()); // load constant "this class" 1093 writer.write<u1>((u1)Bytecodes::_invokestatic); 1094 // invoke "FlightRecorder.register(Ljava/lang/Class;") 1095 writer.write<u2>(register_method_ref_index); 1096 if (clinit_method == nullptr) { 1097 writer.write<u1>((u1)Bytecodes::_nop); 1098 writer.write<u1>((u1)Bytecodes::_return); 1099 } else { 1100 // If we are pre-pending to original code, 1101 // do padding to minimize disruption to the original. 1102 // It might have dependencies on 4-byte boundaries 1103 // i.e. lookupswitch and tableswitch instructions 1104 writer.write<u1>((u1)Bytecodes::_nop); 1105 writer.write<u1>((u1)Bytecodes::_nop); 1106 // insert original clinit code 1107 writer.write_bytes(orig_bytecodes, orig_bytecodes_length); 1108 } 1109 1110 /* END CLINIT CODE */ 1111 1112 assert(writer.is_valid(), "invariant"); 1113 adjust_exception_table(writer, injected_code_length, clinit_method, THREAD); 1114 assert(writer.is_valid(), "invariant"); 1115 adjust_code_attributes(writer, utf8_indexes, injected_code_length, clinit_method, THREAD); 1116 assert(writer.is_valid(), "invariant"); 1117 u4 code_attribute_len = static_cast<u4>(writer.current_offset() - code_attribute_length_offset); 1118 // the code_attribute_length value is exclusive 1119 code_attribute_len -= 4; 1120 writer.write_at_offset(code_attribute_len, code_attribute_length_offset); 1121 return writer.current_offset(); 1122 } 1123 1124 static Symbol* begin = nullptr; 1125 static Symbol* end = nullptr; 1126 static Symbol* commit = nullptr; 1127 static Symbol* isEnabled = nullptr; 1128 static Symbol* shouldCommit = nullptr; 1129 static Symbol* void_method_sig = nullptr; 1130 static Symbol* boolean_method_sig = nullptr; 1131 1132 static void initialize_symbols() { 1133 if (begin == nullptr) { 1134 begin = SymbolTable::probe("begin", 5); 1135 assert(begin != nullptr, "invariant"); 1136 end = SymbolTable::probe("end", 3); 1137 assert(end != nullptr, "invariant"); 1138 commit = SymbolTable::probe("commit", 6); 1139 assert(commit != nullptr, "invariant"); 1140 isEnabled = SymbolTable::probe("isEnabled", 9); 1141 assert(isEnabled != nullptr, "invariant"); 1142 shouldCommit = SymbolTable::probe("shouldCommit", 12); 1143 assert(shouldCommit != nullptr, "invariant"); 1144 void_method_sig = SymbolTable::probe("()V", 3); 1145 assert(void_method_sig != nullptr, "invariant"); 1146 boolean_method_sig = SymbolTable::probe("()Z", 3); 1147 assert(boolean_method_sig != nullptr, "invariant"); 1148 } 1149 } 1150 1151 // Caller needs ResourceMark 1152 static ClassFileStream* schema_extend_event_klass_bytes(const InstanceKlass* ik, const ClassFileParser& parser, TRAPS) { 1153 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD)); 1154 initialize_symbols(); 1155 static const u2 public_final_flag_mask = JVM_ACC_PUBLIC | JVM_ACC_FINAL; 1156 const ClassFileStream* const orig_stream = parser.clone_stream(); 1157 assert(orig_stream != nullptr, "invariant"); 1158 const int orig_stream_length = orig_stream->length(); 1159 // allocate an identically sized buffer 1160 u1* const new_buffer = NEW_RESOURCE_ARRAY_IN_THREAD_RETURN_NULL(THREAD, u1, orig_stream_length); 1161 if (new_buffer == nullptr) { 1162 return nullptr; 1163 } 1164 assert(new_buffer != nullptr, "invariant"); 1165 // memcpy the entire [B 1166 memcpy(new_buffer, orig_stream->buffer(), orig_stream_length); 1167 const u2 orig_cp_len = position_stream_after_cp(orig_stream); 1168 assert(orig_cp_len > 0, "invariant"); 1169 assert(orig_stream->current_offset() > 0, "invariant"); 1170 orig_stream->skip_u2_fast(3); // access_flags, this_class_index, super_class_index 1171 const u2 iface_len = orig_stream->get_u2_fast(); 1172 orig_stream->skip_u2_fast(iface_len); 1173 // fields len 1174 const u2 orig_fields_len = orig_stream->get_u2_fast(); 1175 // fields 1176 for (u2 i = 0; i < orig_fields_len; ++i) { 1177 orig_stream->skip_u2_fast(3); 1178 const u2 attrib_info_len = orig_stream->get_u2_fast(); 1179 for (u2 j = 0; j < attrib_info_len; ++j) { 1180 orig_stream->skip_u2_fast(1); 1181 const u4 attrib_len = orig_stream->get_u4_fast(); 1182 orig_stream->skip_u1_fast(attrib_len); 1183 } 1184 } 1185 // methods 1186 const u2 orig_methods_len = orig_stream->get_u2_fast(); 1187 for (u2 i = 0; i < orig_methods_len; ++i) { 1188 const u4 access_flag_offset = orig_stream->current_offset(); 1189 const u2 flags = orig_stream->get_u2_fast(); 1190 // Rewrite JVM_ACC_FINAL -> JVM_ACC_PUBLIC 1191 if (public_final_flag_mask == flags) { 1192 JfrBigEndianWriter accessflagsrewriter(new_buffer + access_flag_offset, sizeof(u2)); 1193 accessflagsrewriter.write<u2>(JVM_ACC_PUBLIC); 1194 assert(accessflagsrewriter.is_valid(), "invariant"); 1195 } 1196 orig_stream->skip_u2_fast(2); 1197 const u2 attributes_count = orig_stream->get_u2_fast(); 1198 for (u2 j = 0; j < attributes_count; ++j) { 1199 orig_stream->skip_u2_fast(1); 1200 const u4 attrib_len = orig_stream->get_u4_fast(); 1201 orig_stream->skip_u1_fast(attrib_len); 1202 } 1203 } 1204 return new ClassFileStream(new_buffer, orig_stream_length, nullptr); 1205 } 1206 1207 // Attempt to locate an existing UTF8_INFO mapping the utf8_constant. 1208 // If no UTF8_INFO exists, add (append) a new one to the constant pool. 1209 static u2 find_or_add_utf8_info(JfrBigEndianWriter& writer, 1210 const InstanceKlass* ik, 1211 const char* const utf8_constant, 1212 u2 orig_cp_len, 1213 u2& added_cp_entries, 1214 TRAPS) { 1215 assert(utf8_constant != nullptr, "invariant"); 1216 TempNewSymbol utf8_sym = SymbolTable::new_symbol(utf8_constant); 1217 // lookup existing 1218 const u2 utf8_orig_idx = utf8_info_index(ik, utf8_sym, THREAD); 1219 if (utf8_orig_idx != invalid_cp_index) { 1220 // existing constant pool entry found 1221 return utf8_orig_idx; 1222 } 1223 // no existing match, need to add a new utf8 cp entry 1224 assert(invalid_cp_index == utf8_orig_idx, "invariant"); 1225 // add / append new 1226 return add_utf8_info(writer, utf8_constant, orig_cp_len, added_cp_entries); 1227 } 1228 1229 /* 1230 * This routine will resolve the required utf8_constants array 1231 * to their constant pool indexes (mapping to their UTF8_INFO's) 1232 * Only if a constant is actually needed and does not already exist 1233 * will it be added. 1234 * 1235 * The passed in indexes array will be populated with the resolved indexes. 1236 * The number of newly added constant pool entries is returned. 1237 */ 1238 static u2 resolve_utf8_indexes(JfrBigEndianWriter& writer, 1239 const InstanceKlass* ik, 1240 u2* const utf8_indexes, 1241 u2 orig_cp_len, 1242 const Method* clinit_method, 1243 bool register_klass, 1244 bool untypedEventConfiguration, 1245 TRAPS) { 1246 assert(utf8_indexes != nullptr, "invariant"); 1247 u2 added_cp_entries = 0; 1248 // resolve all required symbols 1249 for (u2 index = 0; index < NOF_UTF8_REQ_SYMBOLS; ++index) { 1250 utf8_indexes[index] = find_or_add_utf8_info(writer, ik, utf8_constants[index], orig_cp_len, added_cp_entries, THREAD); 1251 } 1252 1253 // resolve optional constants 1254 utf8_indexes[UTF8_OPT_eventConfiguration_FIELD_DESC] = untypedEventConfiguration ? invalid_cp_index : 1255 find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_eventConfiguration_FIELD_DESC], orig_cp_len, added_cp_entries, THREAD); 1256 1257 utf8_indexes[UTF8_OPT_LjavaLangObject] = untypedEventConfiguration ? 1258 find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_LjavaLangObject], orig_cp_len, added_cp_entries, THREAD) : invalid_cp_index; 1259 1260 if (register_klass) { 1261 utf8_indexes[UTF8_OPT_clinit] = 1262 find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_clinit], orig_cp_len, added_cp_entries, THREAD); 1263 utf8_indexes[UTF8_OPT_FlightRecorder] = 1264 find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_FlightRecorder], orig_cp_len, added_cp_entries, THREAD); 1265 utf8_indexes[UTF8_OPT_register] = 1266 find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_register], orig_cp_len, added_cp_entries, THREAD); 1267 utf8_indexes[UTF8_OPT_CLASS_VOID_METHOD_DESC] = 1268 find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_CLASS_VOID_METHOD_DESC], orig_cp_len, added_cp_entries, THREAD); 1269 } else { 1270 utf8_indexes[UTF8_OPT_clinit] = invalid_cp_index; 1271 utf8_indexes[UTF8_OPT_FlightRecorder] = invalid_cp_index; 1272 utf8_indexes[UTF8_OPT_register] = invalid_cp_index; 1273 utf8_indexes[UTF8_OPT_CLASS_VOID_METHOD_DESC] = invalid_cp_index; 1274 } 1275 1276 if (clinit_method != nullptr && clinit_method->has_stackmap_table()) { 1277 utf8_indexes[UTF8_OPT_StackMapTable] = 1278 find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_StackMapTable], orig_cp_len, added_cp_entries, THREAD); 1279 } else { 1280 utf8_indexes[UTF8_OPT_StackMapTable] = invalid_cp_index; 1281 } 1282 1283 if (clinit_method != nullptr && clinit_method->has_linenumber_table()) { 1284 utf8_indexes[UTF8_OPT_LineNumberTable] = 1285 find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_LineNumberTable], orig_cp_len, added_cp_entries, THREAD); 1286 } else { 1287 utf8_indexes[UTF8_OPT_LineNumberTable] = invalid_cp_index; 1288 } 1289 1290 if (clinit_method != nullptr && clinit_method->has_localvariable_table()) { 1291 utf8_indexes[UTF8_OPT_LocalVariableTable] = 1292 find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_LocalVariableTable], orig_cp_len, added_cp_entries, THREAD); 1293 utf8_indexes[UTF8_OPT_LocalVariableTypeTable] = 1294 find_or_add_utf8_info(writer, ik, utf8_constants[UTF8_OPT_LocalVariableTypeTable], orig_cp_len, added_cp_entries, THREAD); 1295 } else { 1296 utf8_indexes[UTF8_OPT_LocalVariableTable] = invalid_cp_index; 1297 utf8_indexes[UTF8_OPT_LocalVariableTypeTable] = invalid_cp_index; 1298 } 1299 1300 return added_cp_entries; 1301 } 1302 1303 static u1* schema_extend_event_subklass_bytes(const InstanceKlass* ik, 1304 const ClassFileParser& parser, 1305 jint& size_of_new_bytes, 1306 TRAPS) { 1307 assert(ik != nullptr, "invariant"); 1308 // If the class already has a clinit method 1309 // we need to take that into account 1310 const Method* clinit_method = ik->class_initializer(); 1311 bool untypedEventHandler = false; 1312 const bool register_klass = should_register_klass(ik, untypedEventHandler); 1313 const ClassFileStream* const orig_stream = parser.clone_stream(); 1314 const int orig_stream_size = orig_stream->length(); 1315 assert(orig_stream->current_offset() == 0, "invariant"); 1316 const u2 orig_cp_len = position_stream_after_cp(orig_stream); 1317 assert(orig_cp_len > 0, "invariant"); 1318 assert(orig_stream->current_offset() > 0, "invariant"); 1319 // Dimension and allocate a working byte buffer 1320 // to be used in building up a modified class [B. 1321 const jint new_buffer_size = extra_stream_bytes + orig_stream_size; 1322 u1* const new_buffer = NEW_RESOURCE_ARRAY_IN_THREAD_RETURN_NULL(THREAD, u1, new_buffer_size); 1323 if (new_buffer == nullptr) { 1324 log_error(jfr, system) ("Thread local allocation (native) for %zu" 1325 " bytes failed in JfrEventClassTransformer::on_klass_creation", static_cast<size_t>(new_buffer_size)); 1326 return nullptr; 1327 } 1328 assert(new_buffer != nullptr, "invariant"); 1329 // [B wrapped in a big endian writer 1330 JfrBigEndianWriter writer(new_buffer, new_buffer_size); 1331 assert(writer.current_offset() == 0, "invariant"); 1332 const u4 orig_access_flag_offset = orig_stream->current_offset(); 1333 // Copy original stream from the beginning up to AccessFlags 1334 // This means the original constant pool contents are copied unmodified 1335 writer.write_bytes(orig_stream->buffer(), orig_access_flag_offset); 1336 assert(writer.is_valid(), "invariant"); 1337 assert(writer.current_offset() == (intptr_t)orig_access_flag_offset, "invariant"); // same positions 1338 // Our writer now sits just after the last original constant pool entry. 1339 // I.e. we are in a good position to append new constant pool entries 1340 // This array will contain the resolved indexes 1341 // in order to reference UTF8_INFO's needed 1342 u2 utf8_indexes[NOF_UTF8_SYMBOLS]; 1343 // Resolve_utf8_indexes will be conservative in attempting to 1344 // locate an existing UTF8_INFO; it will only append constants 1345 // that is absolutely required 1346 u2 number_of_new_constants = 1347 resolve_utf8_indexes(writer, ik, utf8_indexes, orig_cp_len, clinit_method, register_klass, untypedEventHandler, THREAD); 1348 // UTF8_INFO entries now added to the constant pool 1349 // In order to invoke a method we would need additional 1350 // constants, JVM_CONSTANT_Class, JVM_CONSTANT_NameAndType 1351 // and JVM_CONSTANT_Methodref. 1352 const u2 flr_register_method_ref_index = 1353 register_klass ? 1354 add_flr_register_method_constants(writer, 1355 utf8_indexes, 1356 orig_cp_len, 1357 number_of_new_constants, 1358 THREAD) : invalid_cp_index; 1359 1360 // New constant pool entries added and all UTF8_INFO indexes resolved 1361 // Now update the class file constant_pool_count with an updated count 1362 writer.write_at_offset<u2>(orig_cp_len + number_of_new_constants, 8); 1363 assert(writer.is_valid(), "invariant"); 1364 orig_stream->skip_u2_fast(3); // access_flags, this_class_index, super_class_index 1365 const u2 iface_len = orig_stream->get_u2_fast(); // interfaces 1366 orig_stream->skip_u2_fast(iface_len); 1367 const u4 orig_fields_len_offset = orig_stream->current_offset(); 1368 // Copy from AccessFlags up to and including interfaces 1369 writer.write_bytes(orig_stream->buffer() + orig_access_flag_offset, 1370 orig_fields_len_offset - orig_access_flag_offset); 1371 assert(writer.is_valid(), "invariant"); 1372 const jlong new_fields_len_offset = writer.current_offset(); 1373 const u2 orig_fields_len = position_stream_after_fields(orig_stream); 1374 u4 orig_method_len_offset = orig_stream->current_offset(); 1375 // Copy up to and including fields 1376 writer.write_bytes(orig_stream->buffer() + orig_fields_len_offset, orig_method_len_offset - orig_fields_len_offset); 1377 assert(writer.is_valid(), "invariant"); 1378 // We are sitting just after the original number of field_infos 1379 // so this is a position where we can add (append) new field_infos 1380 const u2 number_of_new_fields = add_field_infos(writer, utf8_indexes, untypedEventHandler); 1381 assert(writer.is_valid(), "invariant"); 1382 const jlong new_method_len_offset = writer.current_offset(); 1383 // Additional field_infos added, update classfile fields_count 1384 writer.write_at_offset<u2>(orig_fields_len + number_of_new_fields, new_fields_len_offset); 1385 assert(writer.is_valid(), "invariant"); 1386 // Our current location is now at classfile methods_count 1387 const u2 orig_methods_len = position_stream_after_methods(writer, 1388 orig_stream, 1389 utf8_indexes, 1390 register_klass, 1391 clinit_method, 1392 orig_method_len_offset); 1393 const u4 orig_attributes_count_offset = orig_stream->current_offset(); 1394 // Copy existing methods 1395 writer.write_bytes(orig_stream->buffer() + orig_method_len_offset, orig_attributes_count_offset - orig_method_len_offset); 1396 assert(writer.is_valid(), "invariant"); 1397 // We are sitting just after the original number of method_infos 1398 // so this is a position where we can add (append) new method_infos 1399 u2 number_of_new_methods = add_method_infos(writer, utf8_indexes); 1400 1401 // We have just added the new methods. 1402 // 1403 // What about the state of <clinit>? 1404 // We would need to do: 1405 // 1. Nothing (@Registered(false) annotation) 1406 // 2. Build up a new <clinit> - and if the original class already contains a <clinit>, 1407 // merging will be necessary. 1408 // 1409 if (register_klass) { 1410 insert_clinit_method(ik, parser, writer, orig_cp_len, utf8_indexes, flr_register_method_ref_index, clinit_method, THREAD); 1411 if (clinit_method == nullptr) { 1412 ++number_of_new_methods; 1413 } 1414 } 1415 // Update classfile methods_count 1416 writer.write_at_offset<u2>(orig_methods_len + number_of_new_methods, new_method_len_offset); 1417 assert(writer.is_valid(), "invariant"); 1418 // Copy last remaining bytes 1419 writer.write_bytes(orig_stream->buffer() + orig_attributes_count_offset, orig_stream_size - orig_attributes_count_offset); 1420 assert(writer.is_valid(), "invariant"); 1421 assert(writer.current_offset() > orig_stream->length(), "invariant"); 1422 size_of_new_bytes = (jint)writer.current_offset(); 1423 return new_buffer; 1424 } 1425 1426 static bool should_force_instrumentation() { 1427 return !JfrOptionSet::allow_event_retransforms() || JfrEventClassTransformer::is_force_instrumentation(); 1428 } 1429 1430 static void log_pending_exception(oop throwable) { 1431 assert(throwable != nullptr, "invariant"); 1432 oop msg = java_lang_Throwable::message(throwable); 1433 if (msg != nullptr) { 1434 char* text = java_lang_String::as_utf8_string(msg); 1435 if (text != nullptr) { 1436 log_error(jfr, system) ("%s", text); 1437 } 1438 } 1439 } 1440 1441 static bool has_pending_exception(TRAPS) { 1442 assert(THREAD != nullptr, "invariant"); 1443 if (HAS_PENDING_EXCEPTION) { 1444 log_pending_exception(PENDING_EXCEPTION); 1445 CLEAR_PENDING_EXCEPTION; 1446 return true; 1447 } 1448 return false; 1449 } 1450 1451 static bool has_local_method_implementation(const InstanceKlass* ik, const Symbol* name, const Symbol* signature) { 1452 assert(ik != nullptr, "invariant"); 1453 assert(name != nullptr, "invariant"); 1454 assert(signature != nullptr, "invariant"); 1455 return nullptr != ik->find_local_method(name, signature, Klass::OverpassLookupMode::skip, Klass::StaticLookupMode::find, 1456 Klass::PrivateLookupMode::find); 1457 } 1458 1459 // If for a subklass, on initial class load, an implementation exist for any of the final methods declared in Event, 1460 // then constraints are considered breached. 1461 static bool invalid_preconditions_for_subklass_on_initial_load(const InstanceKlass* ik) { 1462 assert(ik != nullptr, "invariant"); 1463 return has_local_method_implementation(ik, begin, void_method_sig) || 1464 has_local_method_implementation(ik, end, void_method_sig) || 1465 has_local_method_implementation(ik, commit, void_method_sig) || 1466 has_local_method_implementation(ik, isEnabled, boolean_method_sig) || 1467 has_local_method_implementation(ik, shouldCommit, boolean_method_sig); 1468 } 1469 1470 static ClassFileStream* schema_extend_event_subklass_bytes(const InstanceKlass* ik, const ClassFileParser& parser, bool& is_instrumented, TRAPS) { 1471 assert(JdkJfrEvent::is_a(ik), "invariant"); 1472 assert(!is_instrumented, "invariant"); 1473 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD)); 1474 initialize_symbols(); 1475 if (invalid_preconditions_for_subklass_on_initial_load(ik)) { 1476 // Remove the tag denoting this as a jdk.jfr.Event subklass. No instrumentation, hence no events can be written. 1477 // The class is allowed to load as-is, but it is classified as outside of the jfr system. 1478 JdkJfrEvent::remove(ik); 1479 return nullptr; 1480 } 1481 jint size_of_new_bytes = 0; 1482 const u1* new_bytes = schema_extend_event_subklass_bytes(ik, parser, size_of_new_bytes, THREAD); 1483 if (new_bytes == nullptr) { 1484 return nullptr; 1485 } 1486 assert(new_bytes != nullptr, "invariant"); 1487 assert(size_of_new_bytes > 0, "invariant"); 1488 const bool force_instrumentation = should_force_instrumentation(); 1489 if (Jfr::is_recording() || force_instrumentation) { 1490 jint size_of_instrumented_bytes = 0; 1491 unsigned char* instrumented_bytes = nullptr; 1492 const jclass super = static_cast<jclass>(JfrJavaSupport::local_jni_handle(ik->super()->java_mirror(), THREAD)); 1493 const jboolean boot_class_loader = ik->class_loader_data()->is_boot_class_loader_data(); 1494 JfrUpcalls::new_bytes_eager_instrumentation(JfrTraceId::load_raw(ik), 1495 force_instrumentation, 1496 boot_class_loader, 1497 super, 1498 size_of_new_bytes, 1499 new_bytes, 1500 &size_of_instrumented_bytes, 1501 &instrumented_bytes, 1502 THREAD); 1503 JfrJavaSupport::destroy_local_jni_handle(super); 1504 if (has_pending_exception(THREAD)) { 1505 return nullptr; 1506 } 1507 assert(instrumented_bytes != nullptr, "invariant"); 1508 assert(size_of_instrumented_bytes > 0, "invariant"); 1509 new_bytes = instrumented_bytes; 1510 size_of_new_bytes = size_of_instrumented_bytes; 1511 is_instrumented = true; 1512 } 1513 return new ClassFileStream(new_bytes, size_of_new_bytes, nullptr); 1514 } 1515 1516 static bool _force_instrumentation = false; 1517 1518 void JfrEventClassTransformer::set_force_instrumentation(bool force_instrumentation) { 1519 _force_instrumentation = force_instrumentation; 1520 } 1521 1522 bool JfrEventClassTransformer::is_force_instrumentation() { 1523 return _force_instrumentation; 1524 } 1525 1526 static ClassFileStream* retransform_bytes(const Klass* existing_klass, const ClassFileParser& parser, bool& is_instrumented, TRAPS) { 1527 assert(existing_klass != nullptr, "invariant"); 1528 assert(!is_instrumented, "invariant"); 1529 assert(JdkJfrEvent::is_a(existing_klass) || JdkJfrEvent::is_host(existing_klass), "invariant"); 1530 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD)); 1531 jint size_of_new_bytes = 0; 1532 unsigned char* new_bytes = nullptr; 1533 const ClassFileStream* const stream = parser.clone_stream(); 1534 assert(stream != nullptr, "invariant"); 1535 const jclass clazz = static_cast<jclass>(JfrJavaSupport::local_jni_handle(existing_klass->java_mirror(), THREAD)); 1536 JfrUpcalls::on_retransform(JfrTraceId::load_raw(existing_klass), 1537 clazz, 1538 stream->length(), 1539 stream->buffer(), 1540 &size_of_new_bytes, 1541 &new_bytes, 1542 THREAD); 1543 JfrJavaSupport::destroy_local_jni_handle(clazz); 1544 if (has_pending_exception(THREAD)) { 1545 return nullptr; 1546 } 1547 assert(new_bytes != nullptr, "invariant"); 1548 assert(size_of_new_bytes > 0, "invariant"); 1549 is_instrumented = true; 1550 return new ClassFileStream(new_bytes, size_of_new_bytes, nullptr); 1551 } 1552 1553 // On initial class load. 1554 static void cache_class_file_data(InstanceKlass* new_ik, const ClassFileStream* new_stream, const JavaThread* thread) { 1555 assert(new_ik != nullptr, "invariant"); 1556 assert(new_stream != nullptr, "invariant"); 1557 assert(thread != nullptr, "invariant"); 1558 assert(!thread->has_pending_exception(), "invariant"); 1559 if (!JfrOptionSet::allow_retransforms()) { 1560 return; 1561 } 1562 const jint stream_len = new_stream->length(); 1563 JvmtiCachedClassFileData* p = 1564 (JvmtiCachedClassFileData*)NEW_C_HEAP_ARRAY_RETURN_NULL(u1, offset_of(JvmtiCachedClassFileData, data) + stream_len, mtInternal); 1565 if (p == nullptr) { 1566 log_error(jfr, system)("Allocation using C_HEAP_ARRAY for %zu bytes failed in JfrEventClassTransformer::cache_class_file_data", 1567 static_cast<size_t>(offset_of(JvmtiCachedClassFileData, data) + stream_len)); 1568 return; 1569 } 1570 p->length = stream_len; 1571 memcpy(p->data, new_stream->buffer(), stream_len); 1572 new_ik->set_cached_class_file(p); 1573 } 1574 1575 // On redefine / retransform, in case an agent modified the class, the original bytes are cached onto the scratch klass. 1576 static void transfer_cached_class_file_data(InstanceKlass* ik, InstanceKlass* new_ik, const ClassFileParser& parser, JavaThread* thread) { 1577 assert(ik != nullptr, "invariant"); 1578 assert(new_ik != nullptr, "invariant"); 1579 JvmtiCachedClassFileData* const p = ik->get_cached_class_file(); 1580 if (p != nullptr) { 1581 new_ik->set_cached_class_file(p); 1582 ik->set_cached_class_file(nullptr); 1583 return; 1584 } 1585 // No cached classfile indicates that no agent modified the klass. 1586 // This means that the parser is holding the original bytes. Hence, we cache it onto the scratch klass. 1587 const ClassFileStream* const stream = parser.clone_stream(); 1588 cache_class_file_data(new_ik, stream, thread); 1589 } 1590 1591 static void rewrite_klass_pointer(InstanceKlass*& ik, InstanceKlass* new_ik, ClassFileParser& parser, const JavaThread* thread) { 1592 assert(ik != nullptr, "invariant"); 1593 assert(new_ik != nullptr, "invariant"); 1594 assert(thread != nullptr, "invariant"); 1595 assert(IS_EVENT_OR_HOST_KLASS(new_ik), "invariant"); 1596 assert(TRACE_ID(ik) == TRACE_ID(new_ik), "invariant"); 1597 assert(!thread->has_pending_exception(), "invariant"); 1598 // Assign original InstanceKlass* back onto "its" parser object for proper destruction. 1599 parser.set_klass_to_deallocate(ik); 1600 // Finally rewrite the original pointer to the newly created InstanceKlass. 1601 ik = new_ik; 1602 } 1603 1604 // If code size is 1, it is 0xb1, i.e. the return instruction. 1605 static inline bool is_commit_method_instrumented(const Method* m) { 1606 assert(m != nullptr, "invariant"); 1607 assert(m->name() == commit, "invariant"); 1608 assert(m->constMethod()->code_size() > 0, "invariant"); 1609 return m->constMethod()->code_size() > 1; 1610 } 1611 1612 static bool bless_static_commit_method(const Array<Method*>* methods) { 1613 assert(methods != nullptr, "invariant"); 1614 for (int i = 0; i < methods->length(); ++i) { 1615 const Method* const m = methods->at(i); 1616 // Method is of the form "static void UserEvent::commit(...)" and instrumented 1617 if (m->is_static() && m->name() == commit && is_commit_method_instrumented(m)) { 1618 BLESS_METHOD(m); 1619 return true; 1620 } 1621 } 1622 return false; 1623 } 1624 1625 static void bless_instance_commit_method(const Array<Method*>* methods) { 1626 assert(methods != nullptr, "invariant"); 1627 for (int i = 0; i < methods->length(); ++i) { 1628 const Method* const m = methods->at(i); 1629 // Method is of the form "void UserEvent:commit()" and instrumented 1630 if (!m->is_static() && 1631 m->name() == commit && 1632 m->signature() == void_method_sig && 1633 is_commit_method_instrumented(m)) { 1634 BLESS_METHOD(m); 1635 } 1636 } 1637 } 1638 1639 // A blessed method is a method that is allowed to link to system sensitive code. 1640 // It is primarily the class file schema extended instance 'commit()V' method. 1641 // Jdk events can also define a static commit method with an arbitrary signature. 1642 static void bless_commit_method(const InstanceKlass* new_ik) { 1643 assert(new_ik != nullptr, "invariant"); 1644 assert(JdkJfrEvent::is_subklass(new_ik), "invariant"); 1645 const Array<Method*>* const methods = new_ik->methods(); 1646 if (new_ik->class_loader() == nullptr) { 1647 // JDK events are allowed an additional commit method that is static. 1648 // Search precedence must therefore inspect static methods first. 1649 if (bless_static_commit_method(methods)) { 1650 return; 1651 } 1652 } 1653 bless_instance_commit_method(methods); 1654 } 1655 1656 static void copy_traceid(const InstanceKlass* ik, const InstanceKlass* new_ik) { 1657 assert(ik != nullptr, "invariant"); 1658 assert(new_ik != nullptr, "invariant"); 1659 new_ik->set_trace_id(ik->trace_id()); 1660 assert(TRACE_ID(ik) == TRACE_ID(new_ik), "invariant"); 1661 } 1662 1663 static const Klass* klass_being_redefined(const InstanceKlass* ik, JvmtiThreadState* state) { 1664 assert(ik != nullptr, "invariant"); 1665 assert(state != nullptr, "invariant"); 1666 const GrowableArray<Klass*>* const redef_klasses = state->get_classes_being_redefined(); 1667 if (redef_klasses == nullptr || redef_klasses->is_empty()) { 1668 return nullptr; 1669 } 1670 for (int i = 0; i < redef_klasses->length(); ++i) { 1671 const Klass* const existing_klass = redef_klasses->at(i); 1672 assert(existing_klass != nullptr, "invariant"); 1673 if (ik->name() == existing_klass->name() && ik->class_loader_data() == existing_klass->class_loader_data()) { 1674 // 'ik' is a scratch klass. Return the klass being redefined. 1675 return existing_klass; 1676 } 1677 } 1678 return nullptr; 1679 } 1680 1681 // Redefining / retransforming? 1682 static const Klass* find_existing_klass(const InstanceKlass* ik, JavaThread* thread) { 1683 assert(ik != nullptr, "invariant"); 1684 assert(thread != nullptr, "invariant"); 1685 JvmtiThreadState* const state = thread->jvmti_thread_state(); 1686 return state != nullptr ? klass_being_redefined(ik, state) : nullptr; 1687 } 1688 1689 static InstanceKlass* create_new_instance_klass(InstanceKlass* ik, ClassFileStream* stream, TRAPS) { 1690 assert(stream != nullptr, "invariant"); 1691 ResourceMark rm(THREAD); 1692 ClassLoaderData* const cld = ik->class_loader_data(); 1693 Handle pd(THREAD, ik->protection_domain()); 1694 Symbol* const class_name = ik->name(); 1695 const char* const klass_name = class_name != nullptr ? class_name->as_C_string() : ""; 1696 ClassLoadInfo cl_info(pd); 1697 ClassFileParser new_parser(stream, 1698 class_name, 1699 cld, 1700 &cl_info, 1701 ClassFileParser::INTERNAL, // internal visibility 1702 THREAD); 1703 if (HAS_PENDING_EXCEPTION) { 1704 log_pending_exception(PENDING_EXCEPTION); 1705 CLEAR_PENDING_EXCEPTION; 1706 return nullptr; 1707 } 1708 const ClassInstanceInfo* cl_inst_info = cl_info.class_hidden_info_ptr(); 1709 InstanceKlass* const new_ik = new_parser.create_instance_klass(false, *cl_inst_info, THREAD); 1710 if (HAS_PENDING_EXCEPTION) { 1711 log_pending_exception(PENDING_EXCEPTION); 1712 CLEAR_PENDING_EXCEPTION; 1713 return nullptr; 1714 } 1715 assert(new_ik != nullptr, "invariant"); 1716 assert(new_ik->name() != nullptr, "invariant"); 1717 assert(strncmp(ik->name()->as_C_string(), new_ik->name()->as_C_string(), strlen(ik->name()->as_C_string())) == 0, "invariant"); 1718 return new_ik; 1719 } 1720 1721 static InstanceKlass* create_instance_klass(InstanceKlass*& ik, ClassFileStream* stream, bool is_initial_load, JavaThread* thread) { 1722 if (stream == nullptr) { 1723 if (is_initial_load) { 1724 log_error(jfr, system)("JfrEventClassTransformer: unable to create ClassFileStream for %s", ik->external_name()); 1725 } 1726 return nullptr; 1727 } 1728 InstanceKlass* const new_ik = create_new_instance_klass(ik, stream, thread); 1729 if (new_ik == nullptr) { 1730 if (is_initial_load) { 1731 log_error(jfr, system)("JfrEventClassTransformer: unable to create InstanceKlass for %s", ik->external_name()); 1732 } 1733 } 1734 return new_ik; 1735 } 1736 1737 static void transform(InstanceKlass*& ik, ClassFileParser& parser, JavaThread* thread) { 1738 assert(IS_EVENT_OR_HOST_KLASS(ik), "invariant"); 1739 bool is_instrumented = false; 1740 ClassFileStream* stream = nullptr; 1741 const Klass* const existing_klass = find_existing_klass(ik, thread); 1742 if (existing_klass != nullptr) { 1743 // There is already a klass defined, implying we are redefining / retransforming. 1744 stream = retransform_bytes(existing_klass, parser, is_instrumented, thread); 1745 } else { 1746 // No existing klass, implying this is the initial load. 1747 stream = JdkJfrEvent::is(ik) ? schema_extend_event_klass_bytes(ik, parser, thread) : schema_extend_event_subklass_bytes(ik, parser, is_instrumented, thread); 1748 } 1749 InstanceKlass* const new_ik = create_instance_klass(ik, stream, existing_klass == nullptr, thread); 1750 if (new_ik == nullptr) { 1751 return; 1752 } 1753 if (existing_klass != nullptr) { 1754 transfer_cached_class_file_data(ik, new_ik, parser, thread); 1755 } else { 1756 cache_class_file_data(new_ik, stream, thread); 1757 } 1758 if (is_instrumented && JdkJfrEvent::is_subklass(new_ik)) { 1759 bless_commit_method(new_ik); 1760 } 1761 copy_traceid(ik, new_ik); 1762 rewrite_klass_pointer(ik, new_ik, parser, thread); 1763 } 1764 1765 // Target for the JFR_ON_KLASS_CREATION hook. 1766 // Extends the class file schema on initial class load or reinstruments on redefine / retransform. 1767 // The passed in parameter 'ik' acts as an in-out parameter: it is rewritten to point to a replaced 1768 // instance of the passed in InstanceKlass. The original 'ik' will be set onto the passed parser, 1769 // for destruction when the parser goes out of scope. 1770 void JfrEventClassTransformer::on_klass_creation(InstanceKlass*& ik, ClassFileParser& parser, TRAPS) { 1771 assert(ik != nullptr, "invariant"); 1772 assert(IS_EVENT_OR_HOST_KLASS(ik), "invariant"); 1773 if (ik->is_abstract() && !JdkJfrEvent::is(ik)) { 1774 assert(JdkJfrEvent::is_subklass(ik), "invariant"); 1775 // Abstract subklasses are not instrumented. 1776 return; 1777 } 1778 ResourceMark rm(THREAD); 1779 HandleMark hm(THREAD); 1780 transform(ik, parser, THREAD); 1781 } 1782 1783 static bool is_static_commit_method_blessed(const Array<Method*>* methods) { 1784 assert(methods != nullptr, "invariant"); 1785 for (int i = 0; i < methods->length(); ++i) { 1786 const Method* const m = methods->at(i); 1787 // Must be of form: static void UserEvent::commit(...) 1788 if (m->is_static() && m->name() == commit) { 1789 return IS_METHOD_BLESSED(m); 1790 } 1791 } 1792 return false; 1793 } 1794 1795 static bool is_instance_commit_method_blessed(const Array<Method*>* methods) { 1796 assert(methods != nullptr, "invariant"); 1797 for (int i = 0; i < methods->length(); ++i) { 1798 const Method* const m = methods->at(i); 1799 // Must be of form: void UserEvent::commit() 1800 if (!m->is_static() && m->name() == commit && m->signature() == void_method_sig) { 1801 return IS_METHOD_BLESSED(m); 1802 } 1803 } 1804 return false; 1805 } 1806 1807 bool JfrEventClassTransformer::is_instrumented(const InstanceKlass* ik) { 1808 assert(ik != nullptr, "invariant"); 1809 assert(JdkJfrEvent::is_subklass(ik), "invariant"); 1810 const Array<Method*>* const methods = ik->methods(); 1811 if (ik->class_loader() == nullptr) { 1812 // JDK events are allowed an additional commit method that is static. 1813 // Search precedence must therefore inspect static methods first. 1814 if (is_static_commit_method_blessed(methods)) { 1815 return true; 1816 } 1817 } 1818 return is_instance_commit_method_blessed(methods); 1819 }