Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp
32285 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_aarch3234# include "bytes_aarch32.hpp"35#endif36#ifdef TARGET_ARCH_aarch6437# include "bytes_aarch64.hpp"38#endif39#ifdef TARGET_ARCH_sparc40# include "bytes_sparc.hpp"41#endif42#ifdef TARGET_ARCH_zero43# include "bytes_zero.hpp"44#endif45#ifdef TARGET_ARCH_arm46# include "bytes_arm.hpp"47#endif48#ifdef TARGET_ARCH_ppc49# include "bytes_ppc.hpp"50#endif51// FIXME: add Deprecated attribute52// FIXME: fix Synthetic attribute53// FIXME: per Serguei, add error return handling for ConstantPool::copy_cpool_bytes()545556// Write the field information portion of ClassFile structure57// JVMSpec| u2 fields_count;58// JVMSpec| field_info fields[fields_count];59void JvmtiClassFileReconstituter::write_field_infos() {60HandleMark hm(thread());61Array<AnnotationArray*>* fields_anno = ikh()->fields_annotations();62Array<AnnotationArray*>* fields_type_anno = ikh()->fields_type_annotations();6364// Compute the real number of Java fields65int java_fields = ikh()->java_fields_count();6667write_u2(java_fields);68for (JavaFieldStream fs(ikh()); !fs.done(); fs.next()) {69AccessFlags access_flags = fs.access_flags();70int name_index = fs.name_index();71int signature_index = fs.signature_index();72int initial_value_index = fs.initval_index();73guarantee(name_index != 0 && signature_index != 0, "bad constant pool index for field");74// int offset = ikh()->field_offset( index );75int generic_signature_index = fs.generic_signature_index();76AnnotationArray* anno = fields_anno == NULL ? NULL : fields_anno->at(fs.index());77AnnotationArray* type_anno = fields_type_anno == NULL ? NULL : fields_type_anno->at(fs.index());7879// JVMSpec| field_info {80// JVMSpec| u2 access_flags;81// JVMSpec| u2 name_index;82// JVMSpec| u2 descriptor_index;83// JVMSpec| u2 attributes_count;84// JVMSpec| attribute_info attributes[attributes_count];85// JVMSpec| }8687write_u2(access_flags.as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS);88write_u2(name_index);89write_u2(signature_index);90int attr_count = 0;91if (initial_value_index != 0) {92++attr_count;93}94if (access_flags.is_synthetic()) {95// ++attr_count;96}97if (generic_signature_index != 0) {98++attr_count;99}100if (anno != NULL) {101++attr_count; // has RuntimeVisibleAnnotations attribute102}103if (type_anno != NULL) {104++attr_count; // has RuntimeVisibleTypeAnnotations attribute105}106107write_u2(attr_count);108109if (initial_value_index != 0) {110write_attribute_name_index("ConstantValue");111write_u4(2); //length always 2112write_u2(initial_value_index);113}114if (access_flags.is_synthetic()) {115// write_synthetic_attribute();116}117if (generic_signature_index != 0) {118write_signature_attribute(generic_signature_index);119}120if (anno != NULL) {121write_annotations_attribute("RuntimeVisibleAnnotations", anno);122}123if (type_anno != NULL) {124write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);125}126}127}128129// Write Code attribute130// JVMSpec| Code_attribute {131// JVMSpec| u2 attribute_name_index;132// JVMSpec| u4 attribute_length;133// JVMSpec| u2 max_stack;134// JVMSpec| u2 max_locals;135// JVMSpec| u4 code_length;136// JVMSpec| u1 code[code_length];137// JVMSpec| u2 exception_table_length;138// JVMSpec| { u2 start_pc;139// JVMSpec| u2 end_pc;140// JVMSpec| u2 handler_pc;141// JVMSpec| u2 catch_type;142// JVMSpec| } exception_table[exception_table_length];143// JVMSpec| u2 attributes_count;144// JVMSpec| attribute_info attributes[attributes_count];145// JVMSpec| }146void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) {147ConstMethod* const_method = method->constMethod();148u2 line_num_cnt = 0;149int stackmap_len = 0;150int local_variable_table_length = 0;151int local_variable_type_table_length = 0;152153// compute number and length of attributes154int attr_count = 0;155int attr_size = 0;156if (const_method->has_linenumber_table()) {157line_num_cnt = line_number_table_entries(method);158if (line_num_cnt != 0) {159++attr_count;160// Compute the complete size of the line number table attribute:161// LineNumberTable_attribute {162// u2 attribute_name_index;163// u4 attribute_length;164// u2 line_number_table_length;165// { u2 start_pc;166// u2 line_number;167// } line_number_table[line_number_table_length];168// }169attr_size += 2 + 4 + 2 + line_num_cnt * (2 + 2);170}171}172if (method->has_stackmap_table()) {173stackmap_len = method->stackmap_data()->length();174if (stackmap_len != 0) {175++attr_count;176// Compute the size of the stack map table attribute (VM stores raw):177// StackMapTable_attribute {178// u2 attribute_name_index;179// u4 attribute_length;180// u2 number_of_entries;181// stack_map_frame_entries[number_of_entries];182// }183attr_size += 2 + 4 + stackmap_len;184}185}186if (method->has_localvariable_table()) {187local_variable_table_length = method->localvariable_table_length();188if (local_variable_table_length != 0) {189++attr_count;190// Compute the size of the local variable table attribute (VM stores raw):191// LocalVariableTable_attribute {192// u2 attribute_name_index;193// u4 attribute_length;194// u2 local_variable_table_length;195// {196// u2 start_pc;197// u2 length;198// u2 name_index;199// u2 descriptor_index;200// u2 index;201// }202attr_size += 2 + 4 + 2 + local_variable_table_length * (2 + 2 + 2 + 2 + 2);203204// Local variables with generic signatures must have LVTT entries205LocalVariableTableElement *elem = method->localvariable_table_start();206for (int idx = 0; idx < local_variable_table_length; idx++) {207if (elem[idx].signature_cp_index != 0) {208local_variable_type_table_length++;209}210}211212if (local_variable_type_table_length != 0) {213++attr_count;214// Compute the size of the local variable type table attribute (VM stores raw):215// LocalVariableTypeTable_attribute {216// u2 attribute_name_index;217// u4 attribute_length;218// u2 local_variable_type_table_length;219// {220// u2 start_pc;221// u2 length;222// u2 name_index;223// u2 signature_index;224// u2 index;225// }226attr_size += 2 + 4 + 2 + local_variable_type_table_length * (2 + 2 + 2 + 2 + 2);227}228}229}230231ExceptionTable exception_table(method());232int exception_table_length = exception_table.length();233int code_size = const_method->code_size();234int size =2352+2+4 + // max_stack, max_locals, code_length236code_size + // code2372 + // exception_table_length238(2+2+2+2) * exception_table_length + // exception_table2392 + // attributes_count240attr_size; // attributes241242write_attribute_name_index("Code");243write_u4(size);244write_u2(method->verifier_max_stack());245write_u2(method->max_locals());246write_u4(code_size);247copy_bytecodes(method, (unsigned char*)writeable_address(code_size));248write_u2(exception_table_length);249for (int index = 0; index < exception_table_length; index++) {250write_u2(exception_table.start_pc(index));251write_u2(exception_table.end_pc(index));252write_u2(exception_table.handler_pc(index));253write_u2(exception_table.catch_type_index(index));254}255write_u2(attr_count);256if (line_num_cnt != 0) {257write_line_number_table_attribute(method, line_num_cnt);258}259if (stackmap_len != 0) {260write_stackmap_table_attribute(method, stackmap_len);261}262if (local_variable_table_length != 0) {263write_local_variable_table_attribute(method, local_variable_table_length);264}265if (local_variable_type_table_length != 0) {266write_local_variable_type_table_attribute(method, local_variable_type_table_length);267}268}269270// Write Exceptions attribute271// JVMSpec| Exceptions_attribute {272// JVMSpec| u2 attribute_name_index;273// JVMSpec| u4 attribute_length;274// JVMSpec| u2 number_of_exceptions;275// JVMSpec| u2 exception_index_table[number_of_exceptions];276// JVMSpec| }277void JvmtiClassFileReconstituter::write_exceptions_attribute(ConstMethod* const_method) {278CheckedExceptionElement* checked_exceptions = const_method->checked_exceptions_start();279int checked_exceptions_length = const_method->checked_exceptions_length();280int size =2812 + // number_of_exceptions2822 * checked_exceptions_length; // exception_index_table283284write_attribute_name_index("Exceptions");285write_u4(size);286write_u2(checked_exceptions_length);287for (int index = 0; index < checked_exceptions_length; index++) {288write_u2(checked_exceptions[index].class_cp_index);289}290}291292// Write SourceFile attribute293// JVMSpec| SourceFile_attribute {294// JVMSpec| u2 attribute_name_index;295// JVMSpec| u4 attribute_length;296// JVMSpec| u2 sourcefile_index;297// JVMSpec| }298void JvmtiClassFileReconstituter::write_source_file_attribute() {299assert(ikh()->source_file_name() != NULL, "caller must check");300301write_attribute_name_index("SourceFile");302write_u4(2); // always length 2303write_u2(symbol_to_cpool_index(ikh()->source_file_name()));304}305306// Write SourceDebugExtension attribute307// JSR45| SourceDebugExtension_attribute {308// JSR45| u2 attribute_name_index;309// JSR45| u4 attribute_length;310// JSR45| u1 debug_extension[attribute_length];311// JSR45| }312void JvmtiClassFileReconstituter::write_source_debug_extension_attribute() {313assert(ikh()->source_debug_extension() != NULL, "caller must check");314315write_attribute_name_index("SourceDebugExtension");316int len = (int)strlen(ikh()->source_debug_extension());317write_u4(len);318u1* ext = (u1*)ikh()->source_debug_extension();319for (int i=0; i<len; i++) {320write_u1(ext[i]);321}322}323324// Write (generic) Signature attribute325// JVMSpec| Signature_attribute {326// JVMSpec| u2 attribute_name_index;327// JVMSpec| u4 attribute_length;328// JVMSpec| u2 signature_index;329// JVMSpec| }330void JvmtiClassFileReconstituter::write_signature_attribute(u2 generic_signature_index) {331write_attribute_name_index("Signature");332write_u4(2); // always length 2333write_u2(generic_signature_index);334}335336// Compute the number of entries in the InnerClasses attribute337u2 JvmtiClassFileReconstituter::inner_classes_attribute_length() {338InnerClassesIterator iter(ikh());339return iter.length();340}341342// Write an annotation attribute. The VM stores them in raw form, so all we need343// to do is add the attrubute name and fill in the length.344// JSR202| *Annotations_attribute {345// JSR202| u2 attribute_name_index;346// JSR202| u4 attribute_length;347// JSR202| ...348// JSR202| }349void JvmtiClassFileReconstituter::write_annotations_attribute(const char* attr_name,350AnnotationArray* annos) {351u4 length = annos->length();352write_attribute_name_index(attr_name);353write_u4(length);354memcpy(writeable_address(length), annos->adr_at(0), length);355}356357// BootstrapMethods_attribute {358// u2 attribute_name_index;359// u4 attribute_length;360// u2 num_bootstrap_methods;361// { u2 bootstrap_method_ref;362// u2 num_bootstrap_arguments;363// u2 bootstrap_arguments[num_bootstrap_arguments];364// } bootstrap_methods[num_bootstrap_methods];365// }366void JvmtiClassFileReconstituter::write_bootstrapmethod_attribute() {367Array<u2>* operands = cpool()->operands();368write_attribute_name_index("BootstrapMethods");369int num_bootstrap_methods = ConstantPool::operand_array_length(operands);370371// calculate length of attribute372int length = sizeof(u2); // num_bootstrap_methods373for (int n = 0; n < num_bootstrap_methods; n++) {374u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n);375length += sizeof(u2); // bootstrap_method_ref376length += sizeof(u2); // num_bootstrap_arguments377length += sizeof(u2) * num_bootstrap_arguments; // bootstrap_arguments[num_bootstrap_arguments]378}379write_u4(length);380381// write attribute382write_u2(num_bootstrap_methods);383for (int n = 0; n < num_bootstrap_methods; n++) {384u2 bootstrap_method_ref = cpool()->operand_bootstrap_method_ref_index_at(n);385u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n);386write_u2(bootstrap_method_ref);387write_u2(num_bootstrap_arguments);388for (int arg = 0; arg < num_bootstrap_arguments; arg++) {389u2 bootstrap_argument = cpool()->operand_argument_index_at(n, arg);390write_u2(bootstrap_argument);391}392}393}394395396// Write InnerClasses attribute397// JVMSpec| InnerClasses_attribute {398// JVMSpec| u2 attribute_name_index;399// JVMSpec| u4 attribute_length;400// JVMSpec| u2 number_of_classes;401// JVMSpec| { u2 inner_class_info_index;402// JVMSpec| u2 outer_class_info_index;403// JVMSpec| u2 inner_name_index;404// JVMSpec| u2 inner_class_access_flags;405// JVMSpec| } classes[number_of_classes];406// JVMSpec| }407void JvmtiClassFileReconstituter::write_inner_classes_attribute(int length) {408InnerClassesIterator iter(ikh());409guarantee(iter.length() != 0 && iter.length() == length,410"caller must check");411u2 entry_count = length / InstanceKlass::inner_class_next_offset;412u4 size = 2 + entry_count * (2+2+2+2);413414write_attribute_name_index("InnerClasses");415write_u4(size);416write_u2(entry_count);417for (; !iter.done(); iter.next()) {418write_u2(iter.inner_class_info_index());419write_u2(iter.outer_class_info_index());420write_u2(iter.inner_name_index());421write_u2(iter.inner_access_flags());422}423}424425// Write Synthetic attribute426// JVMSpec| Synthetic_attribute {427// JVMSpec| u2 attribute_name_index;428// JVMSpec| u4 attribute_length;429// JVMSpec| }430void JvmtiClassFileReconstituter::write_synthetic_attribute() {431write_attribute_name_index("Synthetic");432write_u4(0); //length always zero433}434435// Compute size of LineNumberTable436u2 JvmtiClassFileReconstituter::line_number_table_entries(methodHandle method) {437// The line number table is compressed so we don't know how big it is until decompressed.438// Decompression is really fast so we just do it twice.439u2 num_entries = 0;440CompressedLineNumberReadStream stream(method->compressed_linenumber_table());441while (stream.read_pair()) {442num_entries++;443}444return num_entries;445}446447// Write LineNumberTable attribute448// JVMSpec| LineNumberTable_attribute {449// JVMSpec| u2 attribute_name_index;450// JVMSpec| u4 attribute_length;451// JVMSpec| u2 line_number_table_length;452// JVMSpec| { u2 start_pc;453// JVMSpec| u2 line_number;454// JVMSpec| } line_number_table[line_number_table_length];455// JVMSpec| }456void JvmtiClassFileReconstituter::write_line_number_table_attribute(methodHandle method,457u2 num_entries) {458459write_attribute_name_index("LineNumberTable");460write_u4(2 + num_entries * (2 + 2));461write_u2(num_entries);462463CompressedLineNumberReadStream stream(method->compressed_linenumber_table());464while (stream.read_pair()) {465write_u2(stream.bci());466write_u2(stream.line());467}468}469470// Write LocalVariableTable attribute471// JVMSpec| LocalVariableTable_attribute {472// JVMSpec| u2 attribute_name_index;473// JVMSpec| u4 attribute_length;474// JVMSpec| u2 local_variable_table_length;475// JVMSpec| { u2 start_pc;476// JVMSpec| u2 length;477// JVMSpec| u2 name_index;478// JVMSpec| u2 descriptor_index;479// JVMSpec| u2 index;480// JVMSpec| } local_variable_table[local_variable_table_length];481// JVMSpec| }482void JvmtiClassFileReconstituter::write_local_variable_table_attribute(methodHandle method, u2 num_entries) {483write_attribute_name_index("LocalVariableTable");484write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2));485write_u2(num_entries);486487assert(method->localvariable_table_length() == num_entries, "just checking");488489LocalVariableTableElement *elem = method->localvariable_table_start();490for (int j=0; j<method->localvariable_table_length(); j++) {491write_u2(elem->start_bci);492write_u2(elem->length);493write_u2(elem->name_cp_index);494write_u2(elem->descriptor_cp_index);495write_u2(elem->slot);496elem++;497}498}499500// Write LocalVariableTypeTable attribute501// JVMSpec| LocalVariableTypeTable_attribute {502// JVMSpec| u2 attribute_name_index;503// JVMSpec| u4 attribute_length;504// JVMSpec| u2 local_variable_type_table_length;505// JVMSpec| { u2 start_pc;506// JVMSpec| u2 length;507// JVMSpec| u2 name_index;508// JVMSpec| u2 signature_index;509// JVMSpec| u2 index;510// JVMSpec| } local_variable_type_table[local_variable_type_table_length];511// JVMSpec| }512void JvmtiClassFileReconstituter::write_local_variable_type_table_attribute(methodHandle method, u2 num_entries) {513write_attribute_name_index("LocalVariableTypeTable");514write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2));515write_u2(num_entries);516517LocalVariableTableElement *elem = method->localvariable_table_start();518for (int j=0; j<method->localvariable_table_length(); j++) {519if (elem->signature_cp_index > 0) {520// Local variable has a generic signature - write LVTT attribute entry521write_u2(elem->start_bci);522write_u2(elem->length);523write_u2(elem->name_cp_index);524write_u2(elem->signature_cp_index);525write_u2(elem->slot);526num_entries--;527}528elem++;529}530assert(num_entries == 0, "just checking");531}532533// Write stack map table attribute534// JSR-202| StackMapTable_attribute {535// JSR-202| u2 attribute_name_index;536// JSR-202| u4 attribute_length;537// JSR-202| u2 number_of_entries;538// JSR-202| stack_map_frame_entries[number_of_entries];539// JSR-202| }540void JvmtiClassFileReconstituter::write_stackmap_table_attribute(methodHandle method,541int stackmap_len) {542543write_attribute_name_index("StackMapTable");544write_u4(stackmap_len);545memcpy(546writeable_address(stackmap_len),547(void*)(method->stackmap_data()->adr_at(0)),548stackmap_len);549}550551// Write one method_info structure552// JVMSpec| method_info {553// JVMSpec| u2 access_flags;554// JVMSpec| u2 name_index;555// JVMSpec| u2 descriptor_index;556// JVMSpec| u2 attributes_count;557// JVMSpec| attribute_info attributes[attributes_count];558// JVMSpec| }559void JvmtiClassFileReconstituter::write_method_info(methodHandle method) {560AccessFlags access_flags = method->access_flags();561ConstMethod* const_method = method->constMethod();562u2 generic_signature_index = const_method->generic_signature_index();563AnnotationArray* anno = method->annotations();564AnnotationArray* param_anno = method->parameter_annotations();565AnnotationArray* default_anno = method->annotation_default();566AnnotationArray* type_anno = method->type_annotations();567568// skip generated default interface methods569if (method->is_overpass()) {570return;571}572573write_u2(access_flags.get_flags() & JVM_RECOGNIZED_METHOD_MODIFIERS);574write_u2(const_method->name_index());575write_u2(const_method->signature_index());576577// write attributes in the same order javac does, so we can test with byte for578// byte comparison579int attr_count = 0;580if (const_method->code_size() != 0) {581++attr_count; // has Code attribute582}583if (const_method->has_checked_exceptions()) {584++attr_count; // has Exceptions attribute585}586if (default_anno != NULL) {587++attr_count; // has AnnotationDefault attribute588}589// Deprecated attribute would go here590if (access_flags.is_synthetic()) { // FIXME591// ++attr_count;592}593if (generic_signature_index != 0) {594++attr_count;595}596if (anno != NULL) {597++attr_count; // has RuntimeVisibleAnnotations attribute598}599if (param_anno != NULL) {600++attr_count; // has RuntimeVisibleParameterAnnotations attribute601}602if (type_anno != NULL) {603++attr_count; // has RuntimeVisibleTypeAnnotations attribute604}605606write_u2(attr_count);607if (const_method->code_size() > 0) {608write_code_attribute(method);609}610if (const_method->has_checked_exceptions()) {611write_exceptions_attribute(const_method);612}613if (default_anno != NULL) {614write_annotations_attribute("AnnotationDefault", default_anno);615}616// Deprecated attribute would go here617if (access_flags.is_synthetic()) {618// write_synthetic_attribute();619}620if (generic_signature_index != 0) {621write_signature_attribute(generic_signature_index);622}623if (anno != NULL) {624write_annotations_attribute("RuntimeVisibleAnnotations", anno);625}626if (param_anno != NULL) {627write_annotations_attribute("RuntimeVisibleParameterAnnotations", param_anno);628}629if (type_anno != NULL) {630write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);631}632}633634// Write the class attributes portion of ClassFile structure635// JVMSpec| u2 attributes_count;636// JVMSpec| attribute_info attributes[attributes_count];637void JvmtiClassFileReconstituter::write_class_attributes() {638u2 inner_classes_length = inner_classes_attribute_length();639Symbol* generic_signature = ikh()->generic_signature();640AnnotationArray* anno = ikh()->class_annotations();641AnnotationArray* type_anno = ikh()->class_type_annotations();642643int attr_count = 0;644if (generic_signature != NULL) {645++attr_count;646}647if (ikh()->source_file_name() != NULL) {648++attr_count;649}650if (ikh()->source_debug_extension() != NULL) {651++attr_count;652}653if (inner_classes_length > 0) {654++attr_count;655}656if (anno != NULL) {657++attr_count; // has RuntimeVisibleAnnotations attribute658}659if (type_anno != NULL) {660++attr_count; // has RuntimeVisibleTypeAnnotations attribute661}662if (cpool()->operands() != NULL) {663++attr_count;664}665666write_u2(attr_count);667668if (generic_signature != NULL) {669write_signature_attribute(symbol_to_cpool_index(generic_signature));670}671if (ikh()->source_file_name() != NULL) {672write_source_file_attribute();673}674if (ikh()->source_debug_extension() != NULL) {675write_source_debug_extension_attribute();676}677if (inner_classes_length > 0) {678write_inner_classes_attribute(inner_classes_length);679}680if (anno != NULL) {681write_annotations_attribute("RuntimeVisibleAnnotations", anno);682}683if (type_anno != NULL) {684write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);685}686if (cpool()->operands() != NULL) {687write_bootstrapmethod_attribute();688}689}690691// Write the method information portion of ClassFile structure692// JVMSpec| u2 methods_count;693// JVMSpec| method_info methods[methods_count];694void JvmtiClassFileReconstituter::write_method_infos() {695HandleMark hm(thread());696Array<Method*>* methods = ikh()->methods();697int num_methods = methods->length();698int num_overpass = 0;699700// count the generated default interface methods701// these will not be re-created by write_method_info702// and should not be included in the total count703for (int index = 0; index < num_methods; index++) {704Method* method = methods->at(index);705if (method->is_overpass()) {706num_overpass++;707}708}709710write_u2(num_methods - num_overpass);711if (JvmtiExport::can_maintain_original_method_order()) {712int index;713int original_index;714intArray method_order(num_methods, 0);715716// invert the method order mapping717for (index = 0; index < num_methods; index++) {718original_index = ikh()->method_ordering()->at(index);719assert(original_index >= 0 && original_index < num_methods,720"invalid original method index");721method_order.at_put(original_index, index);722}723724// write in original order725for (original_index = 0; original_index < num_methods; original_index++) {726index = method_order.at(original_index);727methodHandle method(thread(), methods->at(index));728write_method_info(method);729}730} else {731// method order not preserved just dump the method infos732for (int index = 0; index < num_methods; index++) {733methodHandle method(thread(), methods->at(index));734write_method_info(method);735}736}737}738739void JvmtiClassFileReconstituter::write_class_file_format() {740ReallocMark();741742// JVMSpec| ClassFile {743// JVMSpec| u4 magic;744write_u4(0xCAFEBABE);745746// JVMSpec| u2 minor_version;747// JVMSpec| u2 major_version;748write_u2(ikh()->minor_version());749u2 major = ikh()->major_version();750write_u2(major);751752// JVMSpec| u2 constant_pool_count;753// JVMSpec| cp_info constant_pool[constant_pool_count-1];754write_u2(cpool()->length());755copy_cpool_bytes(writeable_address(cpool_size()));756757// JVMSpec| u2 access_flags;758write_u2(ikh()->access_flags().get_flags() & JVM_RECOGNIZED_CLASS_MODIFIERS);759760// JVMSpec| u2 this_class;761// JVMSpec| u2 super_class;762write_u2(class_symbol_to_cpool_index(ikh()->name()));763Klass* super_class = ikh()->super();764write_u2(super_class == NULL? 0 : // zero for java.lang.Object765class_symbol_to_cpool_index(super_class->name()));766767// JVMSpec| u2 interfaces_count;768// JVMSpec| u2 interfaces[interfaces_count];769Array<Klass*>* interfaces = ikh()->local_interfaces();770int num_interfaces = interfaces->length();771write_u2(num_interfaces);772for (int index = 0; index < num_interfaces; index++) {773HandleMark hm(thread());774instanceKlassHandle iikh(thread(), interfaces->at(index));775write_u2(class_symbol_to_cpool_index(iikh->name()));776}777778// JVMSpec| u2 fields_count;779// JVMSpec| field_info fields[fields_count];780write_field_infos();781782// JVMSpec| u2 methods_count;783// JVMSpec| method_info methods[methods_count];784write_method_infos();785786// JVMSpec| u2 attributes_count;787// JVMSpec| attribute_info attributes[attributes_count];788// JVMSpec| } /* end ClassFile 8?789write_class_attributes();790}791792address JvmtiClassFileReconstituter::writeable_address(size_t size) {793size_t used_size = _buffer_ptr - _buffer;794if (size + used_size >= _buffer_size) {795// compute the new buffer size: must be at least twice as big as before796// plus whatever new is being used; then convert to nice clean block boundary797size_t new_buffer_size = (size + _buffer_size*2 + 1) / initial_buffer_size798* initial_buffer_size;799800// VM goes belly-up if the memory isn't available, so cannot do OOM processing801_buffer = REALLOC_RESOURCE_ARRAY(u1, _buffer, _buffer_size, new_buffer_size);802_buffer_size = new_buffer_size;803_buffer_ptr = _buffer + used_size;804}805u1* ret_ptr = _buffer_ptr;806_buffer_ptr += size;807return ret_ptr;808}809810void JvmtiClassFileReconstituter::write_attribute_name_index(const char* name) {811TempNewSymbol sym = SymbolTable::probe(name, (int)strlen(name));812assert(sym != NULL, "attribute name symbol not found");813u2 attr_name_index = symbol_to_cpool_index(sym);814assert(attr_name_index != 0, "attribute name symbol not in constant pool");815write_u2(attr_name_index);816}817818void JvmtiClassFileReconstituter::write_u1(u1 x) {819*writeable_address(1) = x;820}821822void JvmtiClassFileReconstituter::write_u2(u2 x) {823Bytes::put_Java_u2(writeable_address(2), x);824}825826void JvmtiClassFileReconstituter::write_u4(u4 x) {827Bytes::put_Java_u4(writeable_address(4), x);828}829830void JvmtiClassFileReconstituter::write_u8(u8 x) {831Bytes::put_Java_u8(writeable_address(8), x);832}833834void JvmtiClassFileReconstituter::copy_bytecodes(methodHandle mh,835unsigned char* bytecodes) {836// use a BytecodeStream to iterate over the bytecodes. JVM/fast bytecodes837// and the breakpoint bytecode are converted to their original bytecodes.838839BytecodeStream bs(mh);840841unsigned char* p = bytecodes;842Bytecodes::Code code;843bool is_rewritten = mh->method_holder()->is_rewritten();844845while ((code = bs.next()) >= 0) {846assert(Bytecodes::is_java_code(code), "sanity check");847assert(code != Bytecodes::_breakpoint, "sanity check");848849// length of bytecode (mnemonic + operands)850address bcp = bs.bcp();851int len = bs.instruction_size();852assert(len > 0, "length must be > 0");853854// copy the bytecodes855*p = (unsigned char) (bs.is_wide()? Bytecodes::_wide : code);856if (len > 1) {857memcpy(p+1, bcp+1, len-1);858}859860// During linking the get/put and invoke instructions are rewritten861// with an index into the constant pool cache. The original constant862// pool index must be returned to caller. Rewrite the index.863if (is_rewritten && len > 1) {864bool is_wide = false;865switch (code) {866case Bytecodes::_getstatic : // fall through867case Bytecodes::_putstatic : // fall through868case Bytecodes::_getfield : // fall through869case Bytecodes::_putfield : // fall through870case Bytecodes::_invokevirtual : // fall through871case Bytecodes::_invokespecial : // fall through872case Bytecodes::_invokestatic : // fall through873case Bytecodes::_invokedynamic : // fall through874case Bytecodes::_invokeinterface : {875assert(len == 3 ||876(code == Bytecodes::_invokeinterface && len == 5) ||877(code == Bytecodes::_invokedynamic && len == 5),878"sanity check");879880int cpci = Bytes::get_native_u2(bcp+1);881bool is_invokedynamic = (EnableInvokeDynamic && code == Bytecodes::_invokedynamic);882ConstantPoolCacheEntry* entry;883if (is_invokedynamic) {884cpci = Bytes::get_native_u4(bcp+1);885entry = mh->constants()->invokedynamic_cp_cache_entry_at(cpci);886} else {887// cache cannot be pre-fetched since some classes won't have it yet888entry = mh->constants()->cache()->entry_at(cpci);889}890int i = entry->constant_pool_index();891assert(i < mh->constants()->length(), "sanity check");892Bytes::put_Java_u2((address)(p+1), (u2)i); // java byte ordering893if (is_invokedynamic) *(p+3) = *(p+4) = 0;894break;895}896case Bytecodes::_ldc_w:897is_wide = true; // fall through898case Bytecodes::_ldc: {899if (bs.raw_code() == Bytecodes::_fast_aldc || bs.raw_code() == Bytecodes::_fast_aldc_w) {900int cpci = is_wide ? Bytes::get_native_u2(bcp+1) : (u1)(*(bcp+1));901int i = mh->constants()->object_to_cp_index(cpci);902assert(i < mh->constants()->length(), "sanity check");903if (is_wide) {904Bytes::put_Java_u2((address)(p+1), (u2)i); // java byte ordering905} else {906*(p+1) = (u1)i;907}908}909break;910}911}912}913914p += len;915}916}917918919