jvmtiClassFileReconstituter.hpp revision 9248:6ab7e19c9220
150276Speter/* 2174993Srafan * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. 350276Speter * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 450276Speter * 550276Speter * This code is free software; you can redistribute it and/or modify it 650276Speter * under the terms of the GNU General Public License version 2 only, as 750276Speter * published by the Free Software Foundation. 850276Speter * 950276Speter * This code is distributed in the hope that it will be useful, but WITHOUT 1050276Speter * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1150276Speter * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1250276Speter * version 2 for more details (a copy is included in the LICENSE file that 1350276Speter * accompanied this code). 1450276Speter * 1550276Speter * You should have received a copy of the GNU General Public License version 1650276Speter * 2 along with this work; if not, write to the Free Software Foundation, 1750276Speter * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1850276Speter * 1950276Speter * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2050276Speter * or visit www.oracle.com if you need additional information or have any 2150276Speter * questions. 2250276Speter * 2350276Speter */ 2450276Speter 2550276Speter#ifndef SHARE_VM_PRIMS_JVMTICLASSFILERECONSTITUTER_HPP 2650276Speter#define SHARE_VM_PRIMS_JVMTICLASSFILERECONSTITUTER_HPP 2750276Speter 2850276Speter#include "jvmtifiles/jvmtiEnv.hpp" 2950276Speter 3050276Speter 3150276Speterclass JvmtiConstantPoolReconstituter : public StackObj { 3250276Speter private: 3350276Speter int _cpool_size; 3450276Speter SymbolHashMap* _symmap; 3550276Speter SymbolHashMap* _classmap; 3650276Speter constantPoolHandle _cpool; 3750276Speter instanceKlassHandle _ikh; 3850276Speter jvmtiError _err; 3950276Speter 4050276Speter protected: 4150276Speter instanceKlassHandle ikh() { return _ikh; }; 42174993Srafan constantPoolHandle cpool() { return _cpool; }; 4350276Speter 4476726Speter u2 symbol_to_cpool_index(Symbol* sym) { 4576726Speter return _symmap->symbol_to_value(sym); 4650276Speter } 4776726Speter 4876726Speter u2 class_symbol_to_cpool_index(Symbol* sym) { 49174993Srafan return _classmap->symbol_to_value(sym); 5050276Speter } 5176726Speter 5250276Speter public: 53174993Srafan // Calls to this constructor must be proceeded by a ResourceMark 54174993Srafan // and a HandleMark 55174993Srafan JvmtiConstantPoolReconstituter(instanceKlassHandle ikh){ 5676726Speter set_error(JVMTI_ERROR_NONE); 5776726Speter _ikh = ikh; 5850276Speter _cpool = constantPoolHandle(Thread::current(), ikh->constants()); 5976726Speter _symmap = new SymbolHashMap(); 6076726Speter _classmap = new SymbolHashMap(); 6150276Speter _cpool_size = _cpool->hash_entries_to(_symmap, _classmap); 62166124Srafan if (_cpool_size == 0) { 63166124Srafan set_error(JVMTI_ERROR_OUT_OF_MEMORY); 64166124Srafan } else if (_cpool_size < 0) { 6576726Speter set_error(JVMTI_ERROR_INTERNAL); 6697049Speter } 6797049Speter } 6876726Speter 6976726Speter ~JvmtiConstantPoolReconstituter() { 7050276Speter if (_symmap != NULL) { 71174993Srafan delete _symmap; 7297049Speter _symmap = NULL; 7397049Speter } 7497049Speter if (_classmap != NULL) { 7597049Speter delete _classmap; 7676726Speter _classmap = NULL; 77166124Srafan } 78166124Srafan } 79166124Srafan 80166124Srafan 8176726Speter void set_error(jvmtiError err) { _err = err; } 8250276Speter jvmtiError get_error() { return _err; } 8376726Speter 8450276Speter int cpool_size() { return _cpool_size; } 85 86 void copy_cpool_bytes(unsigned char *cpool_bytes) { 87 if (cpool_bytes == NULL) { 88 assert(cpool_bytes != NULL, "cpool_bytes pointer must not be NULL"); 89 return; 90 } 91 cpool()->copy_cpool_bytes(cpool_size(), _symmap, cpool_bytes); 92 } 93}; 94 95 96class JvmtiClassFileReconstituter : public JvmtiConstantPoolReconstituter { 97 private: 98 size_t _buffer_size; 99 u1* _buffer; 100 u1* _buffer_ptr; 101 Thread* _thread; 102 103 enum { 104 // initial size should be power of two 105 initial_buffer_size = 1024 106 }; 107 108 inline Thread* thread() { return _thread; } 109 110 void write_class_file_format(); 111 void write_field_infos(); 112 void write_method_infos(); 113 void write_method_info(const methodHandle& method); 114 void write_code_attribute(const methodHandle& method); 115 void write_exceptions_attribute(ConstMethod* const_method); 116 void write_synthetic_attribute(); 117 void write_class_attributes(); 118 void write_source_file_attribute(); 119 void write_source_debug_extension_attribute(); 120 u2 line_number_table_entries(const methodHandle& method); 121 void write_line_number_table_attribute(const methodHandle& method, u2 num_entries); 122 void write_local_variable_table_attribute(const methodHandle& method, u2 num_entries); 123 void write_local_variable_type_table_attribute(const methodHandle& method, u2 num_entries); 124 void write_stackmap_table_attribute(const methodHandle& method, int stackmap_table_len); 125 u2 inner_classes_attribute_length(); 126 void write_inner_classes_attribute(int length); 127 void write_signature_attribute(u2 generic_signaure_index); 128 void write_attribute_name_index(const char* name); 129 void write_annotations_attribute(const char* attr_name, AnnotationArray* annos); 130 void write_bootstrapmethod_attribute(); 131 132 address writeable_address(size_t size); 133 void write_u1(u1 x); 134 void write_u2(u2 x); 135 void write_u4(u4 x); 136 void write_u8(u8 x); 137 138 public: 139 // Calls to this constructor must be proceeded by a ResourceMark 140 // and a HandleMark 141 JvmtiClassFileReconstituter(instanceKlassHandle ikh) : 142 JvmtiConstantPoolReconstituter(ikh) { 143 _buffer_size = initial_buffer_size; 144 _buffer = _buffer_ptr = NEW_RESOURCE_ARRAY(u1, _buffer_size); 145 _thread = Thread::current(); 146 write_class_file_format(); 147 }; 148 149 size_t class_file_size() { return _buffer_ptr - _buffer; } 150 151 u1* class_file_bytes() { return _buffer; } 152 153 static void copy_bytecodes(const methodHandle& method, unsigned char* bytecodes); 154}; 155 156#endif // SHARE_VM_PRIMS_JVMTICLASSFILERECONSTITUTER_HPP 157