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