8150752: Share Class Data

Reviewed-by: acorn, hseigel, mschoene
This commit is contained in:
Ioi Lam 2016-04-06 21:53:44 -07:00
parent 99c24f5f1c
commit 2a09a3923a
8 changed files with 98 additions and 26 deletions

View File

@ -270,6 +270,10 @@ public:
// For reading from/writing to the CDS archive
void serialize(SerializeClosure* soc);
uintx base_address() {
return (uintx) _base_address;
}
};
////////////////////////////////////////////////////////////////////////

View File

@ -238,6 +238,29 @@ Symbol* SymbolTable::lookup(int index, const char* name,
}
}
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() ?

View File

@ -253,6 +253,8 @@ public:
// 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();

View File

@ -78,7 +78,19 @@ public:
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

View File

@ -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 @@ VerificationType VerificationType::from_tag(u1 tag) {
}
}
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 @@ bool VerificationType::is_reference_assignable_from(
// 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);

View File

@ -333,6 +333,12 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
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

View File

@ -806,6 +806,10 @@ void MetaspaceShared::link_and_cleanup_shared_classes(TRAPS) {
exit(1);
}
}
// Copy the verification constraints from C_HEAP-alloced GrowableArrays to RO-alloced
// Arrays
SystemDictionaryShared::finalize_verification_constraints();
}
void MetaspaceShared::prepare_for_dumping() {

View File

@ -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 @@ bool InstanceKlass::link_class_impl(
// 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