// BootstrapMethods_attribute { // u2 attribute_name_index; // u4 attribute_length; // u2 num_bootstrap_methods; // { u2 bootstrap_method_ref; // u2 num_bootstrap_arguments; // u2 bootstrap_arguments[num_bootstrap_arguments]; // } bootstrap_methods[num_bootstrap_methods]; // } void JvmtiClassFileReconstituter::write_bootstrapmethod_attribute() { Array<u2>* operands = cpool()->operands(); write_attribute_name_index("BootstrapMethods"); int num_bootstrap_methods = ConstantPool::operand_array_length(operands); // calculate length of attribute int length = sizeof(u2); // num_bootstrap_methods for (int n = 0; n < num_bootstrap_methods; n++) { u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n); length += sizeof(u2); // bootstrap_method_ref length += sizeof(u2); // num_bootstrap_arguments length += sizeof(u2) * num_bootstrap_arguments; // bootstrap_arguments[num_bootstrap_arguments] } write_u4(length); // write attribute write_u2(num_bootstrap_methods); for (int n = 0; n < num_bootstrap_methods; n++) { u2 bootstrap_method_ref = cpool()->operand_bootstrap_method_ref_index_at(n); u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n); write_u2(bootstrap_method_ref); write_u2(num_bootstrap_arguments); for (int arg = 0; arg < num_bootstrap_arguments; arg++) { u2 bootstrap_argument = cpool()->operand_argument_index_at(n, arg); write_u2(bootstrap_argument); } } }
// Write the class attributes portion of ClassFile structure // JVMSpec| u2 attributes_count; // JVMSpec| attribute_info attributes[attributes_count]; void JvmtiClassFileReconstituter::write_class_attributes() { u2 inner_classes_length = inner_classes_attribute_length(); Symbol* generic_signature = ikh()->generic_signature(); AnnotationArray* anno = ikh()->class_annotations(); AnnotationArray* type_anno = ikh()->class_type_annotations(); int attr_count = 0; if (generic_signature != NULL) { ++attr_count; } if (ikh()->source_file_name() != NULL) { ++attr_count; } if (ikh()->source_debug_extension() != NULL) { ++attr_count; } if (inner_classes_length > 0) { ++attr_count; } if (anno != NULL) { ++attr_count; // has RuntimeVisibleAnnotations attribute } if (type_anno != NULL) { ++attr_count; // has RuntimeVisibleTypeAnnotations attribute } if (cpool()->operands() != NULL) { ++attr_count; } write_u2(attr_count); if (generic_signature != NULL) { write_signature_attribute(symbol_to_cpool_index(generic_signature)); } if (ikh()->source_file_name() != NULL) { write_source_file_attribute(); } if (ikh()->source_debug_extension() != NULL) { write_source_debug_extension_attribute(); } if (inner_classes_length > 0) { write_inner_classes_attribute(inner_classes_length); } if (anno != NULL) { write_annotations_attribute("RuntimeVisibleAnnotations", anno); } if (type_anno != NULL) { write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno); } if (cpool()->operands() != NULL) { write_bootstrapmethod_attribute(); } }
void copy_cpool_bytes(unsigned char *cpool_bytes) { if (cpool_bytes == NULL) { assert(cpool_bytes != NULL, "cpool_bytes pointer must not be NULL"); return; } cpool()->copy_cpool_bytes(cpool_size(), _symmap, cpool_bytes); }
// ------------------------------------------------------------------ // ciBytecodeStream::get_declared_field_holder // // Get the declared holder of the currently referenced field. // // Usage note: the holder() of a ciField class returns the canonical // holder of the field, rather than the holder declared in the // bytecodes. // // There is no "will_link" result passed back. The user is responsible // for checking linkability when retrieving the associated field. ciInstanceKlass* ciBytecodeStream::get_declared_field_holder() { VM_ENTRY_MARK; constantPoolHandle cpool(_method->get_methodOop()->constants()); int holder_index = get_field_holder_index(); bool ignore; return CURRENT_ENV->get_klass_by_index(cpool, holder_index, ignore, _holder) ->as_instance_klass(); }
// ------------------------------------------------------------------ // ciBytecodeStream::get_constant // // If this bytecode is one of the ldc variants, get the referenced // constant. ciConstant ciBytecodeStream::get_constant() { int pool_index = get_constant_raw_index(); int cache_index = -1; if (has_cache_index()) { cache_index = pool_index; pool_index = -1; } VM_ENTRY_MARK; constantPoolHandle cpool(_method->get_methodOop()->constants()); return CURRENT_ENV->get_constant_by_index(cpool, pool_index, cache_index, _holder); }
void JvmtiClassFileReconstituter::write_class_file_format() { ReallocMark(); // JVMSpec| ClassFile { // JVMSpec| u4 magic; write_u4(0xCAFEBABE); // JVMSpec| u2 minor_version; // JVMSpec| u2 major_version; write_u2(ikh()->minor_version()); u2 major = ikh()->major_version(); write_u2(major); // JVMSpec| u2 constant_pool_count; // JVMSpec| cp_info constant_pool[constant_pool_count-1]; write_u2(cpool()->length()); copy_cpool_bytes(writeable_address(cpool_size())); // JVMSpec| u2 access_flags; write_u2(ikh()->access_flags().get_flags() & JVM_RECOGNIZED_CLASS_MODIFIERS); // JVMSpec| u2 this_class; // JVMSpec| u2 super_class; write_u2(class_symbol_to_cpool_index(ikh()->name())); Klass* super_class = ikh()->super(); write_u2(super_class == NULL? 0 : // zero for java.lang.Object class_symbol_to_cpool_index(super_class->name())); // JVMSpec| u2 interfaces_count; // JVMSpec| u2 interfaces[interfaces_count]; Array<Klass*>* interfaces = ikh()->local_interfaces(); int num_interfaces = interfaces->length(); write_u2(num_interfaces); for (int index = 0; index < num_interfaces; index++) { HandleMark hm(thread()); instanceKlassHandle iikh(thread(), interfaces->at(index)); write_u2(class_symbol_to_cpool_index(iikh->name())); } // JVMSpec| u2 fields_count; // JVMSpec| field_info fields[fields_count]; write_field_infos(); // JVMSpec| u2 methods_count; // JVMSpec| method_info methods[methods_count]; write_method_infos(); // JVMSpec| u2 attributes_count; // JVMSpec| attribute_info attributes[attributes_count]; // JVMSpec| } /* end ClassFile 8? write_class_attributes(); }
// ------------------------------------------------------------------ // ciExceptionHandler::catch_klass // // Get the exception klass that this handler catches. ciInstanceKlass* ciExceptionHandler::catch_klass() { VM_ENTRY_MARK; assert(!is_catch_all(), "bad index"); if (_catch_klass == NULL) { bool will_link; assert(_loading_klass->get_instanceKlass()->is_linked(), "must be linked before accessing constant pool"); constantPoolHandle cpool(_loading_klass->get_instanceKlass()->constants()); ciKlass* k = CURRENT_ENV->get_klass_by_index(cpool, _catch_klass_index, will_link, _loading_klass); if (!will_link && k->is_loaded()) { GUARDED_VM_ENTRY( k = CURRENT_ENV->get_unloaded_klass(_loading_klass, k->name()); ) }
// ------------------------------------------------------------------ // ciField::ciField ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with(NULL) { ASSERT_IN_VM; CompilerThread *thread = CompilerThread::current(); assert(ciObjectFactory::is_initialized(), "not a shared field"); assert(klass->get_instanceKlass()->is_linked(), "must be linked before using its constan-pool"); _cp_index = index; constantPoolHandle cpool(thread, klass->get_instanceKlass()->constants()); // Get the field's name, signature, and type. symbolHandle name (thread, cpool->name_ref_at(index)); _name = ciEnv::current(thread)->get_object(name())->as_symbol(); int nt_index = cpool->name_and_type_ref_index_at(index); int sig_index = cpool->signature_ref_index_at(nt_index); symbolHandle signature (thread, cpool->symbol_at(sig_index)); _signature = ciEnv::current(thread)->get_object(signature())->as_symbol(); BasicType field_type = FieldType::basic_type(signature()); // If the field is a pointer type, get the klass of the // field. if (field_type == T_OBJECT || field_type == T_ARRAY) { bool ignore; // This is not really a class reference; the index always refers to the // field's type signature, as a symbol. Linkage checks do not apply. _type = ciEnv::current(thread)->get_klass_by_index(cpool, sig_index, ignore, klass); } else { _type = ciType::make(field_type); } _name = (ciSymbol*)ciEnv::current(thread)->get_object(name()); // Get the field's declared holder. // // Note: we actually create a ciInstanceKlass for this klass, // even though we may not need to. int holder_index = cpool->klass_ref_index_at(index); bool holder_is_accessible; ciInstanceKlass* declared_holder = ciEnv::current(thread)->get_klass_by_index(cpool, holder_index, holder_is_accessible, klass)->as_instance_klass(); // The declared holder of this field may not have been loaded. // Bail out with partial field information. if (!holder_is_accessible) { // _cp_index and _type have already been set. // The default values for _flags and _constant_value will suffice. // We need values for _holder, _offset, and _is_constant, _holder = declared_holder; _offset = -1; _is_constant = false; return; } instanceKlass* loaded_decl_holder = declared_holder->get_instanceKlass(); // Perform the field lookup. fieldDescriptor field_desc; klassOop canonical_holder = loaded_decl_holder->find_field(name(), signature(), &field_desc); if (canonical_holder == NULL) { // Field lookup failed. Will be detected by will_link. _holder = declared_holder; _offset = -1; _is_constant = false; return; } assert(canonical_holder == field_desc.field_holder(), "just checking"); initialize_from(&field_desc); }
// ------------------------------------------------------------------ // ciBytecodeStream::get_klass // // If this bytecode is a new, newarray, multianewarray, instanceof, // or checkcast, get the referenced klass. ciKlass* ciBytecodeStream::get_klass(bool& will_link) { VM_ENTRY_MARK; constantPoolHandle cpool(_method->get_methodOop()->constants()); return CURRENT_ENV->get_klass_by_index(cpool, get_klass_index(), will_link, _holder); }