Path: blob/jdk8u272-b10-aarch32-20201026/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp
48773 views
/*1* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "classfile/symbolTable.hpp"26#include "interpreter/bytecodeStream.hpp"27#include "oops/fieldStreams.hpp"28#include "prims/jvmtiClassFileReconstituter.hpp"29#include "runtime/signature.hpp"30#ifdef TARGET_ARCH_x8631# include "bytes_x86.hpp"32#endif33#ifdef TARGET_ARCH_aarch6434# include "bytes_aarch64.hpp"35#endif36#ifdef TARGET_ARCH_sparc37# include "bytes_sparc.hpp"38#endif39#ifdef TARGET_ARCH_zero40# include "bytes_zero.hpp"41#endif42#ifdef TARGET_ARCH_arm43# include "bytes_arm.hpp"44#endif45#ifdef TARGET_ARCH_ppc46# include "bytes_ppc.hpp"47#endif48#ifdef TARGET_ARCH_aarch3249# include "bytes_aarch32.hpp"50#endif5152// FIXME: add Deprecated attribute53// FIXME: fix Synthetic attribute54// FIXME: per Serguei, add error return handling for ConstantPool::copy_cpool_bytes()555657// Write the field information portion of ClassFile structure58// JVMSpec| u2 fields_count;59// JVMSpec| field_info fields[fields_count];60void JvmtiClassFileReconstituter::write_field_infos() {61HandleMark hm(thread());62Array<AnnotationArray*>* fields_anno = ikh()->fields_annotations();63Array<AnnotationArray*>* fields_type_anno = ikh()->fields_type_annotations();6465// Compute the real number of Java fields66int java_fields = ikh()->java_fields_count();6768write_u2(java_fields);69for (JavaFieldStream fs(ikh()); !fs.done(); fs.next()) {70AccessFlags access_flags = fs.access_flags();71int name_index = fs.name_index();72int signature_index = fs.signature_index();73int initial_value_index = fs.initval_index();74guarantee(name_index != 0 && signature_index != 0, "bad constant pool index for field");75// int offset = ikh()->field_offset( index );76int generic_signature_index = fs.generic_signature_index();77AnnotationArray* anno = fields_anno == NULL ? NULL : fields_anno->at(fs.index());78AnnotationArray* type_anno = fields_type_anno == NULL ? NULL : fields_type_anno->at(fs.index());7980// JVMSpec| field_info {81// JVMSpec| u2 access_flags;82// JVMSpec| u2 name_index;83// JVMSpec| u2 descriptor_index;84// JVMSpec| u2 attributes_count;85// JVMSpec| attribute_info attributes[attributes_count];86// JVMSpec| }8788write_u2(access_flags.as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS);89write_u2(name_index);90write_u2(signature_index);91int attr_count = 0;92if (initial_value_index != 0) {93++attr_count;94}95if (access_flags.is_synthetic()) {96// ++attr_count;97}98if (generic_signature_index != 0) {99++attr_count;100}101if (anno != NULL) {102++attr_count; // has RuntimeVisibleAnnotations attribute103}104if (type_anno != NULL) {105++attr_count; // has RuntimeVisibleTypeAnnotations attribute106}107108write_u2(attr_count);109110if (initial_value_index != 0) {111write_attribute_name_index("ConstantValue");112write_u4(2); //length always 2113write_u2(initial_value_index);114}115if (access_flags.is_synthetic()) {116// write_synthetic_attribute();117}118if (generic_signature_index != 0) {119write_signature_attribute(generic_signature_index);120}121if (anno != NULL) {122write_annotations_attribute("RuntimeVisibleAnnotations", anno);123}124if (type_anno != NULL) {125write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);126}127}128}129130// Write Code attribute131// JVMSpec| Code_attribute {132// JVMSpec| u2 attribute_name_index;133// JVMSpec| u4 attribute_length;134// JVMSpec| u2 max_stack;135// JVMSpec| u2 max_locals;136// JVMSpec| u4 code_length;137// JVMSpec| u1 code[code_length];138// JVMSpec| u2 exception_table_length;139// JVMSpec| { u2 start_pc;140// JVMSpec| u2 end_pc;141// JVMSpec| u2 handler_pc;142// JVMSpec| u2 catch_type;143// JVMSpec| } exception_table[exception_table_length];144// JVMSpec| u2 attributes_count;145// JVMSpec| attribute_info attributes[attributes_count];146// JVMSpec| }147void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) {148ConstMethod* const_method = method->constMethod();149u2 line_num_cnt = 0;150int stackmap_len = 0;151int local_variable_table_length = 0;152int local_variable_type_table_length = 0;153154// compute number and length of attributes155int attr_count = 0;156int attr_size = 0;157if (const_method->has_linenumber_table()) {158line_num_cnt = line_number_table_entries(method);159if (line_num_cnt != 0) {160++attr_count;161// Compute the complete size of the line number table attribute:162// LineNumberTable_attribute {163// u2 attribute_name_index;164// u4 attribute_length;165// u2 line_number_table_length;166// { u2 start_pc;167// u2 line_number;168// } line_number_table[line_number_table_length];169// }170attr_size += 2 + 4 + 2 + line_num_cnt * (2 + 2);171}172}173if (method->has_stackmap_table()) {174stackmap_len = method->stackmap_data()->length();175if (stackmap_len != 0) {176++attr_count;177// Compute the size of the stack map table attribute (VM stores raw):178// StackMapTable_attribute {179// u2 attribute_name_index;180// u4 attribute_length;181// u2 number_of_entries;182// stack_map_frame_entries[number_of_entries];183// }184attr_size += 2 + 4 + stackmap_len;185}186}187if (method->has_localvariable_table()) {188local_variable_table_length = method->localvariable_table_length();189if (local_variable_table_length != 0) {190++attr_count;191// Compute the size of the local variable table attribute (VM stores raw):192// LocalVariableTable_attribute {193// u2 attribute_name_index;194// u4 attribute_length;195// u2 local_variable_table_length;196// {197// u2 start_pc;198// u2 length;199// u2 name_index;200// u2 descriptor_index;201// u2 index;202// }203attr_size += 2 + 4 + 2 + local_variable_table_length * (2 + 2 + 2 + 2 + 2);204205// Local variables with generic signatures must have LVTT entries206LocalVariableTableElement *elem = method->localvariable_table_start();207for (int idx = 0; idx < local_variable_table_length; idx++) {208if (elem[idx].signature_cp_index != 0) {209local_variable_type_table_length++;210}211}212213if (local_variable_type_table_length != 0) {214++attr_count;215// Compute the size of the local variable type table attribute (VM stores raw):216// LocalVariableTypeTable_attribute {217// u2 attribute_name_index;218// u4 attribute_length;219// u2 local_variable_type_table_length;220// {221// u2 start_pc;222// u2 length;223// u2 name_index;224// u2 signature_index;225// u2 index;226// }227attr_size += 2 + 4 + 2 + local_variable_type_table_length * (2 + 2 + 2 + 2 + 2);228}229}230}231232ExceptionTable exception_table(method());233int exception_table_length = exception_table.length();234int code_size = const_method->code_size();235int size =2362+2+4 + // max_stack, max_locals, code_length237code_size + // code2382 + // exception_table_length239(2+2+2+2) * exception_table_length + // exception_table2402 + // attributes_count241attr_size; // attributes242243write_attribute_name_index("Code");244write_u4(size);245write_u2(method->verifier_max_stack());246write_u2(method->max_locals());247write_u4(code_size);248copy_bytecodes(method, (unsigned char*)writeable_address(code_size));249write_u2(exception_table_length);250for (int index = 0; index < exception_table_length; index++) {251write_u2(exception_table.start_pc(index));252write_u2(exception_table.end_pc(index));253write_u2(exception_table.handler_pc(index));254write_u2(exception_table.catch_type_index(index));255}256write_u2(attr_count);257if (line_num_cnt != 0) {258write_line_number_table_attribute(method, line_num_cnt);259}260if (stackmap_len != 0) {261write_stackmap_table_attribute(method, stackmap_len);262}263if (local_variable_table_length != 0) {264write_local_variable_table_attribute(method, local_variable_table_length);265}266if (local_variable_type_table_length != 0) {267write_local_variable_type_table_attribute(method, local_variable_type_table_length);268}269}270271// Write Exceptions attribute272// JVMSpec| Exceptions_attribute {273// JVMSpec| u2 attribute_name_index;274// JVMSpec| u4 attribute_length;275// JVMSpec| u2 number_of_exceptions;276// JVMSpec| u2 exception_index_table[number_of_exceptions];277// JVMSpec| }278void JvmtiClassFileReconstituter::write_exceptions_attribute(ConstMethod* const_method) {279CheckedExceptionElement* checked_exceptions = const_method->checked_exceptions_start();280int checked_exceptions_length = const_method->checked_exceptions_length();281int size =2822 + // number_of_exceptions2832 * checked_exceptions_length; // exception_index_table284285write_attribute_name_index("Exceptions");286write_u4(size);287write_u2(checked_exceptions_length);288for (int index = 0; index < checked_exceptions_length; index++) {289write_u2(checked_exceptions[index].class_cp_index);290}291}292293// Write SourceFile attribute294// JVMSpec| SourceFile_attribute {295// JVMSpec| u2 attribute_name_index;296// JVMSpec| u4 attribute_length;297// JVMSpec| u2 sourcefile_index;298// JVMSpec| }299void JvmtiClassFileReconstituter::write_source_file_attribute() {300assert(ikh()->source_file_name() != NULL, "caller must check");301302write_attribute_name_index("SourceFile");303write_u4(2); // always length 2304write_u2(symbol_to_cpool_index(ikh()->source_file_name()));305}306307// Write SourceDebugExtension attribute308// JSR45| SourceDebugExtension_attribute {309// JSR45| u2 attribute_name_index;310// JSR45| u4 attribute_length;311// JSR45| u1 debug_extension[attribute_length];312// JSR45| }313void JvmtiClassFileReconstituter::write_source_debug_extension_attribute() {314assert(ikh()->source_debug_extension() != NULL, "caller must check");315316write_attribute_name_index("SourceDebugExtension");317int len = (int)strlen(ikh()->source_debug_extension());318write_u4(len);319u1* ext = (u1*)ikh()->source_debug_extension();320for (int i=0; i<len; i++) {321write_u1(ext[i]);322}323}324325// Write (generic) Signature attribute326// JVMSpec| Signature_attribute {327// JVMSpec| u2 attribute_name_index;328// JVMSpec| u4 attribute_length;329// JVMSpec| u2 signature_index;330// JVMSpec| }331void JvmtiClassFileReconstituter::write_signature_attribute(u2 generic_signature_index) {332write_attribute_name_index("Signature");333write_u4(2); // always length 2334write_u2(generic_signature_index);335}336337// Compute the number of entries in the InnerClasses attribute338u2 JvmtiClassFileReconstituter::inner_classes_attribute_length() {339InnerClassesIterator iter(ikh());340return iter.length();341}342343// Write an annotation attribute. The VM stores them in raw form, so all we need344// to do is add the attrubute name and fill in the length.345// JSR202| *Annotations_attribute {346// JSR202| u2 attribute_name_index;347// JSR202| u4 attribute_length;348// JSR202| ...349// JSR202| }350void JvmtiClassFileReconstituter::write_annotations_attribute(const char* attr_name,351AnnotationArray* annos) {352u4 length = annos->length();353write_attribute_name_index(attr_name);354write_u4(length);355memcpy(writeable_address(length), annos->adr_at(0), length);356}357358// BootstrapMethods_attribute {359// u2 attribute_name_index;360// u4 attribute_length;361// u2 num_bootstrap_methods;362// { u2 bootstrap_method_ref;363// u2 num_bootstrap_arguments;364// u2 bootstrap_arguments[num_bootstrap_arguments];365// } bootstrap_methods[num_bootstrap_methods];366// }367void JvmtiClassFileReconstituter::write_bootstrapmethod_attribute() {368Array<u2>* operands = cpool()->operands();369write_attribute_name_index("BootstrapMethods");370int num_bootstrap_methods = ConstantPool::operand_array_length(operands);371372// calculate length of attribute373int length = sizeof(u2); // num_bootstrap_methods374for (int n = 0; n < num_bootstrap_methods; n++) {375u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n);376length += sizeof(u2); // bootstrap_method_ref377length += sizeof(u2); // num_bootstrap_arguments378length += sizeof(u2) * num_bootstrap_arguments; // bootstrap_arguments[num_bootstrap_arguments]379}380write_u4(length);381382// write attribute383write_u2(num_bootstrap_methods);384for (int n = 0; n < num_bootstrap_methods; n++) {385u2 bootstrap_method_ref = cpool()->operand_bootstrap_method_ref_index_at(n);386u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n);387write_u2(bootstrap_method_ref);388write_u2(num_bootstrap_arguments);389for (int arg = 0; arg < num_bootstrap_arguments; arg++) {390u2 bootstrap_argument = cpool()->operand_argument_index_at(n, arg);391write_u2(bootstrap_argument);392}393}394}395396397// Write InnerClasses attribute398// JVMSpec| InnerClasses_attribute {399// JVMSpec| u2 attribute_name_index;400// JVMSpec| u4 attribute_length;401// JVMSpec| u2 number_of_classes;402// JVMSpec| { u2 inner_class_info_index;403// JVMSpec| u2 outer_class_info_index;404// JVMSpec| u2 inner_name_index;405// JVMSpec| u2 inner_class_access_flags;406// JVMSpec| } classes[number_of_classes];407// JVMSpec| }408void JvmtiClassFileReconstituter::write_inner_classes_attribute(int length) {409InnerClassesIterator iter(ikh());410guarantee(iter.length() != 0 && iter.length() == length,411"caller must check");412u2 entry_count = length / InstanceKlass::inner_class_next_offset;413u4 size = 2 + entry_count * (2+2+2+2);414415write_attribute_name_index("InnerClasses");416write_u4(size);417write_u2(entry_count);418for (; !iter.done(); iter.next()) {419write_u2(iter.inner_class_info_index());420write_u2(iter.outer_class_info_index());421write_u2(iter.inner_name_index());422write_u2(iter.inner_access_flags());423}424}425426// Write Synthetic attribute427// JVMSpec| Synthetic_attribute {428// JVMSpec| u2 attribute_name_index;429// JVMSpec| u4 attribute_length;430// JVMSpec| }431void JvmtiClassFileReconstituter::write_synthetic_attribute() {432write_attribute_name_index("Synthetic");433write_u4(0); //length always zero434}435436// Compute size of LineNumberTable437u2 JvmtiClassFileReconstituter::line_number_table_entries(methodHandle method) {438// The line number table is compressed so we don't know how big it is until decompressed.439// Decompression is really fast so we just do it twice.440u2 num_entries = 0;441CompressedLineNumberReadStream stream(method->compressed_linenumber_table());442while (stream.read_pair()) {443num_entries++;444}445return num_entries;446}447448// Write LineNumberTable attribute449// JVMSpec| LineNumberTable_attribute {450// JVMSpec| u2 attribute_name_index;451// JVMSpec| u4 attribute_length;452// JVMSpec| u2 line_number_table_length;453// JVMSpec| { u2 start_pc;454// JVMSpec| u2 line_number;455// JVMSpec| } line_number_table[line_number_table_length];456// JVMSpec| }457void JvmtiClassFileReconstituter::write_line_number_table_attribute(methodHandle method,458u2 num_entries) {459460write_attribute_name_index("LineNumberTable");461write_u4(2 + num_entries * (2 + 2));462write_u2(num_entries);463464CompressedLineNumberReadStream stream(method->compressed_linenumber_table());465while (stream.read_pair()) {466write_u2(stream.bci());467write_u2(stream.line());468}469}470471// Write LocalVariableTable attribute472// JVMSpec| LocalVariableTable_attribute {473// JVMSpec| u2 attribute_name_index;474// JVMSpec| u4 attribute_length;475// JVMSpec| u2 local_variable_table_length;476// JVMSpec| { u2 start_pc;477// JVMSpec| u2 length;478// JVMSpec| u2 name_index;479// JVMSpec| u2 descriptor_index;480// JVMSpec| u2 index;481// JVMSpec| } local_variable_table[local_variable_table_length];482// JVMSpec| }483void JvmtiClassFileReconstituter::write_local_variable_table_attribute(methodHandle method, u2 num_entries) {484write_attribute_name_index("LocalVariableTable");485write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2));486write_u2(num_entries);487488assert(method->localvariable_table_length() == num_entries, "just checking");489490LocalVariableTableElement *elem = method->localvariable_table_start();491for (int j=0; j<method->localvariable_table_length(); j++) {492write_u2(elem->start_bci);493write_u2(elem->length);494write_u2(elem->name_cp_index);495write_u2(elem->descriptor_cp_index);496write_u2(elem->slot);497elem++;498}499}500501// Write LocalVariableTypeTable attribute502// JVMSpec| LocalVariableTypeTable_attribute {503// JVMSpec| u2 attribute_name_index;504// JVMSpec| u4 attribute_length;505// JVMSpec| u2 local_variable_type_table_length;506// JVMSpec| { u2 start_pc;507// JVMSpec| u2 length;508// JVMSpec| u2 name_index;509// JVMSpec| u2 signature_index;510// JVMSpec| u2 index;511// JVMSpec| } local_variable_type_table[local_variable_type_table_length];512// JVMSpec| }513void JvmtiClassFileReconstituter::write_local_variable_type_table_attribute(methodHandle method, u2 num_entries) {514write_attribute_name_index("LocalVariableTypeTable");515write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2));516write_u2(num_entries);517518LocalVariableTableElement *elem = method->localvariable_table_start();519for (int j=0; j<method->localvariable_table_length(); j++) {520if (elem->signature_cp_index > 0) {521// Local variable has a generic signature - write LVTT attribute entry522write_u2(elem->start_bci);523write_u2(elem->length);524write_u2(elem->name_cp_index);525write_u2(elem->signature_cp_index);526write_u2(elem->slot);527num_entries--;528}529elem++;530}531assert(num_entries == 0, "just checking");532}533534// Write stack map table attribute535// JSR-202| StackMapTable_attribute {536// JSR-202| u2 attribute_name_index;537// JSR-202| u4 attribute_length;538// JSR-202| u2 number_of_entries;539// JSR-202| stack_map_frame_entries[number_of_entries];540// JSR-202| }541void JvmtiClassFileReconstituter::write_stackmap_table_attribute(methodHandle method,542int stackmap_len) {543544write_attribute_name_index("StackMapTable");545write_u4(stackmap_len);546memcpy(547writeable_address(stackmap_len),548(void*)(method->stackmap_data()->adr_at(0)),549stackmap_len);550}551552// Write one method_info structure553// JVMSpec| method_info {554// JVMSpec| u2 access_flags;555// JVMSpec| u2 name_index;556// JVMSpec| u2 descriptor_index;557// JVMSpec| u2 attributes_count;558// JVMSpec| attribute_info attributes[attributes_count];559// JVMSpec| }560void JvmtiClassFileReconstituter::write_method_info(methodHandle method) {561AccessFlags access_flags = method->access_flags();562ConstMethod* const_method = method->constMethod();563u2 generic_signature_index = const_method->generic_signature_index();564AnnotationArray* anno = method->annotations();565AnnotationArray* param_anno = method->parameter_annotations();566AnnotationArray* default_anno = method->annotation_default();567AnnotationArray* type_anno = method->type_annotations();568569// skip generated default interface methods570if (method->is_overpass()) {571return;572}573574write_u2(access_flags.get_flags() & JVM_RECOGNIZED_METHOD_MODIFIERS);575write_u2(const_method->name_index());576write_u2(const_method->signature_index());577578// write attributes in the same order javac does, so we can test with byte for579// byte comparison580int attr_count = 0;581if (const_method->code_size() != 0) {582++attr_count; // has Code attribute583}584if (const_method->has_checked_exceptions()) {585++attr_count; // has Exceptions attribute586}587if (default_anno != NULL) {588++attr_count; // has AnnotationDefault attribute589}590// Deprecated attribute would go here591if (access_flags.is_synthetic()) { // FIXME592// ++attr_count;593}594if (generic_signature_index != 0) {595++attr_count;596}597if (anno != NULL) {598++attr_count; // has RuntimeVisibleAnnotations attribute599}600if (param_anno != NULL) {601++attr_count; // has RuntimeVisibleParameterAnnotations attribute602}603if (type_anno != NULL) {604++attr_count; // has RuntimeVisibleTypeAnnotations attribute605}606607write_u2(attr_count);608if (const_method->code_size() > 0) {609write_code_attribute(method);610}611if (const_method->has_checked_exceptions()) {612write_exceptions_attribute(const_method);613}614if (default_anno != NULL) {615write_annotations_attribute("AnnotationDefault", default_anno);616}617// Deprecated attribute would go here618if (access_flags.is_synthetic()) {619// write_synthetic_attribute();620}621if (generic_signature_index != 0) {622write_signature_attribute(generic_signature_index);623}624if (anno != NULL) {625write_annotations_attribute("RuntimeVisibleAnnotations", anno);626}627if (param_anno != NULL) {628write_annotations_attribute("RuntimeVisibleParameterAnnotations", param_anno);629}630if (type_anno != NULL) {631write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);632}633}634635// Write the class attributes portion of ClassFile structure636// JVMSpec| u2 attributes_count;637// JVMSpec| attribute_info attributes[attributes_count];638void JvmtiClassFileReconstituter::write_class_attributes() {639u2 inner_classes_length = inner_classes_attribute_length();640Symbol* generic_signature = ikh()->generic_signature();641AnnotationArray* anno = ikh()->class_annotations();642AnnotationArray* type_anno = ikh()->class_type_annotations();643644int attr_count = 0;645if (generic_signature != NULL) {646++attr_count;647}648if (ikh()->source_file_name() != NULL) {649++attr_count;650}651if (ikh()->source_debug_extension() != NULL) {652++attr_count;653}654if (inner_classes_length > 0) {655++attr_count;656}657if (anno != NULL) {658++attr_count; // has RuntimeVisibleAnnotations attribute659}660if (type_anno != NULL) {661++attr_count; // has RuntimeVisibleTypeAnnotations attribute662}663if (cpool()->operands() != NULL) {664++attr_count;665}666667write_u2(attr_count);668669if (generic_signature != NULL) {670write_signature_attribute(symbol_to_cpool_index(generic_signature));671}672if (ikh()->source_file_name() != NULL) {673write_source_file_attribute();674}675if (ikh()->source_debug_extension() != NULL) {676write_source_debug_extension_attribute();677}678if (inner_classes_length > 0) {679write_inner_classes_attribute(inner_classes_length);680}681if (anno != NULL) {682write_annotations_attribute("RuntimeVisibleAnnotations", anno);683}684if (type_anno != NULL) {685write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);686}687if (cpool()->operands() != NULL) {688write_bootstrapmethod_attribute();689}690}691692// Write the method information portion of ClassFile structure693// JVMSpec| u2 methods_count;694// JVMSpec| method_info methods[methods_count];695void JvmtiClassFileReconstituter::write_method_infos() {696HandleMark hm(thread());697Array<Method*>* methods = ikh()->methods();698int num_methods = methods->length();699int num_overpass = 0;700701// count the generated default interface methods702// these will not be re-created by write_method_info703// and should not be included in the total count704for (int index = 0; index < num_methods; index++) {705Method* method = methods->at(index);706if (method->is_overpass()) {707num_overpass++;708}709}710711write_u2(num_methods - num_overpass);712if (JvmtiExport::can_maintain_original_method_order()) {713int index;714int original_index;715intArray method_order(num_methods, 0);716717// invert the method order mapping718for (index = 0; index < num_methods; index++) {719original_index = ikh()->method_ordering()->at(index);720assert(original_index >= 0 && original_index < num_methods,721"invalid original method index");722method_order.at_put(original_index, index);723}724725// write in original order726for (original_index = 0; original_index < num_methods; original_index++) {727index = method_order.at(original_index);728methodHandle method(thread(), methods->at(index));729write_method_info(method);730}731} else {732// method order not preserved just dump the method infos733for (int index = 0; index < num_methods; index++) {734methodHandle method(thread(), methods->at(index));735write_method_info(method);736}737}738}739740void JvmtiClassFileReconstituter::write_class_file_format() {741ReallocMark();742743// JVMSpec| ClassFile {744// JVMSpec| u4 magic;745write_u4(0xCAFEBABE);746747// JVMSpec| u2 minor_version;748// JVMSpec| u2 major_version;749write_u2(ikh()->minor_version());750u2 major = ikh()->major_version();751write_u2(major);752753// JVMSpec| u2 constant_pool_count;754// JVMSpec| cp_info constant_pool[constant_pool_count-1];755write_u2(cpool()->length());756copy_cpool_bytes(writeable_address(cpool_size()));757758// JVMSpec| u2 access_flags;759write_u2(ikh()->access_flags().get_flags() & JVM_RECOGNIZED_CLASS_MODIFIERS);760761// JVMSpec| u2 this_class;762// JVMSpec| u2 super_class;763write_u2(class_symbol_to_cpool_index(ikh()->name()));764Klass* super_class = ikh()->super();765write_u2(super_class == NULL? 0 : // zero for java.lang.Object766class_symbol_to_cpool_index(super_class->name()));767768// JVMSpec| u2 interfaces_count;769// JVMSpec| u2 interfaces[interfaces_count];770Array<Klass*>* interfaces = ikh()->local_interfaces();771int num_interfaces = interfaces->length();772write_u2(num_interfaces);773for (int index = 0; index < num_interfaces; index++) {774HandleMark hm(thread());775instanceKlassHandle iikh(thread(), interfaces->at(index));776write_u2(class_symbol_to_cpool_index(iikh->name()));777}778779// JVMSpec| u2 fields_count;780// JVMSpec| field_info fields[fields_count];781write_field_infos();782783// JVMSpec| u2 methods_count;784// JVMSpec| method_info methods[methods_count];785write_method_infos();786787// JVMSpec| u2 attributes_count;788// JVMSpec| attribute_info attributes[attributes_count];789// JVMSpec| } /* end ClassFile 8?790write_class_attributes();791}792793address JvmtiClassFileReconstituter::writeable_address(size_t size) {794size_t used_size = _buffer_ptr - _buffer;795if (size + used_size >= _buffer_size) {796// compute the new buffer size: must be at least twice as big as before797// plus whatever new is being used; then convert to nice clean block boundary798size_t new_buffer_size = (size + _buffer_size*2 + 1) / initial_buffer_size799* initial_buffer_size;800801// VM goes belly-up if the memory isn't available, so cannot do OOM processing802_buffer = REALLOC_RESOURCE_ARRAY(u1, _buffer, _buffer_size, new_buffer_size);803_buffer_size = new_buffer_size;804_buffer_ptr = _buffer + used_size;805}806u1* ret_ptr = _buffer_ptr;807_buffer_ptr += size;808return ret_ptr;809}810811void JvmtiClassFileReconstituter::write_attribute_name_index(const char* name) {812TempNewSymbol sym = SymbolTable::probe(name, (int)strlen(name));813assert(sym != NULL, "attribute name symbol not found");814u2 attr_name_index = symbol_to_cpool_index(sym);815assert(attr_name_index != 0, "attribute name symbol not in constant pool");816write_u2(attr_name_index);817}818819void JvmtiClassFileReconstituter::write_u1(u1 x) {820*writeable_address(1) = x;821}822823void JvmtiClassFileReconstituter::write_u2(u2 x) {824Bytes::put_Java_u2(writeable_address(2), x);825}826827void JvmtiClassFileReconstituter::write_u4(u4 x) {828Bytes::put_Java_u4(writeable_address(4), x);829}830831void JvmtiClassFileReconstituter::write_u8(u8 x) {832Bytes::put_Java_u8(writeable_address(8), x);833}834835void JvmtiClassFileReconstituter::copy_bytecodes(methodHandle mh,836unsigned char* bytecodes) {837// use a BytecodeStream to iterate over the bytecodes. JVM/fast bytecodes838// and the breakpoint bytecode are converted to their original bytecodes.839840BytecodeStream bs(mh);841842unsigned char* p = bytecodes;843Bytecodes::Code code;844bool is_rewritten = mh->method_holder()->is_rewritten();845846while ((code = bs.next()) >= 0) {847assert(Bytecodes::is_java_code(code), "sanity check");848assert(code != Bytecodes::_breakpoint, "sanity check");849850// length of bytecode (mnemonic + operands)851address bcp = bs.bcp();852int len = bs.instruction_size();853assert(len > 0, "length must be > 0");854855// copy the bytecodes856*p = (unsigned char) (bs.is_wide()? Bytecodes::_wide : code);857if (len > 1) {858memcpy(p+1, bcp+1, len-1);859}860861// During linking the get/put and invoke instructions are rewritten862// with an index into the constant pool cache. The original constant863// pool index must be returned to caller. Rewrite the index.864if (is_rewritten && len > 1) {865bool is_wide = false;866switch (code) {867case Bytecodes::_getstatic : // fall through868case Bytecodes::_putstatic : // fall through869case Bytecodes::_getfield : // fall through870case Bytecodes::_putfield : // fall through871case Bytecodes::_invokevirtual : // fall through872case Bytecodes::_invokespecial : // fall through873case Bytecodes::_invokestatic : // fall through874case Bytecodes::_invokedynamic : // fall through875case Bytecodes::_invokeinterface : {876assert(len == 3 ||877(code == Bytecodes::_invokeinterface && len == 5) ||878(code == Bytecodes::_invokedynamic && len == 5),879"sanity check");880881int cpci = Bytes::get_native_u2(bcp+1);882bool is_invokedynamic = (EnableInvokeDynamic && code == Bytecodes::_invokedynamic);883ConstantPoolCacheEntry* entry;884if (is_invokedynamic) {885cpci = Bytes::get_native_u4(bcp+1);886entry = mh->constants()->invokedynamic_cp_cache_entry_at(cpci);887} else {888// cache cannot be pre-fetched since some classes won't have it yet889entry = mh->constants()->cache()->entry_at(cpci);890}891int i = entry->constant_pool_index();892assert(i < mh->constants()->length(), "sanity check");893Bytes::put_Java_u2((address)(p+1), (u2)i); // java byte ordering894if (is_invokedynamic) *(p+3) = *(p+4) = 0;895break;896}897case Bytecodes::_ldc_w:898is_wide = true; // fall through899case Bytecodes::_ldc: {900if (bs.raw_code() == Bytecodes::_fast_aldc || bs.raw_code() == Bytecodes::_fast_aldc_w) {901int cpci = is_wide ? Bytes::get_native_u2(bcp+1) : (u1)(*(bcp+1));902int i = mh->constants()->object_to_cp_index(cpci);903assert(i < mh->constants()->length(), "sanity check");904if (is_wide) {905Bytes::put_Java_u2((address)(p+1), (u2)i); // java byte ordering906} else {907*(p+1) = (u1)i;908}909}910break;911}912}913}914915p += len;916}917}918919920