//  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);
 }
Exemple #4
0
// ------------------------------------------------------------------
// 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();
}
Exemple #5
0
// ------------------------------------------------------------------
// 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());
      )
    }
Exemple #8
0
// ------------------------------------------------------------------
// 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);
}
Exemple #9
0
// ------------------------------------------------------------------
// 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);
}