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