--- a/hotspot/src/share/vm/classfile/compactHashtable.hpp Wed Apr 06 07:55:32 2016 -0400
+++ b/hotspot/src/share/vm/classfile/compactHashtable.hpp Wed Apr 06 21:53:44 2016 -0700
@@ -270,6 +270,10 @@
// For reading from/writing to the CDS archive
void serialize(SerializeClosure* soc);
+
+ uintx base_address() {
+ return (uintx) _base_address;
+ }
};
////////////////////////////////////////////////////////////////////////
--- a/hotspot/src/share/vm/classfile/symbolTable.cpp Wed Apr 06 07:55:32 2016 -0400
+++ b/hotspot/src/share/vm/classfile/symbolTable.cpp Wed Apr 06 21:53:44 2016 -0700
@@ -238,6 +238,29 @@
}
}
+u4 SymbolTable::encode_shared(Symbol* sym) {
+ assert(DumpSharedSpaces, "called only during dump time");
+ uintx base_address = uintx(MetaspaceShared::shared_rs()->base());
+ uintx offset = uintx(sym) - base_address;
+ assert(offset < 0x7fffffff, "sanity");
+ return u4(offset);
+}
+
+Symbol* SymbolTable::decode_shared(u4 offset) {
+ assert(!DumpSharedSpaces, "called only during runtime");
+ uintx base_address = _shared_table.base_address();
+ Symbol* sym = (Symbol*)(base_address + offset);
+
+#ifndef PRODUCT
+ const char* s = (const char*)sym->bytes();
+ int len = sym->utf8_length();
+ unsigned int hash = hash_symbol(s, len);
+ assert(sym == lookup_shared(s, len, hash), "must be shared symbol");
+#endif
+
+ return sym;
+}
+
// Pick hashing algorithm.
unsigned int SymbolTable::hash_symbol(const char* s, int len) {
return use_alternate_hashcode() ?
--- a/hotspot/src/share/vm/classfile/symbolTable.hpp Wed Apr 06 07:55:32 2016 -0400
+++ b/hotspot/src/share/vm/classfile/symbolTable.hpp Wed Apr 06 21:53:44 2016 -0700
@@ -253,6 +253,8 @@
// Sharing
static void serialize(SerializeClosure* soc);
+ static u4 encode_shared(Symbol* sym);
+ static Symbol* decode_shared(u4 offset);
// Rehash the symbol table if it gets out of balance
static void rehash_table();
--- a/hotspot/src/share/vm/classfile/systemDictionaryShared.hpp Wed Apr 06 07:55:32 2016 -0400
+++ b/hotspot/src/share/vm/classfile/systemDictionaryShared.hpp Wed Apr 06 21:53:44 2016 -0700
@@ -78,7 +78,19 @@
TRAPS) {
return NULL;
}
+
static void serialize(SerializeClosure* soc) {}
+
+ // The (non-application) CDS implementation supports only classes in the boot
+ // class loader, which ensures that the verification constraints are the same
+ // during archive creation time and runtime. Thus we can do the constraint checks
+ // entirely during archive creation time.
+ static bool add_verification_constraint(Klass* k, Symbol* name,
+ Symbol* from_name, bool from_field_is_protected,
+ bool from_is_array, bool from_is_object) {return false;}
+ static void finalize_verification_constraints() {}
+ static void check_verification_constraints(instanceKlassHandle klass,
+ TRAPS) {}
};
#endif // SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
--- a/hotspot/src/share/vm/classfile/verificationType.cpp Wed Apr 06 07:55:32 2016 -0400
+++ b/hotspot/src/share/vm/classfile/verificationType.cpp Wed Apr 06 21:53:44 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "classfile/symbolTable.hpp"
+#include "classfile/systemDictionaryShared.hpp"
#include "classfile/verificationType.hpp"
#include "classfile/verifier.hpp"
@@ -41,6 +42,39 @@
}
}
+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;
+}
+
bool VerificationType::is_reference_assignable_from(
const VerificationType& from, ClassVerifier* context,
bool from_field_is_protected, TRAPS) const {
@@ -58,33 +92,17 @@
// any object or array is assignable to java.lang.Object
return true;
}
- 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());
+
+ if (DumpSharedSpaces && SystemDictionaryShared::add_verification_constraint(klass(),
+ name(), from.name(), from_field_is_protected, from.is_array(),
+ from.is_object())) {
+ // If add_verification_constraint() returns true, the resolution/check should be
+ // delayed until runtime.
+ return true;
}
- 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 resolve_and_check_assignability(klass(), name(), from.name(),
+ from_field_is_protected, from.is_array(), from.is_object(), THREAD);
} else if (is_array() && from.is_array()) {
VerificationType comp_this = get_component(context, CHECK_false);
VerificationType comp_from = from.get_component(context, CHECK_false);
--- a/hotspot/src/share/vm/classfile/verificationType.hpp Wed Apr 06 07:55:32 2016 -0400
+++ b/hotspot/src/share/vm/classfile/verificationType.hpp Wed Apr 06 21:53:44 2016 -0700
@@ -333,6 +333,12 @@
bool is_reference_assignable_from(
const VerificationType&, ClassVerifier*, bool from_field_is_protected,
TRAPS) const;
+
+ public:
+ static bool 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);
};
#endif // SHARE_VM_CLASSFILE_VERIFICATIONTYPE_HPP
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp Wed Apr 06 07:55:32 2016 -0400
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp Wed Apr 06 21:53:44 2016 -0700
@@ -806,6 +806,10 @@
exit(1);
}
}
+
+ // Copy the verification constraints from C_HEAP-alloced GrowableArrays to RO-alloced
+ // Arrays
+ SystemDictionaryShared::finalize_verification_constraints();
}
void MetaspaceShared::prepare_for_dumping() {
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Apr 06 07:55:32 2016 -0400
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Apr 06 21:53:44 2016 -0700
@@ -27,6 +27,7 @@
#include "classfile/classFileStream.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/systemDictionary.hpp"
+#include "classfile/systemDictionaryShared.hpp"
#include "classfile/verifier.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/dependencyContext.hpp"
@@ -597,6 +598,8 @@
// also sets rewritten
this_k->rewrite_class(CHECK_false);
+ } else if (this_k->is_shared()) {
+ SystemDictionaryShared::check_verification_constraints(this_k, CHECK_false);
}
// relocate jsrs and link methods after they are all rewritten