mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-19 18:44:38 +02:00
8058093: Test nsk/stress/jck60/jck60014: assert in src/share/vm/oops/constantPool.cpp: should not be resolved otherwise
8044209: nsk/split_verifier/security/coglio06 fails with exit code 97 - missing 'prohibited package name' Fix resolution error saving. Reviewed-by: lfoltan, sspitsyn, hseigel, ctornqvi
This commit is contained in:
parent
ee1de3ce2f
commit
63080521d7
3 changed files with 41 additions and 21 deletions
|
@ -206,7 +206,8 @@ void ConstantPool::trace_class_resolution(constantPoolHandle this_cp, KlassHandl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Klass* ConstantPool::klass_at_impl(constantPoolHandle this_cp, int which, TRAPS) {
|
Klass* ConstantPool::klass_at_impl(constantPoolHandle this_cp, int which,
|
||||||
|
bool save_resolution_error, TRAPS) {
|
||||||
assert(THREAD->is_Java_thread(), "must be a Java thread");
|
assert(THREAD->is_Java_thread(), "must be a Java thread");
|
||||||
|
|
||||||
// A resolved constantPool entry will contain a Klass*, otherwise a Symbol*.
|
// A resolved constantPool entry will contain a Klass*, otherwise a Symbol*.
|
||||||
|
@ -249,7 +250,18 @@ Klass* ConstantPool::klass_at_impl(constantPoolHandle this_cp, int which, TRAPS)
|
||||||
// Failed to resolve class. We must record the errors so that subsequent attempts
|
// Failed to resolve class. We must record the errors so that subsequent attempts
|
||||||
// to resolve this constant pool entry fail with the same error (JVMS 5.4.3).
|
// to resolve this constant pool entry fail with the same error (JVMS 5.4.3).
|
||||||
if (HAS_PENDING_EXCEPTION) {
|
if (HAS_PENDING_EXCEPTION) {
|
||||||
save_and_throw_exception(this_cp, which, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_0);
|
if (save_resolution_error) {
|
||||||
|
save_and_throw_exception(this_cp, which, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_NULL);
|
||||||
|
// If CHECK_NULL above doesn't return the exception, that means that
|
||||||
|
// some other thread has beaten us and has resolved the class.
|
||||||
|
// To preserve old behavior, we return the resolved class.
|
||||||
|
entry = this_cp->resolved_klass_at(which);
|
||||||
|
assert(entry.is_resolved(), "must be resolved if exception was cleared");
|
||||||
|
assert(entry.get_klass()->is_klass(), "must be resolved to a klass");
|
||||||
|
return entry.get_klass();
|
||||||
|
} else {
|
||||||
|
return NULL; // return the pending exception
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make this class loader depend upon the class loader owning the class reference
|
// Make this class loader depend upon the class loader owning the class reference
|
||||||
|
@ -573,24 +585,25 @@ void ConstantPool::save_and_throw_exception(constantPoolHandle this_cp, int whic
|
||||||
Symbol* message = exception_message(this_cp, which, tag, PENDING_EXCEPTION);
|
Symbol* message = exception_message(this_cp, which, tag, PENDING_EXCEPTION);
|
||||||
SystemDictionary::add_resolution_error(this_cp, which, error, message);
|
SystemDictionary::add_resolution_error(this_cp, which, error, message);
|
||||||
// CAS in the tag. If a thread beat us to registering this error that's fine.
|
// CAS in the tag. If a thread beat us to registering this error that's fine.
|
||||||
// If another thread resolved the reference, this is an error. The resolution
|
// If another thread resolved the reference, this is a race condition. This
|
||||||
// must deterministically get an error. So why do we save this?
|
// thread may have had a security manager or something temporary.
|
||||||
// We save this because jvmti can add classes to the bootclass path after this
|
// This doesn't deterministically get an error. So why do we save this?
|
||||||
// error, so it needs to get the same error if the error is first.
|
// We save this because jvmti can add classes to the bootclass path after
|
||||||
|
// this error, so it needs to get the same error if the error is first.
|
||||||
jbyte old_tag = Atomic::cmpxchg((jbyte)error_tag,
|
jbyte old_tag = Atomic::cmpxchg((jbyte)error_tag,
|
||||||
(jbyte*)this_cp->tag_addr_at(which), (jbyte)tag.value());
|
(jbyte*)this_cp->tag_addr_at(which), (jbyte)tag.value());
|
||||||
assert(old_tag == error_tag || old_tag == tag.value(), "should not be resolved otherwise");
|
if (old_tag != error_tag && old_tag != tag.value()) {
|
||||||
|
// MethodHandles and MethodType doesn't change to resolved version.
|
||||||
|
assert(this_cp->tag_at(which).is_klass(), "Wrong tag value");
|
||||||
|
// Forget the exception and use the resolved class.
|
||||||
|
CLEAR_PENDING_EXCEPTION;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// some other thread put this in error state
|
// some other thread put this in error state
|
||||||
throw_resolution_error(this_cp, which, CHECK);
|
throw_resolution_error(this_cp, which, CHECK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This exits with some pending exception
|
|
||||||
assert(HAS_PENDING_EXCEPTION, "should not be cleared");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Called to resolve constants in the constant pool and return an oop.
|
// Called to resolve constants in the constant pool and return an oop.
|
||||||
// Some constant pool entries cache their resolved oop. This is also
|
// Some constant pool entries cache their resolved oop. This is also
|
||||||
// called to create oops from constants to use in arguments for invokedynamic
|
// called to create oops from constants to use in arguments for invokedynamic
|
||||||
|
@ -627,7 +640,7 @@ oop ConstantPool::resolve_constant_at_impl(constantPoolHandle this_cp, int index
|
||||||
case JVM_CONSTANT_Class:
|
case JVM_CONSTANT_Class:
|
||||||
{
|
{
|
||||||
assert(cache_index == _no_index_sentinel, "should not have been set");
|
assert(cache_index == _no_index_sentinel, "should not have been set");
|
||||||
Klass* resolved = klass_at_impl(this_cp, index, CHECK_NULL);
|
Klass* resolved = klass_at_impl(this_cp, index, true, CHECK_NULL);
|
||||||
// ldc wants the java mirror.
|
// ldc wants the java mirror.
|
||||||
result_oop = resolved->java_mirror();
|
result_oop = resolved->java_mirror();
|
||||||
break;
|
break;
|
||||||
|
@ -660,7 +673,7 @@ oop ConstantPool::resolve_constant_at_impl(constantPoolHandle this_cp, int index
|
||||||
ref_kind, index, this_cp->method_handle_index_at(index),
|
ref_kind, index, this_cp->method_handle_index_at(index),
|
||||||
callee_index, name->as_C_string(), signature->as_C_string());
|
callee_index, name->as_C_string(), signature->as_C_string());
|
||||||
KlassHandle callee;
|
KlassHandle callee;
|
||||||
{ Klass* k = klass_at_impl(this_cp, callee_index, CHECK_NULL);
|
{ Klass* k = klass_at_impl(this_cp, callee_index, true, CHECK_NULL);
|
||||||
callee = KlassHandle(THREAD, k);
|
callee = KlassHandle(THREAD, k);
|
||||||
}
|
}
|
||||||
KlassHandle klass(THREAD, this_cp->pool_holder());
|
KlassHandle klass(THREAD, this_cp->pool_holder());
|
||||||
|
|
|
@ -336,7 +336,13 @@ class ConstantPool : public Metadata {
|
||||||
|
|
||||||
Klass* klass_at(int which, TRAPS) {
|
Klass* klass_at(int which, TRAPS) {
|
||||||
constantPoolHandle h_this(THREAD, this);
|
constantPoolHandle h_this(THREAD, this);
|
||||||
return klass_at_impl(h_this, which, CHECK_NULL);
|
return klass_at_impl(h_this, which, true, CHECK_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version of klass_at that doesn't save the resolution error, called during deopt
|
||||||
|
Klass* klass_at_ignore_error(int which, TRAPS) {
|
||||||
|
constantPoolHandle h_this(THREAD, this);
|
||||||
|
return klass_at_impl(h_this, which, false, CHECK_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol* klass_name_at(int which); // Returns the name, w/o resolving.
|
Symbol* klass_name_at(int which); // Returns the name, w/o resolving.
|
||||||
|
@ -793,7 +799,8 @@ class ConstantPool : public Metadata {
|
||||||
|
|
||||||
// Implementation of methods that needs an exposed 'this' pointer, in order to
|
// Implementation of methods that needs an exposed 'this' pointer, in order to
|
||||||
// handle GC while executing the method
|
// handle GC while executing the method
|
||||||
static Klass* klass_at_impl(constantPoolHandle this_cp, int which, TRAPS);
|
static Klass* klass_at_impl(constantPoolHandle this_cp, int which,
|
||||||
|
bool save_resolution_error, TRAPS);
|
||||||
static oop string_at_impl(constantPoolHandle this_cp, int which, int obj_index, TRAPS);
|
static oop string_at_impl(constantPoolHandle this_cp, int which, int obj_index, TRAPS);
|
||||||
|
|
||||||
static void trace_class_resolution(constantPoolHandle this_cp, KlassHandle k);
|
static void trace_class_resolution(constantPoolHandle this_cp, KlassHandle k);
|
||||||
|
|
|
@ -1173,7 +1173,7 @@ Deoptimization::get_method_data(JavaThread* thread, methodHandle m,
|
||||||
void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) {
|
void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) {
|
||||||
// in case of an unresolved klass entry, load the class.
|
// in case of an unresolved klass entry, load the class.
|
||||||
if (constant_pool->tag_at(index).is_unresolved_klass()) {
|
if (constant_pool->tag_at(index).is_unresolved_klass()) {
|
||||||
Klass* tk = constant_pool->klass_at(index, CHECK);
|
Klass* tk = constant_pool->klass_at_ignore_error(index, CHECK);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue