Ejemplo n.º 1
0
 FieldStreamBase(instanceKlassHandle klass) {
   _fields = klass->fields();
   _constants = klass->constants();
   _index = 0;
   _limit = klass->java_fields_count();
   init_generic_signature_start_slot();
 }
Ejemplo n.º 2
0
bool VerificationType::resolve_and_check_assignability(instanceKlassHandle klass, Symbol* name,
         Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object, TRAPS) {
  Klass* obj = SystemDictionary::resolve_or_fail(
      name, Handle(THREAD, klass->class_loader()),
      Handle(THREAD, klass->protection_domain()), true, CHECK_false);
  if (log_is_enabled(Debug, class, resolve)) {
    Verifier::trace_class_resolution(obj, klass());
  }

  KlassHandle this_class(THREAD, obj);

  if (this_class->is_interface() && (!from_field_is_protected ||
      from_name != vmSymbols::java_lang_Object())) {
    // If we are not trying to access a protected field or method in
    // java.lang.Object then, for arrays, we only allow assignability
    // to interfaces java.lang.Cloneable and java.io.Serializable.
    // Otherwise, we treat interfaces as java.lang.Object.
    return !from_is_array ||
      this_class == SystemDictionary::Cloneable_klass() ||
      this_class == SystemDictionary::Serializable_klass();
  } else if (from_is_object) {
    Klass* from_class = SystemDictionary::resolve_or_fail(
        from_name, Handle(THREAD, klass->class_loader()),
        Handle(THREAD, klass->protection_domain()), true, CHECK_false);
    if (log_is_enabled(Debug, class, resolve)) {
      Verifier::trace_class_resolution(from_class, klass());
    }
    return InstanceKlass::cast(from_class)->is_subclass_of(this_class());
  }

  return false;
}
Ejemplo n.º 3
0
  // Field names and signatures are referenced via constantpool indexes. In the new class
  // version, the layout of the constantpool can be different, so these indexes should be
  // patched.
  void patch_indexes_for_fields(instanceKlassHandle k_h, instanceKlassHandle k_h_new) {
    typeArrayOop k_fields = k_h->fields();
    typeArrayOop k_new_fields = k_h_new->fields();
    int n_fields = k_fields->length();

    for (int i = 0; i < n_fields; i += instanceKlass::next_offset) {
      // name and signature
      k_fields->short_at_put(
        i + instanceKlass::name_index_offset,
        k_new_fields->short_at(i + instanceKlass::name_index_offset)
        );
      k_fields->short_at_put(
        i + instanceKlass::signature_index_offset,
        k_new_fields->short_at(i + instanceKlass::signature_index_offset)
        );
    }
  }
Ejemplo n.º 4
0
KlassStream::KlassStream(instanceKlassHandle klass, bool local_only, bool classes_only) {
  _klass = klass;
  if (classes_only) {
    _interfaces = Universe::the_empty_system_obj_array();
  } else {
    _interfaces = klass->transitive_interfaces();
  }
  _interface_index = _interfaces->length();
  _local_only = local_only;
  _classes_only = classes_only;
}
Ejemplo n.º 5
0
 instanceKlassHandle record_result(const int classpath_index,
                                   const ClassPathEntry* e,
                                   instanceKlassHandle result, TRAPS) {
   if (ClassLoader::add_package(_file_name, classpath_index, THREAD)) {
     if (DumpSharedSpaces) {
       result->set_shared_classpath_index(classpath_index);
     }
     return result;
   } else {
     return instanceKlassHandle(); // NULL
   }
 }
 // Calls to this constructor must be proceeded by a ResourceMark
 // and a HandleMark
 JvmtiConstantPoolReconstituter(instanceKlassHandle ikh){
   set_error(JVMTI_ERROR_NONE);
   _ikh = ikh;
   _cpool = constantPoolHandle(Thread::current(), ikh->constants());
   _symmap = new SymbolHashMap();
   _classmap = new SymbolHashMap();
   _cpool_size = _cpool->hash_entries_to(_symmap, _classmap);
   if (_cpool_size == 0) {
     set_error(JVMTI_ERROR_OUT_OF_MEMORY);
   } else if (_cpool_size < 0) {
     set_error(JVMTI_ERROR_INTERNAL);
   }
 }
Ejemplo n.º 7
0
void CHA::process_interface(instanceKlassHandle r, GrowableArray<KlassHandle>* receivers, GrowableArray<methodHandle>* methods, 
                            symbolHandle name, symbolHandle signature) {
  // recursively add non-abstract implementors of interface r to receivers list
  assert(r->is_interface(), "should call process_class instead");
  
  // We only store the implementors for an interface, if there is exactly one implementor  
  klassOop k = r->implementor();
  assert(k == NULL || r->nof_implementors() == 1, "inconsistent implementor list");
  if (k != NULL && !methods->is_full()) {   
    instanceKlass* kl = instanceKlass::cast(k);
    assert(kl->oop_is_instance(), "primitive klasses don't implement interfaces");
    assert(!kl->is_interface(), "must be a real klass");
    process_class(kl, receivers, methods, name, signature);
  }

  // now process all subinterfaces
  for (Klass* s = r->subklass(); s != NULL && !methods->is_full(); s = s->next_sibling()) {
    assert(s->is_interface(), "must be an interface");
    instanceKlassHandle sub(s->as_klassOop());
    process_interface(sub, receivers, methods, name, signature);
    if (methods->is_full()) break;          // give up -- too many overriding methods
  }
}
void Dictionary::add_protection_domain(int index, unsigned int hash,
                                       instanceKlassHandle klass,
                                       ClassLoaderData* loader_data, Handle protection_domain,
                                       TRAPS) {
  Symbol*  klass_name = klass->name();
  DictionaryEntry* entry = get_entry(index, hash, klass_name, loader_data);

  assert(entry != NULL,"entry must be present, we just created it");
  assert(protection_domain() != NULL,
         "real protection domain should be present");

  entry->add_protection_domain(this, protection_domain());

  assert(entry->contains_protection_domain(protection_domain()),
         "now protection domain should be present");
}
Ejemplo n.º 9
0
 InternalFieldStream(instanceKlassHandle k): FieldStreamBase(k->fields(), k->constants(), k->java_fields_count(), 0) {}
Ejemplo n.º 10
0
// Relocate jsr/rets in a method.  This can't be done with the rewriter
// stage because it can throw other exceptions, leaving the bytecodes
// pointing at constant pool cache entries.
// Link and check jvmti dependencies while we're iterating over the methods.
// JSR292 code calls with a different set of methods, so two entry points.
void Rewriter::relocate_and_link(instanceKlassHandle this_oop, TRAPS) {
  objArrayHandle methods(THREAD, this_oop->methods());
  relocate_and_link(this_oop, methods, THREAD);
}
Ejemplo n.º 11
0
void Rewriter::rewrite(instanceKlassHandle klass, TRAPS) {
  ResourceMark rm(THREAD);
  Rewriter     rw(klass, klass->constants(), klass->methods(), CHECK);
  // (That's all, folks.)
}
Ejemplo n.º 12
0
  jvmdiError compare_class_versions(instanceKlassHandle k_h_old, instanceKlassHandle k_h_new) {
    int i;

    // Check whether essential class modifiers are the same. The rest can probably differ, e.g.
    // why not allow substitute class to be synthetic, if it satisfies other conditions.
    AccessFlags old_flags = k_h_old->access_flags();
    AccessFlags new_flags = k_h_new->access_flags();
    if (old_flags.is_public() != new_flags.is_public() ||
	old_flags.is_final() != new_flags.is_final() ||
	old_flags.is_interface() != new_flags.is_interface() ||
	old_flags.is_abstract() != new_flags.is_abstract()) {
      return JVMDI_ERROR_CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED;
    }

    // Check superclasses, or rather their names, since superclasses themselves can be
    // requested to replace
    if (Klass::cast(k_h_old->super())->name() != Klass::cast(k_h_new->super())->name()) {
      return JVMDI_ERROR_HIERARCHY_CHANGE_NOT_IMPLEMENTED;
    }

    // Check if the number, names and order of directly implemented interfaces are the same.
    // I think in principle we should just check if the sets of names of directly implemented
    // interfaces are the same, i.e. the order of declaration (which, however, if changed in the
    // .java file, also changes in .class file) should not matter. However, comparing sets is
    // technically a bit more difficult, and, more importantly, I am not sure at present that the
    // order of interfaces does not matter on the implementation level, i.e. that the VM does not
    // rely on it somewhere.
    objArrayOop k_interfaces = k_h_old->local_interfaces();
    objArrayOop k_new_interfaces = k_h_new->local_interfaces();
    int n_intfs = k_interfaces->length();
    if (n_intfs != k_new_interfaces->length()) {
      return JVMDI_ERROR_HIERARCHY_CHANGE_NOT_IMPLEMENTED;
    }
    for (i = 0; i < n_intfs; i++) {
      if (Klass::cast((klassOop) k_interfaces->obj_at(i))->name() !=
	  Klass::cast((klassOop) k_new_interfaces->obj_at(i))->name()) {
        return JVMDI_ERROR_HIERARCHY_CHANGE_NOT_IMPLEMENTED;
      }
    }

    // Check if the number, names, types and order of fields declared in these classes
    // are the same.
    typeArrayOop k_old_fields = k_h_old->fields();
    typeArrayOop k_new_fields = k_h_new->fields();
    int n_fields = k_old_fields->length();
    if (n_fields != k_new_fields->length()) {
      return JVMDI_ERROR_SCHEMA_CHANGE_NOT_IMPLEMENTED;
    }

    for (i = 0; i < n_fields; i += instanceKlass::next_offset) {
      // access
      if (k_old_fields->ushort_at(i + instanceKlass::access_flags_offset) !=
        k_new_fields->ushort_at(i + instanceKlass::access_flags_offset)) {
        return JVMDI_ERROR_SCHEMA_CHANGE_NOT_IMPLEMENTED;
      }
      // offset
      if (k_old_fields->short_at(i + instanceKlass::low_offset) != 
	  k_new_fields->short_at(i + instanceKlass::low_offset) ||
	  k_old_fields->short_at(i + instanceKlass::high_offset) != 
	  k_new_fields->short_at(i + instanceKlass::high_offset)) {
        return JVMDI_ERROR_SCHEMA_CHANGE_NOT_IMPLEMENTED;
      }
      // name and signature
      jshort name_index = k_old_fields->short_at(i + instanceKlass::name_index_offset);
      jshort sig_index = k_old_fields->short_at(i +instanceKlass::signature_index_offset);
      symbolOop name_sym1 = k_h_old->constants()->symbol_at(name_index);
      symbolOop sig_sym1 = k_h_old->constants()->symbol_at(sig_index);
      name_index = k_new_fields->short_at(i + instanceKlass::name_index_offset);
      sig_index = k_new_fields->short_at(i + instanceKlass::signature_index_offset);
      symbolOop name_sym2 = k_h_new->constants()->symbol_at(name_index);
      symbolOop sig_sym2 = k_h_new->constants()->symbol_at(sig_index);
      if (name_sym1 != name_sym2 || sig_sym1 != sig_sym2) {
        return JVMDI_ERROR_SCHEMA_CHANGE_NOT_IMPLEMENTED;
      }
    }

    // Check if the number, names, signatures and order of methods declared in these classes
    // are the same.
    objArrayOop k_methods = k_h_old->methods();
    objArrayOop k_new_methods = k_h_new->methods();
    int n_methods = k_methods->length();
    if (n_methods < k_new_methods->length()) return JVMDI_ERROR_ADD_METHOD_NOT_IMPLEMENTED;
    else if (n_methods > k_new_methods->length()) return JVMDI_ERROR_DELETE_METHOD_NOT_IMPLEMENTED;

    for (i = 0; i < n_methods; i++) {
      methodOop k_method = (methodOop) k_methods->obj_at(i);
      methodOop k_new_method = (methodOop) k_new_methods->obj_at(i);
      if (k_method->name() != k_new_method->name()) return JVMDI_ERROR_DELETE_METHOD_NOT_IMPLEMENTED;
      if (k_method->signature() != k_new_method->signature()) {
        return JVMDI_ERROR_DELETE_METHOD_NOT_IMPLEMENTED;
      }
      old_flags = k_method->access_flags();
      new_flags = k_new_method->access_flags();
      // It's probably safer to not compare the values of access_flags directly, since
      // some bits in them encode some implementation-specific information, e.g.
      // something about inlined tables. This may be different in the new version,
      // but should not affect method changeability.
      if (old_flags.is_public() != new_flags.is_public() ||
	  old_flags.is_protected() != new_flags.is_protected() ||
	  old_flags.is_private() != new_flags.is_private() ||
	  old_flags.is_static() != new_flags.is_static() ||
	  old_flags.is_final() != new_flags.is_final() ||
	  old_flags.is_synchronized() != new_flags.is_synchronized() ||
          old_flags.is_strict() != new_flags.is_strict() ||
	  old_flags.is_interface() != new_flags.is_interface() ||
	  old_flags.is_abstract() != new_flags.is_abstract()) {
        return JVMDI_ERROR_METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED;
      }      
    }

    return JVMDI_ERROR_NONE;
  }
jvmtiError VM_RedefineClasses::compare_class_versions(instanceKlassHandle k_h_old, instanceKlassHandle k_h_new) {
  int i;

  // Check superclasses, or rather their names, since superclasses themselves can be
  // requested to replace. 
  // Check for NULL superclass first since this might be java.lang.Object
  if (k_h_old->super() != k_h_new->super() && 
      (k_h_old->super() == NULL || k_h_new->super() == NULL ||
       Klass::cast(k_h_old->super())->name() != Klass::cast(k_h_new->super())->name())) {
    return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
  }

  // Check if the number, names and order of directly implemented interfaces are the same.
  // I think in principle we should just check if the sets of names of directly implemented
  // interfaces are the same, i.e. the order of declaration (which, however, if changed in the
  // .java file, also changes in .class file) should not matter. However, comparing sets is
  // technically a bit more difficult, and, more importantly, I am not sure at present that the
  // order of interfaces does not matter on the implementation level, i.e. that the VM does not
  // rely on it somewhere.
  objArrayOop k_interfaces = k_h_old->local_interfaces();
  objArrayOop k_new_interfaces = k_h_new->local_interfaces();
  int n_intfs = k_interfaces->length();
  if (n_intfs != k_new_interfaces->length()) {
    return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
  }
  for (i = 0; i < n_intfs; i++) {
    if (Klass::cast((klassOop) k_interfaces->obj_at(i))->name() !=
        Klass::cast((klassOop) k_new_interfaces->obj_at(i))->name()) {
      return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
    }
  }

  // Check whether class is in the error init state.
  if (k_h_old->is_in_error_state()) {
    // TBD #5057930: special error code is needed in 1.6 
    return JVMTI_ERROR_INVALID_CLASS;
  }

  // Check whether class modifiers are the same.
  jushort old_flags = (jushort) k_h_old->access_flags().get_flags();
  jushort new_flags = (jushort) k_h_new->access_flags().get_flags();
  if (old_flags != new_flags) {
    return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED;
  }

  // Check if the number, names, types and order of fields declared in these classes
  // are the same.
  typeArrayOop k_old_fields = k_h_old->fields();
  typeArrayOop k_new_fields = k_h_new->fields();
  int n_fields = k_old_fields->length();
  if (n_fields != k_new_fields->length()) {
    return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
  }

  for (i = 0; i < n_fields; i += instanceKlass::next_offset) {
    // access
    old_flags = k_old_fields->ushort_at(i + instanceKlass::access_flags_offset);
    new_flags = k_new_fields->ushort_at(i + instanceKlass::access_flags_offset);
    if ((old_flags ^ new_flags) & JVM_RECOGNIZED_FIELD_MODIFIERS) {
      return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
    }
    // offset
    if (k_old_fields->short_at(i + instanceKlass::low_offset) != 
        k_new_fields->short_at(i + instanceKlass::low_offset) ||
        k_old_fields->short_at(i + instanceKlass::high_offset) != 
        k_new_fields->short_at(i + instanceKlass::high_offset)) {
      return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
    }
    // name and signature
    jshort name_index = k_old_fields->short_at(i + instanceKlass::name_index_offset);
    jshort sig_index = k_old_fields->short_at(i +instanceKlass::signature_index_offset);
    symbolOop name_sym1 = k_h_old->constants()->symbol_at(name_index);
    symbolOop sig_sym1 = k_h_old->constants()->symbol_at(sig_index);
    name_index = k_new_fields->short_at(i + instanceKlass::name_index_offset);
    sig_index = k_new_fields->short_at(i + instanceKlass::signature_index_offset);
    symbolOop name_sym2 = k_h_new->constants()->symbol_at(name_index);
    symbolOop sig_sym2 = k_h_new->constants()->symbol_at(sig_index);
    if (name_sym1 != name_sym2 || sig_sym1 != sig_sym2) {
      return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
    }
  }

  // Check if the number, names, signatures and order of methods declared in these classes
  // are the same.
  objArrayOop k_methods = k_h_old->methods();
  objArrayOop k_new_methods = k_h_new->methods();
  int n_methods = k_methods->length();
  if (n_methods < k_new_methods->length()) return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED;
  else if (n_methods > k_new_methods->length()) return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED;

  for (i = 0; i < n_methods; i++) {
    methodOop k_method = (methodOop) k_methods->obj_at(i);
    methodOop k_new_method = (methodOop) k_new_methods->obj_at(i);
    if (k_method->name() != k_new_method->name()) return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED;
    if (k_method->signature() != k_new_method->signature()) {
      return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED;
    }
    old_flags = (jushort) k_method->access_flags().get_flags();
    new_flags = (jushort) k_new_method->access_flags().get_flags();
    if (old_flags != new_flags) {
      return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED;
    }      
  }

  return JVMTI_ERROR_NONE;
}
// Install the redefinition of a class --
// The original instanceKlass object (k_h) always represents the latest 
// version of the respective class. However, during class redefinition we swap
// or replace much of its content with that of the instanceKlass object created
// from the bytes of the redefine (k_h_new). Specifically, k_h points to the new
// constantpool and methods objects, which we take from k_h_new. k_h_new, in turn,
// assumes the role of the previous class version, with the old constantpool and
// methods (taken from k_h) attached to it. k_h links to k_h_new to create a 
// linked list of class versions. 
void VM_RedefineClasses::redefine_single_class(jclass j_clazz, instanceKlassHandle k_h_new, TRAPS) {

  oop mirror = JNIHandles::resolve_non_null(j_clazz);
  klassOop k_oop = java_lang_Class::as_klassOop(mirror);
  instanceKlassHandle k_h = instanceKlassHandle(THREAD, k_oop);

  // Remove all breakpoints in methods of this class
  JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
  jvmti_breakpoints.clearall_in_class_at_safepoint(k_oop); 

  // Deoptimize all compiled code that depends on this class
  NOT_CORE(Universe::flush_evol_dependents_on(k_h));

  _old_methods = k_h->methods();
  _new_methods = k_h_new->methods();
  _evolving_koop = k_oop;
  _old_constants = k_h->constants();

  // flush the cached jmethodID fields for _old_methods
  flush_method_jmethod_id_cache();

  // Patch the indexes into the constantpool from the array of fields of the evolving
  // class. This is required, because the layout of the new constantpool can be different,
  // so old indexes corresponding to field names and signatures can become invalid.
  patch_indexes_for_fields(k_h, k_h_new);

  // Make new constantpool object (and methodOops via it) point to the original class object
  k_h_new->constants()->set_pool_holder(k_h());

  // Replace methods and constantpool
  k_h->set_methods(_new_methods);
  k_h_new->set_methods(_old_methods);     // To prevent potential GCing of the old methods, 
                                          // and to be able to undo operation easily.

  constantPoolOop old_constants = k_h->constants();
  k_h->set_constants(k_h_new->constants());
  k_h_new->set_constants(old_constants);  // See the previous comment.

  check_methods_and_mark_as_old();
  transfer_old_native_function_registrations();

  // Replace inner_classes
  typeArrayOop old_inner_classes = k_h->inner_classes();
  k_h->set_inner_classes(k_h_new->inner_classes());
  k_h_new->set_inner_classes(old_inner_classes);

  // Initialize the vtable and interface table after
  // methods have been rewritten
  { ResourceMark rm(THREAD);
  k_h->vtable()->initialize_vtable(THREAD); // No exception can happen here
  k_h->itable()->initialize_itable();
  }

  // Copy the "source file name" attribute from new class version
  k_h->set_source_file_name(k_h_new->source_file_name());

  // Copy the "source debug extension" attribute from new class version
  k_h->set_source_debug_extension(k_h_new->source_debug_extension());

  // Use of javac -g could be different in the old and the new
  if (k_h_new->access_flags().has_localvariable_table() !=
      k_h->access_flags().has_localvariable_table()) {

    AccessFlags flags = k_h->access_flags();
    if (k_h_new->access_flags().has_localvariable_table()) {
      flags.set_has_localvariable_table();
    } else {
      flags.clear_has_localvariable_table();
    }
    k_h->set_access_flags(flags);
  }

  // Replace class annotation fields values
  typeArrayOop old_class_annotations = k_h->class_annotations();
  k_h->set_class_annotations(k_h_new->class_annotations());
  k_h_new->set_class_annotations(old_class_annotations);

  // Replace fields annotation fields values
  objArrayOop old_fields_annotations = k_h->fields_annotations();
  k_h->set_fields_annotations(k_h_new->fields_annotations());
  k_h_new->set_fields_annotations(old_fields_annotations);

  // Replace methods annotation fields values
  objArrayOop old_methods_annotations = k_h->methods_annotations();
  k_h->set_methods_annotations(k_h_new->methods_annotations());
  k_h_new->set_methods_annotations(old_methods_annotations);

  // Replace methods parameter annotation fields values
  objArrayOop old_methods_parameter_annotations = k_h->methods_parameter_annotations();
  k_h->set_methods_parameter_annotations(k_h_new->methods_parameter_annotations());
  k_h_new->set_methods_parameter_annotations(old_methods_parameter_annotations);

  // Replace methods default annotation fields values
  objArrayOop old_methods_default_annotations = k_h->methods_default_annotations();
  k_h->set_methods_default_annotations(k_h_new->methods_default_annotations());
  k_h_new->set_methods_default_annotations(old_methods_default_annotations);

  // Replace major version number of class file
  u2 old_major_version = k_h->major_version();
  k_h->set_major_version(k_h_new->major_version());
  k_h_new->set_major_version(old_major_version);

  // Replace CP indexes for class and name+type of enclosing method
  u2 old_class_idx  = k_h->enclosing_method_class_index();
  u2 old_method_idx = k_h->enclosing_method_method_index();
  k_h->set_enclosing_method_indices(k_h_new->enclosing_method_class_index(),
                                    k_h_new->enclosing_method_method_index());
  k_h_new->set_enclosing_method_indices(old_class_idx, old_method_idx);

  // Maintain a linked list of versions of this class. 
  // List is in ascending age order. Current version (k_h) is the head.
  if (k_h->has_previous_version()) {
    k_h_new->set_previous_version(k_h->previous_version());
  }
  k_h->set_previous_version(k_h_new);

  // Adjust constantpool caches and vtables for all classes
  // that reference methods of the evolved class.
  SystemDictionary::classes_do(adjust_cpool_cache_and_vtable);
  k_h->set_rewritten_by_redefine(true);
}
Ejemplo n.º 15
0
 AllFieldStream(instanceKlassHandle k): FieldStreamBase(k->fields(), k->constants()) {}
Ejemplo n.º 16
0
 // Some recursive calls from the verifier to the name resolver
 // can cause the current class to be re-verified and rewritten.
 // If this happens, the original verification should not continue,
 // because constant pool indexes will have changed.
 // The rewriter is preceded by the verifier.  If the verifier throws
 // an error, rewriting is prevented.  Also, rewriting always precedes
 // bytecode execution or compilation.  Thus, is_rewritten implies
 // that a class has been verified and prepared for execution.
 bool was_recursively_verified() { return _klass->is_rewritten(); }
Ejemplo n.º 17
0
// called during initial loading of a shared class
instanceKlassHandle KlassFactory::check_shared_class_file_load_hook(
                                          instanceKlassHandle ik,
                                          Symbol* class_name,
                                          Handle class_loader,
                                          Handle protection_domain, TRAPS) {
#if INCLUDE_CDS && INCLUDE_JVMTI
  assert(ik.not_null(), "sanity");
  assert(ik()->is_shared(), "expecting a shared class");

  if (JvmtiExport::should_post_class_file_load_hook()) {
    assert(THREAD->is_Java_thread(), "must be JavaThread");

    // Post the CFLH
    JvmtiCachedClassFileData* cached_class_file = NULL;
    JvmtiCachedClassFileData* archived_class_data = ik->get_archived_class_data();
    assert(archived_class_data != NULL, "shared class has no archived class data");
    unsigned char* ptr =
        VM_RedefineClasses::get_cached_class_file_bytes(archived_class_data);
    unsigned char* end_ptr =
        ptr + VM_RedefineClasses::get_cached_class_file_len(archived_class_data);
    unsigned char* old_ptr = ptr;
    JvmtiExport::post_class_file_load_hook(class_name,
                                           class_loader,
                                           protection_domain,
                                           &ptr,
                                           &end_ptr,
                                           &cached_class_file);
    if (old_ptr != ptr) {
      // JVMTI agent has modified class file data.
      // Set new class file stream using JVMTI agent modified class file data.
      ClassLoaderData* loader_data =
        ClassLoaderData::class_loader_data(class_loader());
      int path_index = ik->shared_classpath_index();
      SharedClassPathEntry* ent =
        (SharedClassPathEntry*)FileMapInfo::shared_classpath(path_index);
      ClassFileStream* stream = new ClassFileStream(ptr,
                                                    end_ptr - ptr,
                                                    ent == NULL ? NULL : ent->_name,
                                                    ClassFileStream::verify);
      ClassFileParser parser(stream,
                             class_name,
                             loader_data,
                             protection_domain,
                             NULL,
                             NULL,
                             ClassFileParser::BROADCAST, // publicity level
                             CHECK_NULL);
      instanceKlassHandle new_ik = parser.create_instance_klass(true /* changed_by_loadhook */,
                                                                CHECK_NULL);
      if (cached_class_file != NULL) {
        new_ik->set_cached_class_file(cached_class_file);
      }

      if (class_loader.is_null()) {
        ResourceMark rm;
        ClassLoader::add_package(class_name->as_C_string(), path_index, THREAD);
      }

      return new_ik;
    }
  }
#endif

  return NULL;
}