mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 11:34:38 +02:00
Merge
This commit is contained in:
commit
b7f31f0375
96 changed files with 1222 additions and 1341 deletions
|
@ -105,10 +105,9 @@ objArrayOop Universe::_the_empty_class_klass_array = NULL;
|
|||
Array<Klass*>* Universe::_the_array_interfaces_array = NULL;
|
||||
oop Universe::_the_null_string = NULL;
|
||||
oop Universe::_the_min_jint_string = NULL;
|
||||
LatestMethodOopCache* Universe::_finalizer_register_cache = NULL;
|
||||
LatestMethodOopCache* Universe::_loader_addClass_cache = NULL;
|
||||
LatestMethodOopCache* Universe::_pd_implies_cache = NULL;
|
||||
ActiveMethodOopsCache* Universe::_reflect_invoke_cache = NULL;
|
||||
LatestMethodCache* Universe::_finalizer_register_cache = NULL;
|
||||
LatestMethodCache* Universe::_loader_addClass_cache = NULL;
|
||||
LatestMethodCache* Universe::_pd_implies_cache = NULL;
|
||||
oop Universe::_out_of_memory_error_java_heap = NULL;
|
||||
oop Universe::_out_of_memory_error_metaspace = NULL;
|
||||
oop Universe::_out_of_memory_error_class_metaspace = NULL;
|
||||
|
@ -225,7 +224,6 @@ void Universe::serialize(SerializeClosure* f, bool do_all) {
|
|||
f->do_ptr((void**)&_the_empty_klass_array);
|
||||
_finalizer_register_cache->serialize(f);
|
||||
_loader_addClass_cache->serialize(f);
|
||||
_reflect_invoke_cache->serialize(f);
|
||||
_pd_implies_cache->serialize(f);
|
||||
}
|
||||
|
||||
|
@ -649,10 +647,9 @@ jint universe_init() {
|
|||
|
||||
// We have a heap so create the Method* caches before
|
||||
// Metaspace::initialize_shared_spaces() tries to populate them.
|
||||
Universe::_finalizer_register_cache = new LatestMethodOopCache();
|
||||
Universe::_loader_addClass_cache = new LatestMethodOopCache();
|
||||
Universe::_pd_implies_cache = new LatestMethodOopCache();
|
||||
Universe::_reflect_invoke_cache = new ActiveMethodOopsCache();
|
||||
Universe::_finalizer_register_cache = new LatestMethodCache();
|
||||
Universe::_loader_addClass_cache = new LatestMethodCache();
|
||||
Universe::_pd_implies_cache = new LatestMethodCache();
|
||||
|
||||
if (UseSharedSpaces) {
|
||||
// Read the data structures supporting the shared spaces (shared
|
||||
|
@ -1088,35 +1085,21 @@ bool universe_post_init() {
|
|||
vmSymbols::register_method_name(),
|
||||
vmSymbols::register_method_signature());
|
||||
if (m == NULL || !m->is_static()) {
|
||||
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodException(),
|
||||
"java.lang.ref.Finalizer.register", false);
|
||||
tty->print_cr("Unable to link/verify Finalizer.register method");
|
||||
return false; // initialization failed (cannot throw exception yet)
|
||||
}
|
||||
Universe::_finalizer_register_cache->init(
|
||||
SystemDictionary::Finalizer_klass(), m, CHECK_false);
|
||||
|
||||
// Resolve on first use and initialize class.
|
||||
// Note: No race-condition here, since a resolve will always return the same result
|
||||
|
||||
// Setup method for security checks
|
||||
k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_reflect_Method(), true, CHECK_false);
|
||||
k_h = instanceKlassHandle(THREAD, k);
|
||||
k_h->link_class(CHECK_false);
|
||||
m = k_h->find_method(vmSymbols::invoke_name(), vmSymbols::object_object_array_object_signature());
|
||||
if (m == NULL || m->is_static()) {
|
||||
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodException(),
|
||||
"java.lang.reflect.Method.invoke", false);
|
||||
}
|
||||
Universe::_reflect_invoke_cache->init(k_h(), m, CHECK_false);
|
||||
SystemDictionary::Finalizer_klass(), m);
|
||||
|
||||
// Setup method for registering loaded classes in class loader vector
|
||||
InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->link_class(CHECK_false);
|
||||
m = InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->find_method(vmSymbols::addClass_name(), vmSymbols::class_void_signature());
|
||||
if (m == NULL || m->is_static()) {
|
||||
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodException(),
|
||||
"java.lang.ClassLoader.addClass", false);
|
||||
tty->print_cr("Unable to link/verify ClassLoader.addClass method");
|
||||
return false; // initialization failed (cannot throw exception yet)
|
||||
}
|
||||
Universe::_loader_addClass_cache->init(
|
||||
SystemDictionary::ClassLoader_klass(), m, CHECK_false);
|
||||
SystemDictionary::ClassLoader_klass(), m);
|
||||
|
||||
// Setup method for checking protection domain
|
||||
InstanceKlass::cast(SystemDictionary::ProtectionDomain_klass())->link_class(CHECK_false);
|
||||
|
@ -1132,7 +1115,7 @@ bool universe_post_init() {
|
|||
return false; // initialization failed
|
||||
}
|
||||
Universe::_pd_implies_cache->init(
|
||||
SystemDictionary::ProtectionDomain_klass(), m, CHECK_false);;
|
||||
SystemDictionary::ProtectionDomain_klass(), m);;
|
||||
}
|
||||
|
||||
// The folowing is initializing converter functions for serialization in
|
||||
|
@ -1455,7 +1438,7 @@ void Universe::compute_verify_oop_data() {
|
|||
}
|
||||
|
||||
|
||||
void CommonMethodOopCache::init(Klass* k, Method* m, TRAPS) {
|
||||
void LatestMethodCache::init(Klass* k, Method* m) {
|
||||
if (!UseSharedSpaces) {
|
||||
_klass = k;
|
||||
}
|
||||
|
@ -1471,88 +1454,7 @@ void CommonMethodOopCache::init(Klass* k, Method* m, TRAPS) {
|
|||
}
|
||||
|
||||
|
||||
ActiveMethodOopsCache::~ActiveMethodOopsCache() {
|
||||
if (_prev_methods != NULL) {
|
||||
delete _prev_methods;
|
||||
_prev_methods = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ActiveMethodOopsCache::add_previous_version(Method* method) {
|
||||
assert(Thread::current()->is_VM_thread(),
|
||||
"only VMThread can add previous versions");
|
||||
|
||||
// Only append the previous method if it is executing on the stack.
|
||||
if (method->on_stack()) {
|
||||
|
||||
if (_prev_methods == NULL) {
|
||||
// This is the first previous version so make some space.
|
||||
// Start with 2 elements under the assumption that the class
|
||||
// won't be redefined much.
|
||||
_prev_methods = new (ResourceObj::C_HEAP, mtClass) GrowableArray<Method*>(2, true);
|
||||
}
|
||||
|
||||
// RC_TRACE macro has an embedded ResourceMark
|
||||
RC_TRACE(0x00000100,
|
||||
("add: %s(%s): adding prev version ref for cached method @%d",
|
||||
method->name()->as_C_string(), method->signature()->as_C_string(),
|
||||
_prev_methods->length()));
|
||||
|
||||
_prev_methods->append(method);
|
||||
}
|
||||
|
||||
|
||||
// Since the caller is the VMThread and we are at a safepoint, this is a good
|
||||
// time to clear out unused method references.
|
||||
|
||||
if (_prev_methods == NULL) return;
|
||||
|
||||
for (int i = _prev_methods->length() - 1; i >= 0; i--) {
|
||||
Method* method = _prev_methods->at(i);
|
||||
assert(method != NULL, "weak method ref was unexpectedly cleared");
|
||||
|
||||
if (!method->on_stack()) {
|
||||
// This method isn't running anymore so remove it
|
||||
_prev_methods->remove_at(i);
|
||||
MetadataFactory::free_metadata(method->method_holder()->class_loader_data(), method);
|
||||
} else {
|
||||
// RC_TRACE macro has an embedded ResourceMark
|
||||
RC_TRACE(0x00000400,
|
||||
("add: %s(%s): previous cached method @%d is alive",
|
||||
method->name()->as_C_string(), method->signature()->as_C_string(), i));
|
||||
}
|
||||
}
|
||||
} // end add_previous_version()
|
||||
|
||||
|
||||
bool ActiveMethodOopsCache::is_same_method(const Method* method) const {
|
||||
InstanceKlass* ik = InstanceKlass::cast(klass());
|
||||
const Method* check_method = ik->method_with_idnum(method_idnum());
|
||||
assert(check_method != NULL, "sanity check");
|
||||
if (check_method == method) {
|
||||
// done with the easy case
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_prev_methods != NULL) {
|
||||
// The cached method has been redefined at least once so search
|
||||
// the previous versions for a match.
|
||||
for (int i = 0; i < _prev_methods->length(); i++) {
|
||||
check_method = _prev_methods->at(i);
|
||||
if (check_method == method) {
|
||||
// a previous version matches
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// either no previous versions or no previous version matched
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Method* LatestMethodOopCache::get_Method() {
|
||||
Method* LatestMethodCache::get_method() {
|
||||
if (klass() == NULL) return NULL;
|
||||
InstanceKlass* ik = InstanceKlass::cast(klass());
|
||||
Method* m = ik->method_with_idnum(method_idnum());
|
||||
|
|
|
@ -41,10 +41,11 @@ class CollectedHeap;
|
|||
class DeferredObjAllocEvent;
|
||||
|
||||
|
||||
// Common parts of a Method* cache. This cache safely interacts with
|
||||
// the RedefineClasses API.
|
||||
//
|
||||
class CommonMethodOopCache : public CHeapObj<mtClass> {
|
||||
// A helper class for caching a Method* when the user of the cache
|
||||
// only cares about the latest version of the Method*. This cache safely
|
||||
// interacts with the RedefineClasses API.
|
||||
|
||||
class LatestMethodCache : public CHeapObj<mtClass> {
|
||||
// We save the Klass* and the idnum of Method* in order to get
|
||||
// the current cached Method*.
|
||||
private:
|
||||
|
@ -52,12 +53,14 @@ class CommonMethodOopCache : public CHeapObj<mtClass> {
|
|||
int _method_idnum;
|
||||
|
||||
public:
|
||||
CommonMethodOopCache() { _klass = NULL; _method_idnum = -1; }
|
||||
~CommonMethodOopCache() { _klass = NULL; _method_idnum = -1; }
|
||||
LatestMethodCache() { _klass = NULL; _method_idnum = -1; }
|
||||
~LatestMethodCache() { _klass = NULL; _method_idnum = -1; }
|
||||
|
||||
void init(Klass* k, Method* m, TRAPS);
|
||||
Klass* klass() const { return _klass; }
|
||||
int method_idnum() const { return _method_idnum; }
|
||||
void init(Klass* k, Method* m);
|
||||
Klass* klass() const { return _klass; }
|
||||
int method_idnum() const { return _method_idnum; }
|
||||
|
||||
Method* get_method();
|
||||
|
||||
// Enhanced Class Redefinition support
|
||||
void classes_do(void f(Klass*)) {
|
||||
|
@ -72,39 +75,6 @@ class CommonMethodOopCache : public CHeapObj<mtClass> {
|
|||
};
|
||||
|
||||
|
||||
// A helper class for caching a Method* when the user of the cache
|
||||
// cares about all versions of the Method*.
|
||||
//
|
||||
class ActiveMethodOopsCache : public CommonMethodOopCache {
|
||||
// This subclass adds weak references to older versions of the
|
||||
// Method* and a query method for a Method*.
|
||||
|
||||
private:
|
||||
// If the cached Method* has not been redefined, then
|
||||
// _prev_methods will be NULL. If all of the previous
|
||||
// versions of the method have been collected, then
|
||||
// _prev_methods can have a length of zero.
|
||||
GrowableArray<Method*>* _prev_methods;
|
||||
|
||||
public:
|
||||
ActiveMethodOopsCache() { _prev_methods = NULL; }
|
||||
~ActiveMethodOopsCache();
|
||||
|
||||
void add_previous_version(Method* method);
|
||||
bool is_same_method(const Method* method) const;
|
||||
};
|
||||
|
||||
|
||||
// A helper class for caching a Method* when the user of the cache
|
||||
// only cares about the latest version of the Method*.
|
||||
//
|
||||
class LatestMethodOopCache : public CommonMethodOopCache {
|
||||
// This subclass adds a getter method for the latest Method*.
|
||||
|
||||
public:
|
||||
Method* get_Method();
|
||||
};
|
||||
|
||||
// For UseCompressedOops and UseCompressedKlassPointers.
|
||||
struct NarrowPtrStruct {
|
||||
// Base address for oop/klass-within-java-object materialization.
|
||||
|
@ -174,10 +144,10 @@ class Universe: AllStatic {
|
|||
static objArrayOop _the_empty_class_klass_array; // Canonicalized obj array of type java.lang.Class
|
||||
static oop _the_null_string; // A cache of "null" as a Java string
|
||||
static oop _the_min_jint_string; // A cache of "-2147483648" as a Java string
|
||||
static LatestMethodOopCache* _finalizer_register_cache; // static method for registering finalizable objects
|
||||
static LatestMethodOopCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector
|
||||
static LatestMethodOopCache* _pd_implies_cache; // method for checking protection domain attributes
|
||||
static ActiveMethodOopsCache* _reflect_invoke_cache; // method for security checks
|
||||
static LatestMethodCache* _finalizer_register_cache; // static method for registering finalizable objects
|
||||
static LatestMethodCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector
|
||||
static LatestMethodCache* _pd_implies_cache; // method for checking protection domain attributes
|
||||
|
||||
// preallocated error objects (no backtrace)
|
||||
static oop _out_of_memory_error_java_heap;
|
||||
static oop _out_of_memory_error_metaspace;
|
||||
|
@ -334,11 +304,11 @@ class Universe: AllStatic {
|
|||
static Array<Klass*>* the_array_interfaces_array() { return _the_array_interfaces_array; }
|
||||
static oop the_null_string() { return _the_null_string; }
|
||||
static oop the_min_jint_string() { return _the_min_jint_string; }
|
||||
static Method* finalizer_register_method() { return _finalizer_register_cache->get_Method(); }
|
||||
static Method* loader_addClass_method() { return _loader_addClass_cache->get_Method(); }
|
||||
|
||||
static Method* protection_domain_implies_method() { return _pd_implies_cache->get_Method(); }
|
||||
static ActiveMethodOopsCache* reflect_invoke_cache() { return _reflect_invoke_cache; }
|
||||
static Method* finalizer_register_method() { return _finalizer_register_cache->get_method(); }
|
||||
static Method* loader_addClass_method() { return _loader_addClass_cache->get_method(); }
|
||||
|
||||
static Method* protection_domain_implies_method() { return _pd_implies_cache->get_method(); }
|
||||
|
||||
static oop null_ptr_exception_instance() { return _null_ptr_exception_instance; }
|
||||
static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue