提交 83acec26 编写于 作者: D dcubed

Merge

......@@ -96,9 +96,10 @@ public class DictionaryEntry extends sun.jvm.hotspot.utilities.HashtableEntry {
public boolean containsProtectionDomain(Oop protectionDomain) {
InstanceKlass ik = (InstanceKlass) klass();
if (protectionDomain.equals(ik.getProtectionDomain())) {
return true; // Succeeds trivially
}
// Currently unimplemented and not used.
// if (protectionDomain.equals(ik.getJavaMirror().getProtectionDomain())) {
// return true; // Succeeds trivially
// }
for (ProtectionDomainEntry current = pdSet(); current != null;
current = current.next()) {
if (protectionDomain.equals(current.protectionDomain())) {
......
......@@ -75,8 +75,6 @@ public class InstanceKlass extends Klass {
javaFieldsCount = new CIntField(type.getCIntegerField("_java_fields_count"), 0);
constants = new MetadataField(type.getAddressField("_constants"), 0);
classLoaderData = type.getAddressField("_class_loader_data");
protectionDomain = new OopField(type.getOopField("_protection_domain"), 0);
signers = new OopField(type.getOopField("_signers"), 0);
sourceFileName = type.getAddressField("_source_file_name");
sourceDebugExtension = type.getAddressField("_source_debug_extension");
innerClasses = type.getAddressField("_inner_classes");
......@@ -136,8 +134,6 @@ public class InstanceKlass extends Klass {
private static CIntField javaFieldsCount;
private static MetadataField constants;
private static AddressField classLoaderData;
private static OopField protectionDomain;
private static OopField signers;
private static AddressField sourceFileName;
private static AddressField sourceDebugExtension;
private static AddressField innerClasses;
......@@ -350,8 +346,6 @@ public class InstanceKlass extends Klass {
public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); }
public ClassLoaderData getClassLoaderData() { return ClassLoaderData.instantiateWrapperFor(classLoaderData.getValue(getAddress())); }
public Oop getClassLoader() { return getClassLoaderData().getClassLoader(); }
public Oop getProtectionDomain() { return protectionDomain.getValue(this); }
public ObjArray getSigners() { return (ObjArray) signers.getValue(this); }
public Symbol getSourceFileName() { return getSymbol(sourceFileName); }
public String getSourceDebugExtension(){ return CStringUtilities.getString(sourceDebugExtension.getValue(getAddress())); }
public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); }
......@@ -541,8 +535,6 @@ public class InstanceKlass extends Klass {
// visitor.doOop(methods, true);
// visitor.doOop(localInterfaces, true);
// visitor.doOop(transitiveInterfaces, true);
visitor.doOop(protectionDomain, true);
visitor.doOop(signers, true);
visitor.doCInt(nonstaticFieldSize, true);
visitor.doCInt(staticFieldSize, true);
visitor.doCInt(staticOopFieldCount, true);
......
......@@ -204,13 +204,13 @@ public class HeapGXLWriter extends AbstractHeapGraphWriter {
Oop loader = ik.getClassLoader();
writeEdge(instance, loader, "loaded-by");
// write signers
Oop signers = ik.getSigners();
writeEdge(instance, signers, "signed-by");
// write signers NYI
// Oop signers = ik.getJavaMirror().getSigners();
writeEdge(instance, null, "signed-by");
// write protection domain
Oop protectionDomain = ik.getProtectionDomain();
writeEdge(instance, protectionDomain, "protection-domain");
// write protection domain NYI
// Oop protectionDomain = ik.getJavaMirror().getProtectionDomain();
writeEdge(instance, null, "protection-domain");
// write edges for static reference fields from this class
for (Iterator itr = refFields.iterator(); itr.hasNext();) {
......
......@@ -477,8 +477,8 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
if (k instanceof InstanceKlass) {
InstanceKlass ik = (InstanceKlass) k;
writeObjectID(ik.getClassLoader());
writeObjectID(ik.getSigners());
writeObjectID(ik.getProtectionDomain());
writeObjectID(null); // ik.getJavaMirror().getSigners());
writeObjectID(null); // ik.getJavaMirror().getProtectionDomain());
// two reserved id fields
writeObjectID(null);
writeObjectID(null);
......@@ -516,8 +516,8 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
if (bottomKlass instanceof InstanceKlass) {
InstanceKlass ik = (InstanceKlass) bottomKlass;
writeObjectID(ik.getClassLoader());
writeObjectID(ik.getSigners());
writeObjectID(ik.getProtectionDomain());
writeObjectID(null); // ik.getJavaMirror().getSigners());
writeObjectID(null); // ik.getJavaMirror().getProtectionDomain());
} else {
writeObjectID(null);
writeObjectID(null);
......
......@@ -47,8 +47,6 @@ public class JSJavaInstanceKlass extends JSJavaKlass {
private static final int FIELD_IS_SYNTHETIC = 13;
private static final int FIELD_IS_INTERFACE = 14;
private static final int FIELD_CLASS_LOADER = 15;
private static final int FIELD_PROTECTION_DOMAIN = 16;
private static final int FIELD_SIGNERS = 17;
private static final int FIELD_STATICS = 18;
private static final int FIELD_UNDEFINED = -1;
......@@ -100,10 +98,6 @@ public class JSJavaInstanceKlass extends JSJavaKlass {
return Boolean.valueOf(ik.isInterface());
case FIELD_CLASS_LOADER:
return factory.newJSJavaObject(ik.getClassLoader());
case FIELD_PROTECTION_DOMAIN:
return factory.newJSJavaObject(ik.getProtectionDomain());
case FIELD_SIGNERS:
return factory.newJSJavaObject(ik.getSigners());
case FIELD_STATICS:
return getStatics();
case FIELD_UNDEFINED:
......@@ -246,8 +240,6 @@ public class JSJavaInstanceKlass extends JSJavaKlass {
addField("isSynthetic", FIELD_IS_SYNTHETIC);
addField("isInterface", FIELD_IS_INTERFACE);
addField("classLoader", FIELD_CLASS_LOADER);
addField("protectionDomain", FIELD_PROTECTION_DOMAIN);
addField("signers", FIELD_SIGNERS);
addField("statics", FIELD_STATICS);
}
......
......@@ -444,8 +444,8 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
break;
case JVM_REF_invokeStatic:
case JVM_REF_invokeSpecial:
check_property(
tag.is_method() || tag.is_interface_method(),
check_property(tag.is_method() ||
((_major_version >= JAVA_8_VERSION) && tag.is_interface_method()),
"Invalid constant pool index %u in class file %s (not a method)",
ref_index, CHECK_(nullHandle));
break;
......@@ -4040,6 +4040,9 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
}
}
// Allocate mirror and initialize static fields
java_lang_Class::create_mirror(this_klass, protection_domain, CHECK_(nullHandle));
#ifdef ASSERT
if (ParseAllGenericSignatures) {
......@@ -4055,17 +4058,6 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
this_klass(), &all_mirandas, CHECK_(nullHandle));
}
// Allocate mirror and initialize static fields
java_lang_Class::create_mirror(this_klass, CHECK_(nullHandle));
// Allocate a simple java object for locking during class initialization.
// This needs to be a java object because it can be held across a java call.
typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_NULL);
this_klass->set_init_lock(r);
// TODO: Move these oops to the mirror
this_klass->set_protection_domain(protection_domain());
// Update the loader_data graph.
record_defined_class_dependencies(this_klass, CHECK_NULL);
......
......@@ -512,22 +512,22 @@ void java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) {
// If the offset was read from the shared archive, it was fixed up already
if (!k->is_shared()) {
if (k->oop_is_instance()) {
// During bootstrap, java.lang.Class wasn't loaded so static field
// offsets were computed without the size added it. Go back and
// update all the static field offsets to included the size.
for (JavaFieldStream fs(InstanceKlass::cast(k())); !fs.done(); fs.next()) {
if (fs.access_flags().is_static()) {
int real_offset = fs.offset() + InstanceMirrorKlass::offset_of_static_fields();
fs.set_offset(real_offset);
if (k->oop_is_instance()) {
// During bootstrap, java.lang.Class wasn't loaded so static field
// offsets were computed without the size added it. Go back and
// update all the static field offsets to included the size.
for (JavaFieldStream fs(InstanceKlass::cast(k())); !fs.done(); fs.next()) {
if (fs.access_flags().is_static()) {
int real_offset = fs.offset() + InstanceMirrorKlass::offset_of_static_fields();
fs.set_offset(real_offset);
}
}
}
}
}
create_mirror(k, CHECK);
create_mirror(k, Handle(NULL), CHECK);
}
oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
oop java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAPS) {
assert(k->java_mirror() == NULL, "should only assign mirror once");
// Use this moment of initialization to cache modifier_flags also,
// to support Class.getModifiers(). Instance classes recalculate
......@@ -563,6 +563,16 @@ oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
set_array_klass(comp_mirror(), k());
} else {
assert(k->oop_is_instance(), "Must be");
// Allocate a simple java object for a lock.
// This needs to be a java object because during class initialization
// it can be held across a java call.
typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_NULL);
set_init_lock(mirror(), r);
// Set protection domain also
set_protection_domain(mirror(), protection_domain());
// Initialize static fields
InstanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL);
}
......@@ -597,6 +607,34 @@ void java_lang_Class::set_static_oop_field_count(oop java_class, int size) {
java_class->int_field_put(_static_oop_field_count_offset, size);
}
oop java_lang_Class::protection_domain(oop java_class) {
assert(_protection_domain_offset != 0, "must be set");
return java_class->obj_field(_protection_domain_offset);
}
void java_lang_Class::set_protection_domain(oop java_class, oop pd) {
assert(_protection_domain_offset != 0, "must be set");
java_class->obj_field_put(_protection_domain_offset, pd);
}
oop java_lang_Class::init_lock(oop java_class) {
assert(_init_lock_offset != 0, "must be set");
return java_class->obj_field(_init_lock_offset);
}
void java_lang_Class::set_init_lock(oop java_class, oop init_lock) {
assert(_init_lock_offset != 0, "must be set");
java_class->obj_field_put(_init_lock_offset, init_lock);
}
objArrayOop java_lang_Class::signers(oop java_class) {
assert(_signers_offset != 0, "must be set");
return (objArrayOop)java_class->obj_field(_signers_offset);
}
void java_lang_Class::set_signers(oop java_class, objArrayOop signers) {
assert(_signers_offset != 0, "must be set");
java_class->obj_field_put(_signers_offset, (oop)signers);
}
oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
// This should be improved by adding a field at the Java level or by
// introducing a new VM klass (see comment in ClassFileParser)
......@@ -2934,6 +2972,9 @@ int java_lang_Class::_klass_offset;
int java_lang_Class::_array_klass_offset;
int java_lang_Class::_oop_size_offset;
int java_lang_Class::_static_oop_field_count_offset;
int java_lang_Class::_protection_domain_offset;
int java_lang_Class::_init_lock_offset;
int java_lang_Class::_signers_offset;
GrowableArray<Klass*>* java_lang_Class::_fixup_mirror_list = NULL;
int java_lang_Throwable::backtrace_offset;
int java_lang_Throwable::detailMessage_offset;
......
......@@ -208,7 +208,10 @@ class java_lang_String : AllStatic {
macro(java_lang_Class, klass, intptr_signature, false) \
macro(java_lang_Class, array_klass, intptr_signature, false) \
macro(java_lang_Class, oop_size, int_signature, false) \
macro(java_lang_Class, static_oop_field_count, int_signature, false)
macro(java_lang_Class, static_oop_field_count, int_signature, false) \
macro(java_lang_Class, protection_domain, object_signature, false) \
macro(java_lang_Class, init_lock, object_signature, false) \
macro(java_lang_Class, signers, object_signature, false)
class java_lang_Class : AllStatic {
friend class VMStructs;
......@@ -222,15 +225,20 @@ class java_lang_Class : AllStatic {
static int _oop_size_offset;
static int _static_oop_field_count_offset;
static int _protection_domain_offset;
static int _init_lock_offset;
static int _signers_offset;
static bool offsets_computed;
static int classRedefinedCount_offset;
static GrowableArray<Klass*>* _fixup_mirror_list;
static void set_init_lock(oop java_class, oop init_lock);
public:
static void compute_offsets();
// Instance creation
static oop create_mirror(KlassHandle k, TRAPS);
static oop create_mirror(KlassHandle k, Handle protection_domain, TRAPS);
static void fixup_mirror(KlassHandle k, TRAPS);
static oop create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);
// Conversion
......@@ -262,6 +270,13 @@ class java_lang_Class : AllStatic {
static int classRedefinedCount(oop the_class_mirror);
static void set_classRedefinedCount(oop the_class_mirror, int value);
// Support for embedded per-class oops
static oop protection_domain(oop java_class);
static void set_protection_domain(oop java_class, oop protection_domain);
static oop init_lock(oop java_class);
static objArrayOop signers(oop java_class);
static void set_signers(oop java_class, objArrayOop signers);
static int oop_size(oop java_class);
static void set_oop_size(oop java_class, int size);
static int static_oop_field_count(oop java_class);
......
......@@ -392,6 +392,9 @@
template(array_klass_name, "array_klass") \
template(oop_size_name, "oop_size") \
template(static_oop_field_count_name, "static_oop_field_count") \
template(protection_domain_name, "protection_domain") \
template(init_lock_name, "init_lock") \
template(signers_name, "signers_name") \
template(loader_data_name, "loader_data") \
template(dependencies_name, "dependencies") \
\
......
......@@ -94,7 +94,7 @@ void ArrayKlass::complete_create_array_klass(ArrayKlass* k, KlassHandle super_kl
ResourceMark rm(THREAD);
k->initialize_supers(super_klass(), CHECK);
k->vtable()->initialize_vtable(false, CHECK);
java_lang_Class::create_mirror(k, CHECK);
java_lang_Class::create_mirror(k, Handle(NULL), CHECK);
}
GrowableArray<Klass*>* ArrayKlass::compute_secondary_supers(int num_extra_slots) {
......
......@@ -268,8 +268,6 @@ InstanceKlass::InstanceKlass(int vtable_len,
set_fields(NULL, 0);
set_constants(NULL);
set_class_loader_data(NULL);
set_protection_domain(NULL);
set_signers(NULL);
set_source_file_name(NULL);
set_source_debug_extension(NULL, 0);
set_array_name(NULL);
......@@ -279,7 +277,6 @@ InstanceKlass::InstanceKlass(int vtable_len,
set_is_marked_dependent(false);
set_init_state(InstanceKlass::allocated);
set_init_thread(NULL);
set_init_lock(NULL);
set_reference_type(rt);
set_oop_map_cache(NULL);
set_jni_ids(NULL);
......@@ -408,12 +405,6 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
}
set_inner_classes(NULL);
// Null out Java heap objects, although these won't be walked to keep
// alive once this InstanceKlass is deallocated.
set_protection_domain(NULL);
set_signers(NULL);
set_init_lock(NULL);
// We should deallocate the Annotations instance
MetadataFactory::free_metadata(loader_data, annotations());
set_annotations(NULL);
......@@ -451,6 +442,24 @@ void InstanceKlass::eager_initialize(Thread *thread) {
}
}
// JVMTI spec thinks there are signers and protection domain in the
// instanceKlass. These accessors pretend these fields are there.
// The hprof specification also thinks these fields are in InstanceKlass.
oop InstanceKlass::protection_domain() const {
// return the protection_domain from the mirror
return java_lang_Class::protection_domain(java_mirror());
}
// To remove these from requires an incompatible change and CCC request.
objArrayOop InstanceKlass::signers() const {
// return the signers from the mirror
return java_lang_Class::signers(java_mirror());
}
volatile oop InstanceKlass::init_lock() const {
// return the init lock from the mirror
return java_lang_Class::init_lock(java_mirror());
}
void InstanceKlass::eager_initialize_impl(instanceKlassHandle this_oop) {
EXCEPTION_MARK;
......@@ -1883,16 +1892,6 @@ bool InstanceKlass::is_dependent_nmethod(nmethod* nm) {
// Garbage collection
void InstanceKlass::oops_do(OopClosure* cl) {
Klass::oops_do(cl);
cl->do_oop(adr_protection_domain());
cl->do_oop(adr_signers());
cl->do_oop(adr_init_lock());
// Don't walk the arrays since they are walked from the ClassLoaderData objects.
}
#ifdef ASSERT
template <class T> void assert_is_in(T *p) {
T heap_oop = oopDesc::load_heap_oop(p);
......@@ -2241,9 +2240,6 @@ void InstanceKlass::remove_unshareable_info() {
m->remove_unshareable_info();
}
// Need to reinstate when reading back the class.
set_init_lock(NULL);
// do array classes also.
array_klasses_do(remove_unshareable_in_class);
}
......@@ -2275,13 +2271,6 @@ void InstanceKlass::restore_unshareable_info(TRAPS) {
ik->itable()->initialize_itable(false, CHECK);
}
// Allocate a simple java object for a lock.
// This needs to be a java object because during class initialization
// it can be held across a java call.
typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK);
Handle h(THREAD, (oop)r);
ik->set_init_lock(h());
// restore constant pool resolved references
ik->constants()->restore_unshareable_info(CHECK);
......@@ -2765,15 +2754,28 @@ nmethod* InstanceKlass::lookup_osr_nmethod(const Method* m, int bci, int comp_le
return NULL;
}
void InstanceKlass::add_member_name(Handle mem_name) {
void InstanceKlass::add_member_name(int index, Handle mem_name) {
jweak mem_name_wref = JNIHandles::make_weak_global(mem_name);
MutexLocker ml(MemberNameTable_lock);
assert(0 <= index && index < idnum_allocated_count(), "index is out of bounds");
DEBUG_ONLY(No_Safepoint_Verifier nsv);
if (_member_names == NULL) {
_member_names = new (ResourceObj::C_HEAP, mtClass) MemberNameTable();
_member_names = new (ResourceObj::C_HEAP, mtClass) MemberNameTable(idnum_allocated_count());
}
_member_names->add_member_name(mem_name_wref);
_member_names->add_member_name(index, mem_name_wref);
}
oop InstanceKlass::get_member_name(int index) {
MutexLocker ml(MemberNameTable_lock);
assert(0 <= index && index < idnum_allocated_count(), "index is out of bounds");
DEBUG_ONLY(No_Safepoint_Verifier nsv);
if (_member_names == NULL) {
return NULL;
}
oop mem_name =_member_names->get_member_name(index);
return mem_name;
}
// -----------------------------------------------------------------------------------------------------
......@@ -2836,10 +2838,7 @@ void InstanceKlass::print_on(outputStream* st) const {
class_loader_data()->print_value_on(st);
st->cr();
}
st->print(BULLET"protection domain: "); ((InstanceKlass*)this)->protection_domain()->print_value_on(st); st->cr();
st->print(BULLET"host class: "); host_klass()->print_value_on_maybe_null(st); st->cr();
st->print(BULLET"signers: "); signers()->print_value_on(st); st->cr();
st->print(BULLET"init_lock: "); ((oop)_init_lock)->print_value_on(st); st->cr();
if (source_file_name() != NULL) {
st->print(BULLET"source file: ");
source_file_name()->print_value_on(st);
......@@ -3040,7 +3039,6 @@ void InstanceKlass::collect_statistics(KlassSizeStats *sz) const {
n += (sz->_method_ordering_bytes = sz->count_array(method_ordering()));
n += (sz->_local_interfaces_bytes = sz->count_array(local_interfaces()));
n += (sz->_transitive_interfaces_bytes = sz->count_array(transitive_interfaces()));
n += (sz->_signers_bytes = sz->count_array(signers()));
n += (sz->_fields_bytes = sz->count_array(fields()));
n += (sz->_inner_classes_bytes = sz->count_array(inner_classes()));
sz->_ro_bytes += n;
......@@ -3206,17 +3204,11 @@ void InstanceKlass::verify_on(outputStream* st) {
guarantee(constants()->is_metadata(), "should be in metaspace");
guarantee(constants()->is_constantPool(), "should be constant pool");
}
if (protection_domain() != NULL) {
guarantee(protection_domain()->is_oop(), "should be oop");
}
const Klass* host = host_klass();
if (host != NULL) {
guarantee(host->is_metadata(), "should be in metaspace");
guarantee(host->is_klass(), "should be klass");
}
if (signers() != NULL) {
guarantee(signers()->is_objArray(), "should be obj array");
}
}
void InstanceKlass::oop_verify_on(oop obj, outputStream* st) {
......
......@@ -58,8 +58,6 @@
// [fields ]
// [constants ]
// [class loader ]
// [protection domain ]
// [signers ]
// [source file name ]
// [inner classes ]
// [static field size ]
......@@ -180,16 +178,6 @@ class InstanceKlass: public Klass {
static volatile int _total_instanceKlass_count;
protected:
// Protection domain.
oop _protection_domain;
// Class signers.
objArrayOop _signers;
// Lock for (1) initialization; (2) access to the ConstantPool of this class.
// Must be one per class and it has to be a VM internal object so java code
// cannot lock it (like the mirror).
// It has to be an object not a Mutex because it's held through java calls.
volatile oop _init_lock;
// Annotations for this class
Annotations* _annotations;
// Array classes holding elements of this class.
......@@ -527,8 +515,10 @@ class InstanceKlass: public Klass {
void set_constants(ConstantPool* c) { _constants = c; }
// protection domain
oop protection_domain() { return _protection_domain; }
void set_protection_domain(oop pd) { klass_oop_store(&_protection_domain, pd); }
oop protection_domain() const;
// signers
objArrayOop signers() const;
// host class
Klass* host_klass() const {
......@@ -575,10 +565,6 @@ class InstanceKlass: public Klass {
}
}
// signers
objArrayOop signers() const { return _signers; }
void set_signers(objArrayOop s) { klass_oop_store((oop*)&_signers, s); }
// source file name
Symbol* source_file_name() const { return _source_file_name; }
void set_source_file_name(Symbol* n);
......@@ -912,8 +898,6 @@ class InstanceKlass: public Klass {
Method* method_at_itable(Klass* holder, int index, TRAPS);
// Garbage collection
virtual void oops_do(OopClosure* cl);
void oop_follow_contents(oop obj);
int oop_adjust_pointers(oop obj);
......@@ -999,14 +983,12 @@ private:
// Lock during initialization
public:
volatile oop init_lock() const {return _init_lock; }
// Lock for (1) initialization; (2) access to the ConstantPool of this class.
// Must be one per class and it has to be a VM internal object so java code
// cannot lock it (like the mirror).
// It has to be an object not a Mutex because it's held through java calls.
volatile oop init_lock() const;
private:
void set_init_lock(oop value) { klass_oop_store(&_init_lock, value); }
// Offsets for memory management
oop* adr_protection_domain() const { return (oop*)&this->_protection_domain;}
oop* adr_signers() const { return (oop*)&this->_signers;}
oop* adr_init_lock() const { return (oop*)&this->_init_lock;}
// Static methods that are used to implement member methods where an exposed this pointer
// is needed due to possible GCs
......@@ -1040,7 +1022,8 @@ public:
// JSR-292 support
MemberNameTable* member_names() { return _member_names; }
void set_member_names(MemberNameTable* member_names) { _member_names = member_names; }
void add_member_name(Handle member_name);
void add_member_name(int index, Handle member_name);
oop get_member_name(int index);
public:
// JVMTI support
......
......@@ -511,8 +511,9 @@ void Klass::restore_unshareable_info(TRAPS) {
// (same order as class file parsing)
loader_data->add_class(this);
// Recreate the class mirror
java_lang_Class::create_mirror(this, CHECK);
// Recreate the class mirror. The protection_domain is always null for
// boot loader, for now.
java_lang_Class::create_mirror(this, Handle(NULL), CHECK);
}
Klass* Klass::array_klass_or_null(int rank) {
......
......@@ -445,7 +445,7 @@ class Klass : public Metadata {
Klass* array_klass_or_null(int rank);
Klass* array_klass_or_null();
virtual oop protection_domain() { return NULL; }
virtual oop protection_domain() const = 0;
oop class_loader() const;
......
......@@ -75,7 +75,7 @@ class ObjArrayKlass : public ArrayKlass {
void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS);
// Compute protection domain
oop protection_domain() { return bottom_klass()->protection_domain(); }
oop protection_domain() const { return bottom_klass()->protection_domain(); }
private:
// Either oop or narrowOop depending on UseCompressedOops.
......
......@@ -67,6 +67,8 @@ class TypeArrayKlass : public ArrayKlass {
typeArrayOop allocate(int length, TRAPS) { return allocate_common(length, true, THREAD); }
oop multi_allocate(int rank, jint* sizes, TRAPS);
oop protection_domain() const { return NULL; }
// Copying
void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS);
......
......@@ -1072,11 +1072,7 @@ JVM_ENTRY(jobjectArray, JVM_GetClassSigners(JNIEnv *env, jclass cls))
return NULL;
}
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
objArrayOop signers = NULL;
if (k->oop_is_instance()) {
signers = InstanceKlass::cast(k)->signers();
}
objArrayOop signers = java_lang_Class::signers(JNIHandles::resolve_non_null(cls));
// If there are no signers set in the class, or if the class
// is an array, return NULL.
......@@ -1102,7 +1098,7 @@ JVM_ENTRY(void, JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signer
// be called with an array. Only the bootstrap loader creates arrays.
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
if (k->oop_is_instance()) {
InstanceKlass::cast(k)->set_signers(objArrayOop(JNIHandles::resolve(signers)));
java_lang_Class::set_signers(k->java_mirror(), objArrayOop(JNIHandles::resolve(signers)));
}
}
JVM_END
......@@ -1119,8 +1115,8 @@ JVM_ENTRY(jobject, JVM_GetProtectionDomain(JNIEnv *env, jclass cls))
return NULL;
}
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
return (jobject) JNIHandles::make_local(env, k->protection_domain());
oop pd = java_lang_Class::protection_domain(JNIHandles::resolve(cls));
return (jobject) JNIHandles::make_local(env, pd);
JVM_END
......@@ -1139,7 +1135,7 @@ JVM_ENTRY(void, JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protect
if (k->oop_is_instance()) {
oop pd = JNIHandles::resolve(protection_domain);
assert(pd == NULL || pd->is_oop(), "just checking");
InstanceKlass::cast(k)->set_protection_domain(pd);
java_lang_Class::set_protection_domain(k->java_mirror(), pd);
}
}
JVM_END
......
/*
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -232,7 +232,8 @@ oop MethodHandles::init_method_MemberName(Handle mname, Method* m, bool do_dispa
// This is done eagerly, since it is readily available without
// constructing any new objects.
// TO DO: maybe intern mname_oop
m->method_holder()->add_member_name(mname);
m->method_holder()->add_member_name(m->method_idnum(), mname);
return mname();
}
......@@ -301,7 +302,6 @@ oop MethodHandles::init_field_MemberName(Handle mname, KlassHandle field_holder,
// Although the fieldDescriptor::_index would also identify the field,
// we do not use it, because it is harder to decode.
// TO DO: maybe intern mname_oop
InstanceKlass::cast(field_holder())->add_member_name(mname);
return mname();
}
......@@ -943,7 +943,8 @@ int MethodHandles::find_MemberNames(KlassHandle k,
// MemberNameTable
//
MemberNameTable::MemberNameTable() : GrowableArray<jweak>(10, true) {
MemberNameTable::MemberNameTable(int methods_cnt)
: GrowableArray<jweak>(methods_cnt, true) {
assert_locked_or_safepoint(MemberNameTable_lock);
}
......@@ -957,29 +958,18 @@ MemberNameTable::~MemberNameTable() {
}
}
// Return entry index if found, return -1 otherwise.
int MemberNameTable::find_member_name(oop mem_name) {
void MemberNameTable::add_member_name(int index, jweak mem_name_wref) {
assert_locked_or_safepoint(MemberNameTable_lock);
int len = this->length();
for (int idx = 0; idx < len; idx++) {
jweak ref = this->at(idx);
oop entry = JNIHandles::resolve(ref);
if (entry == mem_name) {
return idx;
}
}
return -1;
this->at_put_grow(index, mem_name_wref);
}
void MemberNameTable::add_member_name(jweak mem_name_wref) {
// Return a member name oop or NULL.
oop MemberNameTable::get_member_name(int index) {
assert_locked_or_safepoint(MemberNameTable_lock);
oop mem_name = JNIHandles::resolve(mem_name_wref);
// Each member name may appear just once: add only if not found
if (find_member_name(mem_name) == -1) {
this->append(mem_name_wref);
}
jweak ref = this->at(index);
oop mem_name = JNIHandles::resolve(ref);
return mem_name;
}
#if INCLUDE_JVMTI
......
/*
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -219,7 +219,6 @@ public:
}
};
//------------------------------------------------------------------------------
// MethodHandlesAdapterGenerator
//
......@@ -233,13 +232,13 @@ public:
//------------------------------------------------------------------------------
// MemberNameTable
//
class MemberNameTable : public GrowableArray<jweak> {
public:
MemberNameTable();
MemberNameTable(int methods_cnt);
~MemberNameTable();
void add_member_name(jweak mem_name_ref);
private:
int find_member_name(oop mem_name);
void add_member_name(int index, jweak mem_name_ref);
oop get_member_name(int index);
#if INCLUDE_JVMTI
public:
......
......@@ -37,6 +37,7 @@
#include "runtime/os.hpp"
#include "utilities/debug.hpp"
#include "utilities/macros.hpp"
#include "utilities/exceptions.hpp"
#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/concurrentMark.hpp"
......@@ -330,8 +331,18 @@ WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o))
WB_END
WB_ENTRY(jlong, WB_ReserveMemory(JNIEnv* env, jobject o, jlong size))
return (jlong)os::reserve_memory(size, NULL, 0);
WB_ENTRY(void, WB_ReadReservedMemory(JNIEnv* env, jobject o))
// static+volatile in order to force the read to happen
// (not be eliminated by the compiler)
static char c;
static volatile char* p;
p = os::reserve_memory(os::vm_allocation_granularity(), NULL, 0);
if (p == NULL) {
THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "Failed to reserve memory");
}
c = *p;
WB_END
//Some convenience methods to deal with objects from java
......@@ -437,7 +448,7 @@ static JNINativeMethod methods[] = {
{CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable },
{CC"fullGC", CC"()V", (void*)&WB_FullGC },
{CC"reserveMemory", CC"(J)J", (void*)&WB_ReserveMemory },
{CC"readReservedMemory", CC"()V", (void*)&WB_ReadReservedMemory },
};
#undef CC
......
......@@ -292,10 +292,8 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
nonstatic_field(InstanceKlass, _transitive_interfaces, Array<Klass*>*) \
nonstatic_field(InstanceKlass, _fields, Array<u2>*) \
nonstatic_field(InstanceKlass, _java_fields_count, u2) \
nonstatic_field(InstanceKlass, _constants, ConstantPool*) \
nonstatic_field(InstanceKlass, _constants, ConstantPool*) \
nonstatic_field(InstanceKlass, _class_loader_data, ClassLoaderData*) \
nonstatic_field(InstanceKlass, _protection_domain, oop) \
nonstatic_field(InstanceKlass, _signers, objArrayOop) \
nonstatic_field(InstanceKlass, _source_file_name, Symbol*) \
nonstatic_field(InstanceKlass, _source_debug_extension, char*) \
nonstatic_field(InstanceKlass, _inner_classes, Array<jushort>*) \
......
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @library /runtime/testlibrary
* @build GeneratedClassLoader
* @run main/othervm/timeout=200 FragmentMetaspace
*/
import java.io.IOException;
/**
* Test that tries to fragment the native memory used by class loaders.
* This test creates class loaders that load classes of increasing size for every
* iteration. By increasing the size of the class meta data needed for every iteration
* we stress the subsystem for allocating native memory for meta data.
*/
public class FragmentMetaspace {
public static void main(String... args) {
runGrowing(Long.valueOf(System.getProperty("time", "80000")));
// try to clean up and unload classes to decrease
// class verification time in debug vm
System.gc();
}
private static void runGrowing(long time) {
long startTime = System.currentTimeMillis();
for (int i = 0; System.currentTimeMillis() < startTime + time; ++i) {
try {
GeneratedClassLoader gcl = new GeneratedClassLoader();
Class<?> c = gcl.getGeneratedClasses(i, 100)[0];
c.newInstance();
c = null;
gcl = null;
} catch (IOException|InstantiationException|IllegalAccessException ex) {
throw new RuntimeException(ex);
}
}
}
}
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @library /runtime/testlibrary
* @library classes
* @build test.Empty ClassUnloadCommon
* @run main/othervm/timeout=200 FragmentMetaspaceSimple
*/
import java.util.ArrayList;
/**
* Test that tries to fragment the native memory used by class loaders.
* Keeps every other class loader alive in order to fragment the memory space
* used to store classes and meta data. Since the memory is probably allocated in
* chunks per class loader this will cause a lot of fragmentation if not handled
* properly since every other chunk will be unused.
*/
public class FragmentMetaspaceSimple {
public static void main(String... args) {
runSimple(Long.valueOf(System.getProperty("time", "80000")));
System.gc();
}
private static void runSimple(long time) {
long startTime = System.currentTimeMillis();
ArrayList<ClassLoader> cls = new ArrayList<>();
for (int i = 0; System.currentTimeMillis() < startTime + time; ++i) {
ClassLoader ldr = ClassUnloadCommon.newClassLoader();
if (i % 1000 == 0) {
cls.clear();
}
// only keep every other class loader alive
if (i % 2 == 1) {
cls.add(ldr);
}
Class<?> c = null;
try {
c = ldr.loadClass("test.Empty");
} catch (ClassNotFoundException ex) {
throw new RuntimeException(ex);
}
c = null;
}
cls = null;
}
}
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package test;
public class Empty {
public String toString() { return "nothing"; }
}
......@@ -34,29 +34,20 @@
import com.oracle.java.testlibrary.*;
import java.lang.reflect.Field;
import sun.hotspot.WhiteBox;
import sun.misc.Unsafe;
public class ReserveMemory {
private static Unsafe getUnsafe() throws Exception {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
return (Unsafe)f.get(null);
}
private static boolean isWindows() {
return System.getProperty("os.name").toLowerCase().startsWith("win");
}
private static boolean isOsx() {
return System.getProperty("os.name").toLowerCase().startsWith("mac");
}
public static void main(String args[]) throws Exception {
if (args.length > 0) {
long address = WhiteBox.getWhiteBox().reserveMemory(4096);
System.out.println("Reserved memory at address: 0x" + Long.toHexString(address));
System.out.println("Will now read from the address, expecting a crash!");
int x = getUnsafe().getInt(address);
WhiteBox.getWhiteBox().readReservedMemory();
throw new Exception("Read of reserved/uncommitted memory unexpectedly succeeded, expected crash!");
}
......@@ -71,6 +62,8 @@ public class ReserveMemory {
OutputAnalyzer output = new OutputAnalyzer(pb.start());
if (isWindows()) {
output.shouldContain("EXCEPTION_ACCESS_VIOLATION");
} else if (isOsx()) {
output.shouldContain("SIGBUS");
} else {
output.shouldContain("SIGSEGV");
}
......
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
/**
* A class loader that generates new classes.
* The generated classes are made by first emitting java sources with nested
* static classes, these are then compiled and the class files are read back.
* Some efforts are made to make the class instances unique and of not insignificant
* size.
*/
public class GeneratedClassLoader extends ClassLoader {
/**
* Holds a pair of class bytecodes and class name (for use with defineClass).
*/
private static class GeneratedClass {
public byte[] bytes;
public String name;
public GeneratedClass(byte[] bytes, String name) {
this.bytes = bytes; this.name = name;
}
}
/**
* Used to uniquely name every class generated.
*/
private static int count = 0;
/**
* Used to enable/disable keeping the class files and java sources for
* the generated classes.
*/
private static boolean deleteFiles = Boolean.parseBoolean(
System.getProperty("GeneratedClassLoader.deleteFiles", "true"));
private static String bigstr =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
+ "In facilisis scelerisque vehicula. Donec congue nisi a "
+ "leo posuere placerat lobortis felis ultrices. Pellentesque "
+ "habitant morbi tristique senectus et netus et malesuada "
+ "fames ac turpis egestas. Nam tristique velit at felis "
+ "iaculis at tempor sem vestibulum. Sed adipiscing lectus "
+ "non mi molestie sagittis. Morbi eu purus urna. Nam tempor "
+ "tristique massa eget semper. Mauris cursus, nulla et ornare "
+ "vehicula, leo dolor scelerisque metus, sit amet rutrum erat "
+ "sapien quis dui. Nullam eleifend risus et velit accumsan sed "
+ "suscipit felis pulvinar. Nullam faucibus suscipit gravida. "
+ "Pellentesque habitant morbi tristique senectus et netus et "
+ "malesuada fames ac turpis egestas. Nullam ut massa augue, "
+ "nec viverra mauris.";
private static int getNextCount() {
return count++;
}
////// end statics
private JavaCompiler javac;
private String nameBase;
public GeneratedClassLoader() {
javac = ToolProvider.getSystemJavaCompiler();
nameBase = "TestSimpleClass";
}
private long getBigValue(int which) {
// > 65536 is too large to encode in the bytecode
// so this will force us to emit a constant pool entry for this int
return (long)which + 65537;
}
private String getBigString(int which) {
return bigstr + which;
}
private String getClassName(int count) {
return nameBase + count;
}
private String generateSource(int count, int sizeFactor, int numClasses) {
StringBuilder sb = new StringBuilder();
sb.append("public class ").append(getClassName(count)).append("{\n");
for (int j = 0; j < numClasses; ++j) {
sb.append("public static class ")
.append("Class")
.append(j)
.append("{\n");
for (int i = 0; i < sizeFactor; ++i) {
int value = i;
sb.append("private long field")
.append(i).append(" = ")
.append(getBigValue(value++))
.append(";\n");
sb.append("public long method")
.append(i)
.append("() {\n");
sb.append("return ")
.append(getBigValue(value++))
.append(";");
sb.append("}\n");
sb.append("private String str").append(i)
.append(" = \"")
.append(getBigString(i))
.append("\";");
}
sb.append("\n}");
}
sb.append("\n}");
return sb.toString();
}
private GeneratedClass[] getGeneratedClass(int sizeFactor, int numClasses) throws IOException {
int uniqueCount = getNextCount();
String src = generateSource(uniqueCount, sizeFactor, numClasses);
String className = getClassName(uniqueCount);
File file = new File(className + ".java");
try (PrintWriter pw = new PrintWriter(new FileWriter(file))) {
pw.append(src);
pw.flush();
}
int exitcode = javac.run(null, null, null, file.getCanonicalPath());
if (exitcode != 0) {
throw new RuntimeException("javac failure when compiling: " +
file.getCanonicalPath());
} else {
if (deleteFiles) {
file.delete();
}
}
GeneratedClass[] gc = new GeneratedClass[numClasses];
for (int i = 0; i < numClasses; ++i) {
String name = className + "$" + "Class" + i;
File classFile = new File(name + ".class");
byte[] bytes;
try (DataInputStream dis = new DataInputStream(new FileInputStream(classFile))) {
bytes = new byte[dis.available()];
dis.readFully(bytes);
}
if (deleteFiles) {
classFile.delete();
}
gc[i] = new GeneratedClass(bytes, name);
}
if (deleteFiles) {
new File(className + ".class").delete();
}
return gc;
}
/**
* Generate a single class, compile it and load it.
* @param sizeFactor Fuzzy measure of how large the class should be.
* @return the Class instance.
* @throws IOException
*/
public Class<?> generateClass(int sizeFactor) throws IOException {
return getGeneratedClasses(sizeFactor, 1)[0];
}
/**
* Generate several classes, compile and load them.
* @param sizeFactor Fuzzy measure of how large each class should be.
* @param numClasses The number of classes to create
* @return an array of the Class instances.
* @throws IOException
*/
public Class<?>[] getGeneratedClasses(int sizeFactor, int numClasses) throws IOException {
GeneratedClass[] gc = getGeneratedClass(sizeFactor, numClasses);
Class<?>[] classes = new Class[numClasses];
for (int i = 0; i < numClasses; ++i) {
classes[i] = defineClass(gc[i].name, gc[i].bytes, 0 , gc[i].bytes.length);
}
return classes;
}
}
......@@ -115,7 +115,7 @@ public class WhiteBox {
public native boolean isInStringTable(String str);
// Memory
public native long reserveMemory(long size);
public native void readReservedMemory();
// force Full GC
public native void fullGC();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册