duke@435: /* mikael@6198: * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: stefank@2314: #ifndef SHARE_VM_PRIMS_JVMTICLASSFILERECONSTITUTER_HPP stefank@2314: #define SHARE_VM_PRIMS_JVMTICLASSFILERECONSTITUTER_HPP stefank@2314: stefank@2314: #include "jvmtifiles/jvmtiEnv.hpp" stefank@2314: duke@435: duke@435: class JvmtiConstantPoolReconstituter : public StackObj { duke@435: private: duke@435: int _cpool_size; duke@435: SymbolHashMap* _symmap; duke@435: SymbolHashMap* _classmap; duke@435: constantPoolHandle _cpool; duke@435: instanceKlassHandle _ikh; duke@435: jvmtiError _err; duke@435: duke@435: protected: duke@435: instanceKlassHandle ikh() { return _ikh; }; duke@435: constantPoolHandle cpool() { return _cpool; }; duke@435: coleenp@2497: u2 symbol_to_cpool_index(Symbol* sym) { duke@435: return _symmap->symbol_to_value(sym); duke@435: } duke@435: coleenp@2497: u2 class_symbol_to_cpool_index(Symbol* sym) { duke@435: return _classmap->symbol_to_value(sym); duke@435: } duke@435: duke@435: public: duke@435: // Calls to this constructor must be proceeded by a ResourceMark duke@435: // and a HandleMark duke@435: JvmtiConstantPoolReconstituter(instanceKlassHandle ikh){ duke@435: set_error(JVMTI_ERROR_NONE); duke@435: _ikh = ikh; duke@435: _cpool = constantPoolHandle(Thread::current(), ikh->constants()); duke@435: _symmap = new SymbolHashMap(); duke@435: _classmap = new SymbolHashMap(); duke@435: _cpool_size = _cpool->hash_entries_to(_symmap, _classmap); duke@435: if (_cpool_size == 0) { duke@435: set_error(JVMTI_ERROR_OUT_OF_MEMORY); duke@435: } else if (_cpool_size < 0) { duke@435: set_error(JVMTI_ERROR_INTERNAL); duke@435: } duke@435: } duke@435: duke@435: ~JvmtiConstantPoolReconstituter() { duke@435: if (_symmap != NULL) { zgu@3900: os::free(_symmap, mtClass); duke@435: _symmap = NULL; duke@435: } duke@435: if (_classmap != NULL) { zgu@3900: os::free(_classmap, mtClass); duke@435: _classmap = NULL; duke@435: } duke@435: } duke@435: duke@435: duke@435: void set_error(jvmtiError err) { _err = err; } duke@435: jvmtiError get_error() { return _err; } duke@435: duke@435: int cpool_size() { return _cpool_size; } duke@435: duke@435: void copy_cpool_bytes(unsigned char *cpool_bytes) { duke@435: if (cpool_bytes == NULL) { duke@435: assert(cpool_bytes != NULL, "cpool_bytes pointer must not be NULL"); duke@435: return; duke@435: } duke@435: cpool()->copy_cpool_bytes(cpool_size(), _symmap, cpool_bytes); duke@435: } duke@435: }; duke@435: duke@435: duke@435: class JvmtiClassFileReconstituter : public JvmtiConstantPoolReconstituter { duke@435: private: duke@435: size_t _buffer_size; duke@435: u1* _buffer; duke@435: u1* _buffer_ptr; duke@435: Thread* _thread; duke@435: duke@435: enum { duke@435: // initial size should be power of two duke@435: initial_buffer_size = 1024 duke@435: }; duke@435: duke@435: inline Thread* thread() { return _thread; } duke@435: duke@435: void write_class_file_format(); duke@435: void write_field_infos(); duke@435: void write_method_infos(); duke@435: void write_method_info(methodHandle method); duke@435: void write_code_attribute(methodHandle method); coleenp@4037: void write_exceptions_attribute(ConstMethod* const_method); duke@435: void write_synthetic_attribute(); duke@435: void write_class_attributes(); duke@435: void write_source_file_attribute(); duke@435: void write_source_debug_extension_attribute(); duke@435: u2 line_number_table_entries(methodHandle method); duke@435: void write_line_number_table_attribute(methodHandle method, u2 num_entries); coleenp@3345: void write_local_variable_table_attribute(methodHandle method, u2 num_entries); minqi@4083: void write_local_variable_type_table_attribute(methodHandle method, u2 num_entries); duke@435: void write_stackmap_table_attribute(methodHandle method, int stackmap_table_len); duke@435: u2 inner_classes_attribute_length(); duke@435: void write_inner_classes_attribute(int length); duke@435: void write_signature_attribute(u2 generic_signaure_index); duke@435: void write_attribute_name_index(const char* name); coleenp@4037: void write_annotations_attribute(const char* attr_name, AnnotationArray* annos); sla@5060: void write_bootstrapmethod_attribute(); duke@435: duke@435: address writeable_address(size_t size); duke@435: void write_u1(u1 x); duke@435: void write_u2(u2 x); duke@435: void write_u4(u4 x); duke@435: void write_u8(u8 x); duke@435: duke@435: public: duke@435: // Calls to this constructor must be proceeded by a ResourceMark duke@435: // and a HandleMark duke@435: JvmtiClassFileReconstituter(instanceKlassHandle ikh) : duke@435: JvmtiConstantPoolReconstituter(ikh) { duke@435: _buffer_size = initial_buffer_size; duke@435: _buffer = _buffer_ptr = NEW_RESOURCE_ARRAY(u1, _buffer_size); duke@435: _thread = Thread::current(); duke@435: write_class_file_format(); duke@435: }; duke@435: duke@435: size_t class_file_size() { return _buffer_ptr - _buffer; } duke@435: duke@435: u1* class_file_bytes() { return _buffer; } duke@435: duke@435: static void copy_bytecodes(methodHandle method, unsigned char* bytecodes); duke@435: }; stefank@2314: stefank@2314: #endif // SHARE_VM_PRIMS_JVMTICLASSFILERECONSTITUTER_HPP