This commit is contained in:
Alejandro Murillo 2016-08-19 11:22:14 -07:00
commit fca083f9fd
54 changed files with 748 additions and 337 deletions

View File

@ -45,15 +45,6 @@ else
LIB_SUBDIR := lib$(OPENJDK_TARGET_CPU_LIBDIR)
endif
################################################################################
# Functions to setup copying of files for variants
# Support macro for SetupDistLibFile
define macosx_universalize
$(MKDIR) -p $(@D)
$(LIPO) -create -output $@ $<
endef
################################################################################
# Setup make rules to copy a native library and associated data.
#
@ -74,16 +65,9 @@ define SetupDistLibFileBody
$1_LIB_NAME := $(LIBRARY_PREFIX)$$($1_NAME)
$1_TARGET_DIR := $$(DIST_OUTPUTDIR)/$$(LIB_SUBDIR)/$$($1_VARIANT_TARGET_DIR)
ifeq ($(OPENJDK_TARGET_OS), macosx)
# We must use the 'universalize' macro to run lipo on shared libraries, at
# least until JDK-8069540 is fixed.
$1_MACRO := macosx_universalize
endif
# Copy the the native library.
$$(eval $$(call SetupCopyFiles, $1_COPY_LIB, \
DEST := $$($1_TARGET_DIR), \
MACRO := $$($1_MACRO), \
FILES := $$(wildcard \
$$($1_SRC_DIR)/$$($1_LIB_NAME)$(SHARED_LIBRARY_SUFFIX)), \
))

View File

@ -1071,6 +1071,9 @@ void InterpreterMacroAssembler::remove_activation(
NOT_LP64(get_thread(rthread);)
cmpl(Address(rthread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_enabled);
jcc(Assembler::equal, no_reserved_zone_enabling);
cmpptr(rbx, Address(rthread, JavaThread::reserved_stack_activation_offset()));
jcc(Assembler::lessEqual, no_reserved_zone_enabling);

View File

@ -255,7 +255,8 @@ public class SALauncher {
}
buildAttachArgs(newArgs, pid, exe, core, false);
JStack.main(newArgs.toArray(new String[newArgs.size()]));
JStack jstack = new JStack(false, false);
jstack.runWithArgs(newArgs.toArray(new String[newArgs.size()]));
}
private static void runJMAP(String[] oldArgs) {

View File

@ -46,7 +46,6 @@ public class PPC64Frame extends Frame {
private static final int SENDER_SP_OFFSET = 0;
// Interpreter frames
private static final int INTERPRETER_FRAME_MIRROR_OFFSET = -3; // for native calls only
private static final int INTERPRETER_FRAME_SENDER_SP_OFFSET = -4;
private static final int INTERPRETER_FRAME_LAST_SP_OFFSET = INTERPRETER_FRAME_SENDER_SP_OFFSET - 1;
private static final int INTERPRETER_FRAME_MDX_OFFSET = INTERPRETER_FRAME_LAST_SP_OFFSET -1;
@ -55,7 +54,8 @@ public class PPC64Frame extends Frame {
private static final int INTERPRETER_FRAME_CACHE_OFFSET =INTERPRETER_FRAME_BCX_OFFSET - 1;
private static final int INTERPRETER_FRAME_MONITORS_OFFSET = INTERPRETER_FRAME_CACHE_OFFSET - 1;
private static final int INTERPRETER_FRAME_LOCALS_OFFSET = INTERPRETER_FRAME_MONITORS_OFFSET - 1;
private static final int INTERPRETER_FRAME_METHOD_OFFSET = INTERPRETER_FRAME_LOCALS_OFFSET - 1;
private static final int INTERPRETER_FRAME_MIRROR_OFFSET = INTERPRETER_FRAME_LOCALS_OFFSET - 1;
private static final int INTERPRETER_FRAME_METHOD_OFFSET = INTERPRETER_FRAME_MIRROR_OFFSET - 1;
private static final int INTERPRETER_FRAME_INITIAL_SP_OFFSET = INTERPRETER_FRAME_BCX_OFFSET - 1; // FIXME: probably wrong, but unused anyway
private static final int INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
private static final int INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;

View File

@ -714,11 +714,7 @@ public class SPARCFrame extends Frame {
/** 2 words, also used to save float regs across calls to C */
public static final int INTERPRETER_FRAME_D_SCRATCH_FP_OFFSET = -2;
public static final int INTERPRETER_FRAME_L_SCRATCH_FP_OFFSET = -4;
/** For native calls only */
public static final int INTERPRETER_FRAME_PADDING_OFFSET = -5;
/** For native calls only */
public static final int INTERPRETER_FRAME_MIRROR_OFFSET = -6;
/** Should be same as above, and should be zero mod 8 */
public static final int INTERPRETER_FRAME_MIRROR_OFFSET = -5;
public static final int INTERPRETER_FRAME_VM_LOCALS_FP_OFFSET = -6;
public static final int INTERPRETER_FRAME_VM_LOCAL_WORDS = -INTERPRETER_FRAME_VM_LOCALS_FP_OFFSET;

View File

@ -48,10 +48,10 @@ public class X86Frame extends Frame {
private static final int SENDER_SP_OFFSET = 2;
// Interpreter frames
private static final int INTERPRETER_FRAME_MIRROR_OFFSET = 2; // for native calls only
private static final int INTERPRETER_FRAME_SENDER_SP_OFFSET = -1;
private static final int INTERPRETER_FRAME_LAST_SP_OFFSET = INTERPRETER_FRAME_SENDER_SP_OFFSET - 1;
private static final int INTERPRETER_FRAME_METHOD_OFFSET = INTERPRETER_FRAME_LAST_SP_OFFSET - 1;
private static int INTERPRETER_FRAME_MIRROR_OFFSET;
private static int INTERPRETER_FRAME_MDX_OFFSET; // Non-core builds only
private static int INTERPRETER_FRAME_CACHE_OFFSET;
private static int INTERPRETER_FRAME_LOCALS_OFFSET;
@ -74,7 +74,8 @@ public class X86Frame extends Frame {
}
private static synchronized void initialize(TypeDataBase db) {
INTERPRETER_FRAME_MDX_OFFSET = INTERPRETER_FRAME_METHOD_OFFSET - 1;
INTERPRETER_FRAME_MIRROR_OFFSET = INTERPRETER_FRAME_METHOD_OFFSET - 1;
INTERPRETER_FRAME_MDX_OFFSET = INTERPRETER_FRAME_MIRROR_OFFSET - 1;
INTERPRETER_FRAME_CACHE_OFFSET = INTERPRETER_FRAME_MDX_OFFSET - 1;
INTERPRETER_FRAME_LOCALS_OFFSET = INTERPRETER_FRAME_CACHE_OFFSET - 1;
INTERPRETER_FRAME_BCX_OFFSET = INTERPRETER_FRAME_LOCALS_OFFSET - 1;

View File

@ -265,9 +265,10 @@ final class CompilerToVM {
native HotSpotResolvedObjectTypeImpl resolveTypeInPool(HotSpotConstantPool constantPool, int cpi) throws LinkageError;
/**
* Looks up and attempts to resolve the {@code JVM_CONSTANT_Field} entry for at index {@code cpi} in
* {@code constantPool}. For some opcodes, checks are performed that require the {@code method}
* that contains {@code opcode} to be specified. The values returned in {@code info} are:
* Looks up and attempts to resolve the {@code JVM_CONSTANT_Field} entry for at index
* {@code cpi} in {@code constantPool}. For some opcodes, checks are performed that require the
* {@code method} that contains {@code opcode} to be specified. The values returned in
* {@code info} are:
*
* <pre>
* [(int) flags, // only valid if field is resolved
@ -556,20 +557,18 @@ final class CompilerToVM {
native HotSpotResolvedJavaMethodImpl getResolvedJavaMethod(Object base, long displacement);
/**
* Read a HotSpot ConstantPool* value from the memory location described by {@code base} plus
* {@code displacement} and return the {@link HotSpotConstantPool} wrapping it. This method does
* no checking that the memory location actually contains a valid pointer and may crash the VM
* if an invalid location is provided. If the {@code base} is null then {@code displacement} is
* used by itself. If {@code base} is a {@link HotSpotResolvedJavaMethodImpl},
* {@link HotSpotConstantPool} or {@link HotSpotResolvedObjectTypeImpl} then the metaspace
* pointer is fetched from that object and added to {@code displacement}. Any other non-null
* object type causes an {@link IllegalArgumentException} to be thrown.
* Gets the {@code ConstantPool*} associated with {@code object} and returns a
* {@link HotSpotConstantPool} wrapping it.
*
* @param base an object to read from or null
* @param displacement
* @return null or the resolved method for this location
* @param object a {@link HotSpotResolvedJavaMethodImpl} or
* {@link HotSpotResolvedObjectTypeImpl} object
* @return a {@link HotSpotConstantPool} wrapping the {@code ConstantPool*} associated with
* {@code object}
* @throws NullPointerException if {@code object == null}
* @throws IllegalArgumentException if {@code object} is neither a
* {@link HotSpotResolvedJavaMethodImpl} nor a {@link HotSpotResolvedObjectTypeImpl}
*/
native HotSpotConstantPool getConstantPool(Object base, long displacement);
native HotSpotConstantPool getConstantPool(Object object);
/**
* Read a HotSpot Klass* value from the memory location described by {@code base} plus

View File

@ -121,7 +121,7 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp
if (metaspaceConstantPool == holder.getConstantPool().getMetaspaceConstantPool()) {
this.constantPool = holder.getConstantPool();
} else {
this.constantPool = compilerToVM().getConstantPool(null, constMethod + config.constMethodConstantsOffset);
this.constantPool = compilerToVM().getConstantPool(this);
}
final int nameIndex = UNSAFE.getChar(constMethod + config.constMethodNameIndexOffset);

View File

@ -445,7 +445,7 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
* operating on the latest one and that HotSpotResolvedJavaMethodImpls will be able to
* use the shared copy instead of creating their own instance.
*/
constantPool = compilerToVM().getConstantPool(this, config().instanceKlassConstantsOffset);
constantPool = compilerToVM().getConstantPool(this);
}
return constantPool;
}

View File

@ -2686,7 +2686,8 @@ void os::hint_no_preempt() {}
// - sets target osthread state to continue
// - sends signal to end the sigsuspend loop in the SR_handler
//
// Note that the SR_lock plays no role in this suspend/resume protocol.
// Note that the SR_lock plays no role in this suspend/resume protocol,
// but is checked for NULL in SR_handler as a thread termination indicator.
//
static void resume_clear_context(OSThread *osthread) {
@ -2718,10 +2719,23 @@ static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
// after sigsuspend.
int old_errno = errno;
Thread* thread = Thread::current();
OSThread* osthread = thread->osthread();
Thread* thread = Thread::current_or_null_safe();
assert(thread != NULL, "Missing current thread in SR_handler");
// On some systems we have seen signal delivery get "stuck" until the signal
// mask is changed as part of thread termination. Check that the current thread
// has not already terminated (via SR_lock()) - else the following assertion
// will fail because the thread is no longer a JavaThread as the ~JavaThread
// destructor has completed.
if (thread->SR_lock() == NULL) {
return;
}
assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
OSThread* osthread = thread->osthread();
os::SuspendResume::State current = osthread->sr.state();
if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
suspend_save_context(osthread, siginfo, context);

View File

@ -2716,7 +2716,8 @@ void os::hint_no_preempt() {}
// - sets target osthread state to continue
// - sends signal to end the sigsuspend loop in the SR_handler
//
// Note that the SR_lock plays no role in this suspend/resume protocol.
// Note that the SR_lock plays no role in this suspend/resume protocol,
// but is checked for NULL in SR_handler as a thread termination indicator.
static void resume_clear_context(OSThread *osthread) {
osthread->set_ucontext(NULL);
@ -2746,10 +2747,23 @@ static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
// after sigsuspend.
int old_errno = errno;
Thread* thread = Thread::current();
OSThread* osthread = thread->osthread();
Thread* thread = Thread::current_or_null_safe();
assert(thread != NULL, "Missing current thread in SR_handler");
// On some systems we have seen signal delivery get "stuck" until the signal
// mask is changed as part of thread termination. Check that the current thread
// has not already terminated (via SR_lock()) - else the following assertion
// will fail because the thread is no longer a JavaThread as the ~JavaThread
// destructor has completed.
if (thread->SR_lock() == NULL) {
return;
}
assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
OSThread* osthread = thread->osthread();
os::SuspendResume::State current = osthread->sr.state();
if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
suspend_save_context(osthread, siginfo, context);

View File

@ -3971,7 +3971,8 @@ void os::hint_no_preempt() {}
// - sets target osthread state to continue
// - sends signal to end the sigsuspend loop in the SR_handler
//
// Note that the SR_lock plays no role in this suspend/resume protocol.
// Note that the SR_lock plays no role in this suspend/resume protocol,
// but is checked for NULL in SR_handler as a thread termination indicator.
static void resume_clear_context(OSThread *osthread) {
osthread->set_ucontext(NULL);
@ -4004,9 +4005,21 @@ static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
Thread* thread = Thread::current_or_null_safe();
assert(thread != NULL, "Missing current thread in SR_handler");
OSThread* osthread = thread->osthread();
// On some systems we have seen signal delivery get "stuck" until the signal
// mask is changed as part of thread termination. Check that the current thread
// has not already terminated (via SR_lock()) - else the following assertion
// will fail because the thread is no longer a JavaThread as the ~JavaThread
// destructor has completed.
if (thread->SR_lock() == NULL) {
return;
}
assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
OSThread* osthread = thread->osthread();
os::SuspendResume::State current = osthread->sr.state();
if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
suspend_save_context(osthread, siginfo, context);

View File

@ -93,10 +93,6 @@ void os::check_dump_limit(char* buffer, size_t bufferSize) {
}
int os::get_native_stack(address* stack, int frames, int toSkip) {
#ifdef _NMT_NOINLINE_
toSkip++;
#endif
int frame_idx = 0;
int num_of_frames; // number of frames captured
frame fr = os::current_frame();

View File

@ -318,9 +318,6 @@ extern "C" void breakpoint() {
// only supported on Windows XP or later.
//
int os::get_native_stack(address* stack, int frames, int toSkip) {
#ifdef _NMT_NOINLINE_
toSkip++;
#endif
int captured = RtlCaptureStackBackTrace(toSkip + 1, frames, (PVOID*)stack, NULL);
for (int index = captured; index < frames; index ++) {
stack[index] = NULL;

View File

@ -417,7 +417,15 @@ intptr_t* _get_previous_fp() {
#else
register intptr_t **ebp __asm__ (SPELL_REG_FP);
#endif
return (intptr_t*) *ebp; // we want what it points to.
// ebp is for this frame (_get_previous_fp). We want the ebp for the
// caller of os::current_frame*(), so go up two frames. However, for
// optimized builds, _get_previous_fp() will be inlined, so only go
// up 1 frame in that case.
#ifdef _NMT_NOINLINE_
return **(intptr_t***)ebp;
#else
return *ebp;
#endif
}

View File

@ -238,6 +238,28 @@ JVM_handle_linux_signal(int sig,
}
}
// Make the signal handler transaction-aware by checking the existence of a
// second (transactional) context with MSR TS bits active. If the signal is
// caught during a transaction, then just return to the HTM abort handler.
// Please refer to Linux kernel document powerpc/transactional_memory.txt,
// section "Signals".
if (uc && uc->uc_link) {
ucontext_t* second_uc = uc->uc_link;
// MSR TS bits are 29 and 30 (Power ISA, v2.07B, Book III-S, pp. 857-858,
// 3.2.1 "Machine State Register"), however note that ISA notation for bit
// numbering is MSB 0, so for normal bit numbering (LSB 0) they come to be
// bits 33 and 34. It's not related to endianness, just a notation matter.
if (second_uc->uc_mcontext.regs->msr & 0x600000000) {
if (TraceTraps) {
tty->print_cr("caught signal in transaction, "
"ignoring to jump to abort handler");
}
// Return control to the HTM abort handler.
return true;
}
}
JavaThread* thread = NULL;
VMThread* vmthread = NULL;
if (os::Linux::signal_handlers_are_installed) {

View File

@ -235,7 +235,15 @@ intptr_t* _get_previous_fp() {
#else
register intptr_t **ebp __asm__ (SPELL_REG_FP);
#endif
return (intptr_t*) *ebp; // we want what it points to.
// ebp is for this frame (_get_previous_fp). We want the ebp for the
// caller of os::current_frame*(), so go up two frames. However, for
// optimized builds, _get_previous_fp() will be inlined, so only go
// up 1 frame in that case.
#ifdef _NMT_NOINLINE_
return **(intptr_t***)ebp;
#else
return *ebp;
#endif
}

View File

@ -292,15 +292,19 @@ extern "C" intptr_t *_get_current_fp(); // in .il file
frame os::current_frame() {
intptr_t* fp = _get_current_fp(); // it's inlined so want current fp
// fp is for os::current_frame. We want the fp for our caller.
frame myframe((intptr_t*)os::current_stack_pointer(),
(intptr_t*)fp,
CAST_FROM_FN_PTR(address, os::current_frame));
if (os::is_first_C_frame(&myframe)) {
frame caller_frame = os::get_sender_for_C_frame(&myframe);
if (os::is_first_C_frame(&caller_frame)) {
// stack is not walkable
frame ret; // This will be a null useless frame
return ret;
} else {
return os::get_sender_for_C_frame(&myframe);
// return frame for our caller's caller
return os::get_sender_for_C_frame(&caller_frame);
}
}

View File

@ -496,7 +496,15 @@ intptr_t* _get_previous_fp() {
__asm {
mov frameptr, ebp
};
// ebp (frameptr) is for this frame (_get_previous_fp). We want the ebp for the
// caller of os::current_frame*(), so go up two frames. However, for
// optimized builds, _get_previous_fp() will be inlined, so only go
// up 1 frame in that case.
#ifdef _NMT_NOINLINE_
return **(intptr_t***)frameptr;
#else
return *frameptr;
#endif
}
#endif // !AMD64

View File

@ -126,13 +126,17 @@ bool ClassLoaderData::claim() {
// ClassLoaderData, no other non-GC thread has knowledge of the anonymous class while
// it is being defined, therefore _keep_alive is not volatile or atomic.
void ClassLoaderData::inc_keep_alive() {
assert(_keep_alive >= 0, "Invalid keep alive count");
_keep_alive++;
if (is_anonymous()) {
assert(_keep_alive >= 0, "Invalid keep alive increment count");
_keep_alive++;
}
}
void ClassLoaderData::dec_keep_alive() {
assert(_keep_alive > 0, "Invalid keep alive count");
_keep_alive--;
if (is_anonymous()) {
assert(_keep_alive > 0, "Invalid keep alive decrement count");
_keep_alive--;
}
}
void ClassLoaderData::oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) {

View File

@ -176,9 +176,9 @@ class ClassLoaderData : public CHeapObj<mtClass> {
Mutex* _metaspace_lock; // Locks the metaspace for allocations and setup.
bool _unloading; // true if this class loader goes away
bool _is_anonymous; // if this CLD is for an anonymous class
int _keep_alive; // if this CLD is kept alive without a keep_alive_object().
// Currently used solely for anonymous classes.
// _keep_alive does not need to be volatile or
s2 _keep_alive; // if this CLD is kept alive without a keep_alive_object().
// Used for anonymous classes and the boot class
// loader. _keep_alive does not need to be volatile or
// atomic since there is one unique CLD per anonymous class.
volatile int _claimed; // true if claimed, for example during GC traces.
// To avoid applying oop closure more than once.
@ -289,6 +289,8 @@ class ClassLoaderData : public CHeapObj<mtClass> {
return _unloading;
}
// Used to refcount an anonymous class's CLD in order to
// indicate their aliveness without a keep_alive_object().
void inc_keep_alive();
void dec_keep_alive();

View File

@ -1082,12 +1082,11 @@ class ClassHierarchyWalker {
if (!(m->is_public() || m->is_protected()))
// The override story is complex when packages get involved.
return true; // Must punt the assertion to true.
Klass* k = ctxk;
Method* lm = k->lookup_method(m->name(), m->signature());
if (lm == NULL && k->is_instance_klass()) {
Method* lm = ctxk->lookup_method(m->name(), m->signature());
if (lm == NULL && ctxk->is_instance_klass()) {
// It might be an interface method
lm = InstanceKlass::cast(k)->lookup_method_in_ordered_interfaces(m->name(),
m->signature());
lm = InstanceKlass::cast(ctxk)->lookup_method_in_ordered_interfaces(m->name(),
m->signature());
}
if (lm == m)
// Method m is inherited into ctxk.
@ -1101,11 +1100,19 @@ class ClassHierarchyWalker {
// Static methods don't override non-static so punt
return true;
}
if ( !Dependencies::is_concrete_method(lm, k)
&& !Dependencies::is_concrete_method(m, ctxk)
&& lm->method_holder()->is_subtype_of(m->method_holder()))
// Method m is overridden by lm, but both are non-concrete.
return true;
if (!Dependencies::is_concrete_method(lm, ctxk) &&
!Dependencies::is_concrete_method(m, ctxk)) {
// They are both non-concrete
if (lm->method_holder()->is_subtype_of(m->method_holder())) {
// Method m is overridden by lm, but both are non-concrete.
return true;
}
if (lm->method_holder()->is_interface() && m->method_holder()->is_interface() &&
ctxk->is_subtype_of(m->method_holder()) && ctxk->is_subtype_of(lm->method_holder())) {
// Interface method defined in multiple super interfaces
return true;
}
}
}
ResourceMark rm;
tty->print_cr("Dependency method not found in the associated context:");

View File

@ -461,31 +461,26 @@ C2V_VMENTRY(jobject, getResolvedJavaMethod, (JNIEnv *, jobject, jobject base, jl
return JNIHandles::make_local(THREAD, result);
}
C2V_VMENTRY(jobject, getConstantPool, (JNIEnv *, jobject, jobject base, jlong offset))
C2V_VMENTRY(jobject, getConstantPool, (JNIEnv *, jobject, jobject object_handle))
constantPoolHandle cp;
oop base_object = JNIHandles::resolve(base);
jlong base_address = 0;
if (base_object != NULL) {
if (base_object->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) {
base_address = HotSpotResolvedJavaMethodImpl::metaspaceMethod(base_object);
} else if (base_object->is_a(SystemDictionary::HotSpotConstantPool_klass())) {
base_address = HotSpotConstantPool::metaspaceConstantPool(base_object);
} else if (base_object->is_a(SystemDictionary::HotSpotResolvedObjectTypeImpl_klass())) {
base_address = (jlong) CompilerToVM::asKlass(base_object);
} else {
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
err_msg("Unexpected type: %s", base_object->klass()->external_name()));
}
oop object = JNIHandles::resolve(object_handle);
if (object == NULL) {
THROW_0(vmSymbols::java_lang_NullPointerException());
}
cp = *((ConstantPool**) (intptr_t) (base_address + offset));
if (!cp.is_null()) {
JavaValue method_result(T_OBJECT);
JavaCallArguments args;
args.push_long((jlong) (address) cp());
JavaCalls::call_static(&method_result, SystemDictionary::HotSpotConstantPool_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::constantPool_fromMetaspace_signature(), &args, CHECK_NULL);
return JNIHandles::make_local(THREAD, (oop)method_result.get_jobject());
if (object->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) {
cp = CompilerToVM::asMethod(object)->constMethod()->constants();
} else if (object->is_a(SystemDictionary::HotSpotResolvedObjectTypeImpl_klass())) {
cp = InstanceKlass::cast(CompilerToVM::asKlass(object))->constants();
} else {
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
err_msg("Unexpected type: %s", object->klass()->external_name()));
}
return NULL;
assert(!cp.is_null(), "npe");
JavaValue method_result(T_OBJECT);
JavaCallArguments args;
args.push_long((jlong) (address) cp());
JavaCalls::call_static(&method_result, SystemDictionary::HotSpotConstantPool_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::constantPool_fromMetaspace_signature(), &args, CHECK_NULL);
return JNIHandles::make_local(THREAD, (oop)method_result.get_jobject());
}
C2V_VMENTRY(jobject, getResolvedJavaType, (JNIEnv *, jobject, jobject base, jlong offset, jboolean compressed))
@ -1522,7 +1517,7 @@ JNINativeMethod CompilerToVM::methods[] = {
{CC "getMaxCallTargetOffset", CC "(J)J", FN_PTR(getMaxCallTargetOffset)},
{CC "getResolvedJavaMethodAtSlot", CC "(" CLASS "I)" HS_RESOLVED_METHOD, FN_PTR(getResolvedJavaMethodAtSlot)},
{CC "getResolvedJavaMethod", CC "(Ljava/lang/Object;J)" HS_RESOLVED_METHOD, FN_PTR(getResolvedJavaMethod)},
{CC "getConstantPool", CC "(Ljava/lang/Object;J)" HS_CONSTANT_POOL, FN_PTR(getConstantPool)},
{CC "getConstantPool", CC "(Ljava/lang/Object;)" HS_CONSTANT_POOL, FN_PTR(getConstantPool)},
{CC "getResolvedJavaType", CC "(Ljava/lang/Object;JZ)" HS_RESOLVED_KLASS, FN_PTR(getResolvedJavaType)},
{CC "readConfiguration", CC "()[" OBJECT, FN_PTR(readConfiguration)},
{CC "installCode", CC "(" TARGET_DESCRIPTION HS_COMPILED_CODE INSTALLED_CODE HS_SPECULATION_LOG ")I", FN_PTR(installCode)},

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 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

View File

@ -630,6 +630,12 @@ bool ArrayCopyNode::may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase) {
}
bool ArrayCopyNode::may_modify_helper(const TypeOopPtr *t_oop, Node* n, PhaseTransform *phase, ArrayCopyNode*& ac) {
if (n->Opcode() == Op_StoreCM ||
n->Opcode() == Op_StoreB) {
// Ignore card mark stores
n = n->in(MemNode::Memory);
}
if (n->is_Proj()) {
n = n->in(0);
if (n->is_Call() && n->as_Call()->may_modify(t_oop, phase)) {
@ -657,9 +663,6 @@ bool ArrayCopyNode::may_modify(const TypeOopPtr *t_oop, MemBarNode* mb, PhaseTra
}
}
}
} else if (n->Opcode() == Op_StoreCM) {
// Ignore card mark stores
return may_modify_helper(t_oop, n->in(MemNode::Memory), phase, ac);
}
}

View File

@ -861,6 +861,13 @@ Unsafe_DefineAnonymousClass_impl(JNIEnv *env,
}
const Klass* host_klass = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(host_class));
// Make sure it's the real host class, not another anonymous class.
while (host_klass != NULL && host_klass->is_instance_klass() &&
InstanceKlass::cast(host_klass)->is_anonymous()) {
host_klass = InstanceKlass::cast(host_klass)->host_klass();
}
// Primitive types have NULL Klass* fields in their java.lang.Class instances.
if (host_klass == NULL) {
THROW_0(vmSymbols::java_lang_IllegalArgumentException());

View File

@ -679,7 +679,7 @@ WB_ENTRY(jboolean, WB_IsMethodQueuedForCompilation(JNIEnv* env, jobject o, jobje
WB_END
WB_ENTRY(jboolean, WB_IsIntrinsicAvailable(JNIEnv* env, jobject o, jobject method, jobject compilation_context, jint compLevel))
if (compLevel < CompLevel_none || compLevel > CompLevel_highest_tier) {
if (compLevel < CompLevel_none || compLevel > MIN2((CompLevel) TieredStopAtLevel, CompLevel_highest_tier)) {
return false; // Intrinsic is not available on a non-existent compilation level.
}
jmethodID method_id, compilation_context_id;
@ -689,6 +689,7 @@ WB_ENTRY(jboolean, WB_IsIntrinsicAvailable(JNIEnv* env, jobject o, jobject metho
DirectiveSet* directive;
AbstractCompiler* comp = CompileBroker::compiler((int)compLevel);
assert(comp != NULL, "compiler not available");
if (compilation_context != NULL) {
compilation_context_id = reflected_method_to_jmid(thread, env, compilation_context);
CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
@ -698,7 +699,7 @@ WB_ENTRY(jboolean, WB_IsIntrinsicAvailable(JNIEnv* env, jobject o, jobject metho
// Calling with NULL matches default directive
directive = DirectivesStack::getDefaultDirective(comp);
}
bool result = CompileBroker::compiler(compLevel)->is_intrinsic_available(mh, directive);
bool result = comp->is_intrinsic_available(mh, directive);
DirectivesStack::release(directive);
return result;
WB_END

View File

@ -55,7 +55,8 @@ void AdvancedThresholdPolicy::initialize() {
// Simple log n seems to grow too slowly for tiered, try something faster: log n * log log n
int log_cpu = log2_intptr(os::active_processor_count());
int loglog_cpu = log2_intptr(MAX2(log_cpu, 1));
count = MAX2(log_cpu * loglog_cpu, 1) * 3 / 2;
count = MAX2(log_cpu * loglog_cpu * 3 / 2, 2);
FLAG_SET_ERGO(intx, CICompilerCount, count);
}
#else
// On 32-bit systems, the number of compiler threads is limited to 3.
@ -67,12 +68,18 @@ void AdvancedThresholdPolicy::initialize() {
/// available to the VM and thus cause the VM to crash.
if (FLAG_IS_DEFAULT(CICompilerCount)) {
count = 3;
FLAG_SET_ERGO(intx, CICompilerCount, count);
}
#endif
set_c1_count(MAX2(count / 3, 1));
set_c2_count(MAX2(count - c1_count(), 1));
FLAG_SET_ERGO(intx, CICompilerCount, c1_count() + c2_count());
if (TieredStopAtLevel < CompLevel_full_optimization) {
// No C2 compiler thread required
set_c1_count(count);
} else {
set_c1_count(MAX2(count / 3, 1));
set_c2_count(MAX2(count - c1_count(), 1));
}
assert(count == c1_count() + c2_count(), "inconsistent compiler thread count");
// Some inlining tuning
#ifdef X86

View File

@ -2411,7 +2411,7 @@ public:
product(intx, CICompilerCount, CI_COMPILER_COUNT, \
"Number of compiler threads to run") \
range(0, max_jint) \
constraint(CICompilerCountConstraintFunc, AtParse) \
constraint(CICompilerCountConstraintFunc, AfterErgo) \
\
product(intx, CompilationPolicyChoice, 0, \
"which compilation policy (0-3)") \

View File

@ -660,11 +660,13 @@ bool Reflection::verify_field_access(const Klass* current_class,
}
const Klass* host_class = current_class;
while (host_class->is_instance_klass() &&
InstanceKlass::cast(host_class)->is_anonymous()) {
const Klass* next_host_class = InstanceKlass::cast(host_class)->host_klass();
if (next_host_class == NULL) break;
host_class = next_host_class;
if (host_class->is_instance_klass() &&
InstanceKlass::cast(host_class)->is_anonymous()) {
host_class = InstanceKlass::cast(host_class)->host_klass();
assert(host_class != NULL, "Anonymous class has null host class");
assert(!(host_class->is_instance_klass() &&
InstanceKlass::cast(host_class)->is_anonymous()),
"host_class should not be anonymous");
}
if (host_class == field_class) {
return true;

View File

@ -147,12 +147,18 @@ void SimpleThresholdPolicy::initialize() {
// performed on 32-bit systems because it can lead to exhaustion
// of the virtual memory address space available to the JVM.
if (CICompilerCountPerCPU) {
count = MAX2(log2_intptr(os::active_processor_count()), 1) * 3 / 2;
count = MAX2(log2_intptr(os::active_processor_count()) * 3 / 2, 2);
FLAG_SET_ERGO(intx, CICompilerCount, count);
}
#endif
set_c1_count(MAX2(count / 3, 1));
set_c2_count(MAX2(count - c1_count(), 1));
FLAG_SET_ERGO(intx, CICompilerCount, c1_count() + c2_count());
if (TieredStopAtLevel < CompLevel_full_optimization) {
// No C2 compiler thread required
set_c1_count(count);
} else {
set_c1_count(MAX2(count / 3, 1));
set_c2_count(MAX2(count - c1_count(), 1));
}
assert(count == c1_count() + c2_count(), "inconsistent compiler thread count");
}
void SimpleThresholdPolicy::set_carry_if_necessary(InvocationCounter *counter) {

View File

@ -374,11 +374,14 @@ Thread::~Thread() {
delete handle_area();
delete metadata_handles();
// SR_handler uses this as a termination indicator -
// needs to happen before os::free_thread()
delete _SR_lock;
_SR_lock = NULL;
// osthread() can be NULL, if creation of thread failed.
if (osthread() != NULL) os::free_thread(osthread());
delete _SR_lock;
// clear Thread::current if thread is deleting itself.
// Needed to ensure JNI correctly detects non-attached threads.
if (this == Thread::current()) {

View File

@ -2643,7 +2643,7 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
/* DEFAULT_CACHE_LINE_SIZE (globalDefinitions.hpp) */ \
/***************************************************/ \
\
declare_constant(DEFAULT_CACHE_LINE_SIZE) \
declare_preprocessor_constant("DEFAULT_CACHE_LINE_SIZE", DEFAULT_CACHE_LINE_SIZE) \
\
declare_constant(Deoptimization::Unpack_deopt) \
declare_constant(Deoptimization::Unpack_exception) \

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 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
@ -33,6 +33,19 @@ NativeCallStack::NativeCallStack(int toSkip, bool fillStack) :
_hash_value(0) {
if (fillStack) {
// We need to skip the NativeCallStack::NativeCallStack frame if a tail call is NOT used
// to call os::get_native_stack. A tail call is used if _NMT_NOINLINE_ is not defined
// (which means this is not a slowdebug build), and we are on 64-bit (except Windows).
// This is not necessarily a rule, but what has been obvserved to date.
#define TAIL_CALL (!defined(_NMT_NOINLINE_) && !defined(WINDOWS) && defined(_LP64))
#if !TAIL_CALL
toSkip++;
#if (defined(_NMT_NOINLINE_) && defined(BSD) && defined(_LP64))
// Mac OS X slowdebug builds have this odd behavior where NativeCallStack::NativeCallStack
// appears as two frames, so we need to skip an extra frame.
toSkip++;
#endif
#endif
os::get_native_stack(_stack, NMT_TrackingStackDepth, toSkip);
} else {
for (int index = 0; index < NMT_TrackingStackDepth; index ++) {

View File

@ -167,7 +167,7 @@ needs_compact3 = \
gc/survivorAlignment \
runtime/InternalApi/ThreadCpuTimesDeadlock.java \
runtime/NMT/JcmdSummaryDiff.java \
runtime/RedefineTests/RedefineAnnotations.java
runtime/RedefineTests/RedefineAnnotations.java \
serviceability/sa/jmap-hashcode/Test8028623.java \
serviceability/threads/TestFalseDeadLock.java \
compiler/codecache/jmx \
@ -282,7 +282,7 @@ hotspot_fast_compiler_1 = \
-compiler/c2/Test6905845.java \
-compiler/c2/cr6340864 \
-compiler/c2/cr6589834 \
-compiler/c2/cr8004867
-compiler/c2/cr8004867 \
-compiler/c2/stemmer \
-compiler/c2/Test6792161.java \
-compiler/c2/Test6603011.java \

View File

@ -23,8 +23,7 @@
/*
* @test CheckCheckCICompilerCount
* @bug 8130858
* @bug 8132525
* @bug 8130858 8132525 8162881
* @summary Check that correct range of values for CICompilerCount are allowed depending on whether tiered is enabled or not
* @library /testlibrary /
* @modules java.base/jdk.internal.misc
@ -53,6 +52,13 @@ public class CheckCICompilerCount {
"-XX:CICompilerCount=1",
"-version"
},
{
"-server",
"-XX:+PrintFlagsFinal",
"-XX:CICompilerCount=1",
"-XX:-TieredCompilation",
"-version"
},
{
"-client",
"-XX:-TieredCompilation",
@ -66,30 +72,31 @@ public class CheckCICompilerCount {
"-XX:+PrintFlagsFinal",
"-XX:CICompilerCount=1",
"-version"
},
{
"-client",
"-XX:+PrintFlagsFinal",
"-XX:CICompilerCount=1",
"-XX:-TieredCompilation",
"-version"
}
};
private static final String[][] NON_TIERED_EXPECTED_OUTPUTS = {
{
private static final String[] NON_TIERED_EXPECTED_OUTPUTS = {
"CICompilerCount (0) must be at least 1",
"Improperly specified VM option 'CICompilerCount=0'"
},
{
"intx CICompilerCount = 1 {product} {command line}"
},
{
"intx CICompilerCount = 1 {product} {command line}",
"intx CICompilerCount = 1 {product} {command line}",
"CICompilerCount (0) must be at least 1",
"Improperly specified VM option 'CICompilerCount=0'"
},
{
"intx CICompilerCount = 1 {product} {command line}",
"intx CICompilerCount = 1 {product} {command line}"
}
};
private static final int[] NON_TIERED_EXIT = {
1,
0,
0,
1,
0,
0
};
@ -101,6 +108,22 @@ public class CheckCICompilerCount {
"-XX:CICompilerCount=1",
"-version"
},
{
"-server",
"-XX:+TieredCompilation",
"-XX:TieredStopAtLevel=1",
"-XX:+PrintFlagsFinal",
"-XX:CICompilerCount=1",
"-version"
},
{
"-server",
"-XX:+TieredCompilation",
"-XX:+PrintFlagsFinal",
"-XX:CICompilerCount=1",
"-XX:TieredStopAtLevel=1",
"-version"
},
{
"-server",
"-XX:+TieredCompilation",
@ -115,6 +138,22 @@ public class CheckCICompilerCount {
"-XX:CICompilerCount=1",
"-version"
},
{
"-client",
"-XX:+TieredCompilation",
"-XX:TieredStopAtLevel=1",
"-XX:+PrintFlagsFinal",
"-XX:CICompilerCount=1",
"-version"
},
{
"-client",
"-XX:+TieredCompilation",
"-XX:+PrintFlagsFinal",
"-XX:CICompilerCount=1",
"-XX:TieredStopAtLevel=1",
"-version"
},
{
"-client",
"-XX:+TieredCompilation",
@ -124,31 +163,29 @@ public class CheckCICompilerCount {
}
};
private static final String[][] TIERED_EXPECTED_OUTPUTS = {
{
private static final String[] TIERED_EXPECTED_OUTPUTS = {
"CICompilerCount (1) must be at least 2",
"Improperly specified VM option 'CICompilerCount=1'"
},
{
"intx CICompilerCount = 2 {product} {command line, ergonomic}"
},
{
"intx CICompilerCount = 1 {product} {command line}",
"intx CICompilerCount = 1 {product} {command line}",
"intx CICompilerCount = 2 {product} {command line}",
"CICompilerCount (1) must be at least 2",
"Improperly specified VM option 'CICompilerCount=1'"
},
{
"intx CICompilerCount = 2 {product} {command line, ergonomic}"
}
"intx CICompilerCount = 1 {product} {command line}",
"intx CICompilerCount = 1 {product} {command line}",
"intx CICompilerCount = 2 {product} {command line}",
};
private static final int[] TIERED_EXIT = {
1,
0,
0,
0,
1,
0,
0,
0
};
private static void verifyValidOption(String[] arguments, String[] expected_outputs, int exit, boolean tiered) throws Exception {
private static void verifyValidOption(String[] arguments, String expected_output, int exit, boolean tiered) throws Exception {
ProcessBuilder pb;
OutputAnalyzer out;
@ -157,9 +194,7 @@ public class CheckCICompilerCount {
try {
out.shouldHaveExitValue(exit);
for (String expected_output : expected_outputs) {
out.shouldContain(expected_output);
}
out.shouldContain(expected_output);
} catch (RuntimeException e) {
// Check if tiered compilation is available in this JVM
// Version. Throw exception only if it is available.

View File

@ -25,7 +25,6 @@
* @test
* @bug 8130847 8156760
* @summary Eliminated instance/array written to by an array copy variant must be correctly initialized when reallocated at a deopt
* @ignore 8136818
* @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement
* compiler.arraycopy.TestEliminatedArrayCopyDeopt
* @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement

View File

@ -27,7 +27,7 @@
* @bug 6792161
* @summary assert("No dead instructions after post-alloc")
*
* @run main/othervm/timeout=600 -Xcomp -XX:MaxInlineSize=120 compiler.c2.Test6792161
* @run main/othervm/timeout=600 -Xcomp -XX:-TieredCompilation -XX:MaxInlineSize=120 compiler.c2.Test6792161
*/
package compiler.c2;

View File

@ -36,6 +36,11 @@
* -XX:CompileCommand=compileonly,null::* -XX:-UseLargePages
* -XX:+SegmentedCodeCache
* compiler.codecache.jmx.InitialAndMaxUsageTest
* @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing
* -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* -XX:CompileCommand=compileonly,null::* -XX:-UseLargePages
* -XX:-SegmentedCodeCache
* compiler.codecache.jmx.InitialAndMaxUsageTest
*/
package compiler.codecache.jmx;
@ -70,10 +75,16 @@ public class InitialAndMaxUsageTest {
}
}
private void fillWithSize(long size, List<Long> blobs) {
private void fillWithSize(long size, List<Long> blobs, MemoryPoolMXBean bean) {
long blob;
while ((blob = CodeCacheUtils.WB.allocateCodeBlob(size, btype.id))
!= 0L) {
/* Don't fill too much to have space for adapters. So, stop after crossing 95% and
don't allocate in case we'll cross 97% on next allocation. We can hit situation
like 94% -> (1 allocation) -> 100% otherwise. So, check if
<Usage + allocatedSize> is less than 97%, then allocate in case it is, then, stop
further allocations with given size in case <Usage> more than 95% */
while (((double) bean.getUsage().getUsed() + size <= (CACHE_USAGE_COEF + 0.02d) * maxSize)
&& (blob = CodeCacheUtils.WB.allocateCodeBlob(size, btype.id)) != 0L
&& ((double) bean.getUsage().getUsed() <= CACHE_USAGE_COEF * maxSize)) {
blobs.add(blob);
}
}
@ -90,13 +101,13 @@ public class InitialAndMaxUsageTest {
Asserts.assertEQ(initialUsage, 0L, "Unexpected initial usage");
}
ArrayList<Long> blobs = new ArrayList<>();
long minAllocationUnit = Math.max(0, CodeCacheUtils.MIN_ALLOCATION - headerSize);
long minAllocationUnit = Math.max(1, CodeCacheUtils.MIN_ALLOCATION - headerSize);
/* now filling code cache with large-sized allocation first, since
lots of small allocations takes too much time, so, just a small
optimization */
try {
for (int coef = 1000000; coef > 0; coef /= 10) {
fillWithSize(coef * minAllocationUnit, blobs);
fillWithSize(coef * minAllocationUnit, blobs, bean);
}
Asserts.assertGT((double) bean.getUsage().getUsed(),
CACHE_USAGE_COEF * maxSize, String.format("Unable to fill "

View File

@ -31,11 +31,11 @@
* @build compiler.codecache.jmx.ThresholdNotificationsTest
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing
* -XX:+WhiteBoxAPI -XX:-MethodFlushing -XX:CompileCommand=compileonly,null::*
* -XX:+SegmentedCodeCache
* compiler.codecache.jmx.ThresholdNotificationsTest
* @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing
* -XX:+WhiteBoxAPI -XX:-MethodFlushing -XX:CompileCommand=compileonly,null::*
* -XX:-SegmentedCodeCache
* compiler.codecache.jmx.ThresholdNotificationsTest
@ -63,7 +63,9 @@ public class ThresholdNotificationsTest implements NotificationListener {
public static void main(String[] args) {
for (BlobType bt : BlobType.getAvailable()) {
new ThresholdNotificationsTest(bt).runTest();
if (CodeCacheUtils.isCodeHeapPredictable(bt)) {
new ThresholdNotificationsTest(bt).runTest();
}
}
}

View File

@ -63,7 +63,9 @@ public class UsageThresholdExceededTest {
public static void main(String[] args) {
int iterationsCount = Integer.getInteger("jdk.test.lib.iterations", 1);
for (BlobType btype : BlobType.getAvailable()) {
new UsageThresholdExceededTest(btype, iterationsCount).runTest();
if (CodeCacheUtils.isCodeHeapPredictable(btype)) {
new UsageThresholdExceededTest(btype, iterationsCount).runTest();
}
}
}

View File

@ -29,9 +29,9 @@
* @modules java.base/jdk.internal.misc
* java.management
*
* @build compiler.codecache.jmx.UsageThresholdIncreasedTest
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @build compiler.codecache.jmx.UsageThresholdIncreasedTest
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI -XX:-UseCodeCacheFlushing -XX:-MethodFlushing
* -XX:CompileCommand=compileonly,null::*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 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
@ -114,7 +114,7 @@ public class IntrinsicAvailableTest extends CompilerWhiteBoxTest {
public void test() throws Exception {
Executable intrinsicMethod = testCase.getExecutable();
if (Platform.isServer()) {
if (Platform.isServer() && (TIERED_STOP_AT_LEVEL == COMP_LEVEL_FULL_OPTIMIZATION)) {
if (TIERED_COMPILATION) {
checkIntrinsicForCompilationLevel(intrinsicMethod, COMP_LEVEL_SIMPLE);
}

View File

@ -59,9 +59,9 @@ public class IntrinsicDisabledTest {
private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4;
/* Determine if tiered compilation is enabled. */
private static boolean isTieredCompilationEnabled() {
return Boolean.valueOf(Objects.toString(wb.getVMFlag("TieredCompilation")));
}
private static final boolean TIERED_COMPILATION = wb.getBooleanVMFlag("TieredCompilation");
private static final int TIERED_STOP_AT_LEVEL = wb.getIntxVMFlag("TieredStopAtLevel").intValue();
/* This test uses several methods from jdk.internal.misc.Unsafe. The method
* getMethod() returns a different Executable for each different
@ -202,8 +202,8 @@ public class IntrinsicDisabledTest {
}
public static void main(String args[]) {
if (Platform.isServer()) {
if (isTieredCompilationEnabled()) {
if (Platform.isServer() && (TIERED_STOP_AT_LEVEL == COMP_LEVEL_FULL_OPTIMIZATION)) {
if (TIERED_COMPILATION) {
test(COMP_LEVEL_SIMPLE);
}
test(COMP_LEVEL_FULL_OPTIMIZATION);

View File

@ -273,8 +273,8 @@ public class CompilerToVMHelper {
return CTVM.getResolvedJavaMethod(base, displacement);
}
public static HotSpotConstantPool getConstantPool(Object base, long displacement) {
return CTVM.getConstantPool(base, displacement);
public static HotSpotConstantPool getConstantPool(Object object) {
return CTVM.getConstantPool(object);
}
public static HotSpotResolvedObjectType getResolvedJavaType(Object base,

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 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
* 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 compiler.jvmci.common.testcases;
public interface DuplicateSimpleSingleImplementerInterface {
void interfaceMethod();
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 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
* 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 compiler.jvmci.common.testcases;
public abstract class MultipleSuperImplementers implements DuplicateSimpleSingleImplementerInterface, SimpleSingleImplementerInterface {
public void finalize() {
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 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
* 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 compiler.jvmci.common.testcases;
public interface SimpleSingleImplementerInterface {
void interfaceMethod();
}

View File

@ -32,6 +32,8 @@
* java.base/jdk.internal.org.objectweb.asm.tree
* jdk.vm.ci/jdk.vm.ci.hotspot
* jdk.vm.ci/jdk.vm.ci.code
* jdk.vm.ci/jdk.vm.ci.meta
* jdk.vm.ci/jdk.vm.ci.runtime
* @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
* @build compiler.jvmci.compilerToVM.FindUniqueConcreteMethodTest
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
@ -41,7 +43,10 @@
package compiler.jvmci.compilerToVM;
import compiler.jvmci.common.CTVMUtilities;
import compiler.jvmci.common.testcases.DuplicateSimpleSingleImplementerInterface;
import compiler.jvmci.common.testcases.SimpleSingleImplementerInterface;
import compiler.jvmci.common.testcases.MultipleImplementer1;
import compiler.jvmci.common.testcases.MultipleSuperImplementers;
import compiler.jvmci.common.testcases.SingleImplementer;
import compiler.jvmci.common.testcases.SingleImplementerInterface;
import compiler.jvmci.common.testcases.SingleSubclass;
@ -96,6 +101,11 @@ public class FindUniqueConcreteMethodTest {
// static method
result.add(new TestCase(false, SingleSubclass.class,
SingleSubclass.class, "staticMethod"));
// interface method
result.add(new TestCase(false, MultipleSuperImplementers.class,
DuplicateSimpleSingleImplementerInterface.class, "interfaceMethod", false));
result.add(new TestCase(false, MultipleSuperImplementers.class,
SimpleSingleImplementerInterface.class, "interfaceMethod", false));
return result;
}
@ -103,7 +113,7 @@ public class FindUniqueConcreteMethodTest {
System.out.println(tcase);
Method method = tcase.holder.getDeclaredMethod(tcase.methodName);
HotSpotResolvedJavaMethod testMethod = CTVMUtilities
.getResolvedMethod(tcase.receiver, method);
.getResolvedMethod(tcase.methodFromReceiver ? tcase.receiver : tcase.holder, method);
HotSpotResolvedObjectType resolvedType = CompilerToVMHelper
.lookupType(Utils.toJVMTypeSignature(tcase.receiver), getClass(),
/* resolve = */ true);
@ -118,20 +128,25 @@ public class FindUniqueConcreteMethodTest {
public final Class<?> holder;
public final String methodName;
public final boolean isPositive;
public final boolean methodFromReceiver;
public TestCase(boolean isPositive, Class<?> clazz, Class<?> holder,
String methodName) {
String methodName, boolean methodFromReceiver) {
this.receiver = clazz;
this.methodName = methodName;
this.isPositive = isPositive;
this.holder = holder;
this.methodFromReceiver = methodFromReceiver;
}
public TestCase(boolean isPositive, Class<?> clazz, Class<?> holder, String methodName) {
this(isPositive, clazz, holder, methodName, true);
}
@Override
public String toString() {
return String.format("CASE: receiver=%s, holder=%s, method=%s,"
+ " isPositive=%s", receiver.getName(),
holder.getName(), methodName, isPositive);
return String.format("CASE: receiver=%s, holder=%s, method=%s, isPositive=%s, methodFromReceiver=%s",
receiver.getName(), holder.getName(), methodName, isPositive, methodFromReceiver);
}
}
}

View File

@ -29,187 +29,76 @@
* @library /testlibrary /test/lib /
* @library ../common/patches
* @modules java.base/jdk.internal.misc
* @modules jdk.vm.ci/jdk.vm.ci.hotspot
* @modules java.base/jdk.internal.org.objectweb.asm
java.base/jdk.internal.org.objectweb.asm.tree
jdk.vm.ci/jdk.vm.ci.hotspot
* jdk.vm.ci/jdk.vm.ci.meta
* jdk.vm.ci/jdk.vm.ci.code
*
* @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
* @build jdk.vm.ci/jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject
* @build compiler.jvmci.compilerToVM.GetConstantPoolTest
* @build sun.hotspot.WhiteBox
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* -XX:+UnlockDiagnosticVMOptions
* -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
* compiler.jvmci.compilerToVM.GetConstantPoolTest
*/
package compiler.jvmci.compilerToVM;
import jdk.internal.misc.Unsafe;
import jdk.test.lib.Utils;
import compiler.jvmci.common.CTVMUtilities;
import compiler.jvmci.common.testcases.TestCase;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject;
import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import jdk.vm.ci.meta.ConstantPool;
import sun.hotspot.WhiteBox;
import java.lang.reflect.Field;
import java.lang.reflect.Executable;
/**
* Tests for jdk.vm.ci.hotspot.CompilerToVM::getConstantPool method
*/
public class GetConstantPoolTest {
private static enum TestCase {
NULL_BASE {
@Override
ConstantPool getConstantPool() {
return CompilerToVMHelper.getConstantPool(null,
getPtrToCpAddress());
}
},
JAVA_METHOD_BASE {
@Override
ConstantPool getConstantPool() {
HotSpotResolvedJavaMethod methodInstance
= CompilerToVMHelper.getResolvedJavaMethodAtSlot(
TEST_CLASS, 0);
Field field;
try {
// jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl.metaspaceMethod
field = methodInstance.getClass()
.getDeclaredField("metaspaceMethod");
field.setAccessible(true);
field.set(methodInstance, getPtrToCpAddress());
} catch (ReflectiveOperationException e) {
throw new Error("TESTBUG : " + e, e);
}
return CompilerToVMHelper.getConstantPool(methodInstance, 0L);
}
},
CONSTANT_POOL_BASE {
@Override
ConstantPool getConstantPool() {
ConstantPool cpInst;
try {
cpInst = CompilerToVMHelper.getConstantPool(null,
getPtrToCpAddress());
Field field = CompilerToVMHelper.HotSpotConstantPoolClass()
.getDeclaredField("metaspaceConstantPool");
field.setAccessible(true);
field.set(cpInst, getPtrToCpAddress());
} catch (ReflectiveOperationException e) {
throw new Error("TESTBUG : " + e.getMessage(), e);
}
return CompilerToVMHelper.getConstantPool(cpInst, 0L);
}
},
CONSTANT_POOL_BASE_IN_TWO {
@Override
ConstantPool getConstantPool() {
long ptr = getPtrToCpAddress();
ConstantPool cpInst;
try {
cpInst = CompilerToVMHelper.getConstantPool(null, ptr);
Field field = CompilerToVMHelper.HotSpotConstantPoolClass()
.getDeclaredField("metaspaceConstantPool");
field.setAccessible(true);
field.set(cpInst, ptr / 2L);
} catch (ReflectiveOperationException e) {
throw new Error("TESTBUG : " + e.getMessage(), e);
}
return CompilerToVMHelper.getConstantPool(cpInst,
ptr - ptr / 2L);
}
},
CONSTANT_POOL_BASE_ZERO {
@Override
ConstantPool getConstantPool() {
long ptr = getPtrToCpAddress();
ConstantPool cpInst;
try {
cpInst = CompilerToVMHelper.getConstantPool(null, ptr);
Field field = CompilerToVMHelper.HotSpotConstantPoolClass()
.getDeclaredField("metaspaceConstantPool");
field.setAccessible(true);
field.set(cpInst, 0L);
} catch (ReflectiveOperationException e) {
throw new Error("TESTBUG : " + e.getMessage(), e);
}
return CompilerToVMHelper.getConstantPool(cpInst, ptr);
}
},
;
abstract ConstantPool getConstantPool();
public static void testMethod(Executable executable) {
test(CTVMUtilities.getResolvedMethod(executable));
}
private static final WhiteBox WB = WhiteBox.getWhiteBox();
private static final Unsafe UNSAFE = Utils.getUnsafe();
public static void testClass(Class cls) {
HotSpotResolvedObjectType type = CompilerToVMHelper
.lookupType(Utils.toJVMTypeSignature(cls),
GetConstantPoolTest.class, /* resolve = */ true);
test(type);
}
private static final Class TEST_CLASS = GetConstantPoolTest.class;
private static final long CP_ADDRESS
= WB.getConstantPool(GetConstantPoolTest.class);
public void test(TestCase testCase) {
System.out.println(testCase.name());
ConstantPool cp = testCase.getConstantPool();
String cpStringRep = cp.toString();
String cpClassSimpleName
= CompilerToVMHelper.HotSpotConstantPoolClass().getSimpleName();
if (!cpStringRep.contains(cpClassSimpleName)
|| !cpStringRep.contains(TEST_CLASS.getName())) {
String msg = String.format("%s : "
+ " Constant pool is not valid."
+ " String representation should contain \"%s\" and \"%s\"",
testCase.name(), cpClassSimpleName,
TEST_CLASS.getName());
throw new AssertionError(msg);
}
private static void test(Object object) {
ConstantPool cp = CompilerToVMHelper.getConstantPool(object);
System.out.println(object + " -> " + cp);
}
public static void main(String[] args) {
GetConstantPoolTest test = new GetConstantPoolTest();
for (TestCase testCase : TestCase.values()) {
test.test(testCase);
}
testObjectBase();
testMetaspaceWrapperBase();
TestCase.getAllClasses().forEach(GetConstantPoolTest::testClass);
TestCase.getAllExecutables().forEach(GetConstantPoolTest::testMethod);
testNull();
testObject();
}
private static void testObjectBase() {
private static void testNull() {
try {
Object cp = CompilerToVMHelper.getConstantPool(new Object(), 0L);
throw new AssertionError("Test OBJECT_BASE."
Object cp = CompilerToVMHelper.getConstantPool(null);
throw new AssertionError("Test OBJECT."
+ " Expected IllegalArgumentException has not been caught");
} catch (NullPointerException npe) {
// expected
}
}
private static void testObject() {
try {
Object cp = CompilerToVMHelper.getConstantPool(new Object());
throw new AssertionError("Test OBJECT."
+ " Expected IllegalArgumentException has not been caught");
} catch (IllegalArgumentException iae) {
// expected
}
}
private static void testMetaspaceWrapperBase() {
try {
Object cp = CompilerToVMHelper.getConstantPool(
new PublicMetaspaceWrapperObject() {
@Override
public long getMetaspacePointer() {
return getPtrToCpAddress();
}
}, 0L);
throw new AssertionError("Test METASPACE_WRAPPER_BASE."
+ " Expected IllegalArgumentException has not been caught");
} catch (IllegalArgumentException iae) {
// expected
}
}
private static long getPtrToCpAddress() {
Field field;
try {
field = TEST_CLASS.getDeclaredField("CP_ADDRESS");
} catch (NoSuchFieldException nsfe) {
throw new Error("TESTBUG : cannot find field \"CP_ADDRESS\" : "
+ nsfe.getMessage(), nsfe);
}
Object base = UNSAFE.staticFieldBase(field);
return WB.getObjectAddress(base) + UNSAFE.staticFieldOffset(field);
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 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
* 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 compiler.runtime.cr8015436;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
public class Driver8015436 {
public static void main(String args[]) {
OutputAnalyzer oa;
try {
oa = ProcessTools.executeProcess(ProcessTools.createJavaProcessBuilder(
/* add test vm options */ true, Test8015436.class.getName()));
} catch (Exception ex) {
throw new Error("TESTBUG: exception while running child process: " + ex, ex);
}
oa.shouldHaveExitValue(0);
oa.shouldContain(Test8015436.SOME_MTD_INVOKED);
oa.shouldContain(Test8015436.DEFAULT_MTD_INVOKED_DIRECTLY);
oa.shouldContain(Test8015436.DEFAULT_MTD_INVOKED_MH);
}
}

View File

@ -25,8 +25,12 @@
* @test
* @bug 8015436
* @summary the IK _initial_method_idnum value must be adjusted if overpass methods are added
* @library /test/lib/share/classes /
* @modules java.base/jdk.internal.misc
* @build compiler.runtime.cr8015436.Test8015436
* compiler.runtime.cr8015436.Driver8015436
*
* @run main compiler.runtime.cr8015436.Test8015436
* @run driver compiler.runtime.cr8015436.Driver8015436
*/
/*
@ -45,20 +49,24 @@ import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
public class Test8015436 implements InterfaceWithDefaultMethod {
public static final String SOME_MTD_INVOKED = "someMethod() invoked";
public static final String DEFAULT_MTD_INVOKED_DIRECTLY = "defaultMethod() invoked directly";
public static final String DEFAULT_MTD_INVOKED_MH = "defaultMethod() invoked via a MethodHandle";
@Override
public void someMethod() {
System.out.println("someMethod() invoked");
System.out.println(SOME_MTD_INVOKED);
}
public static void main(String[] args) throws Throwable {
Test8015436 testObj = new Test8015436();
testObj.someMethod();
testObj.defaultMethod("invoked directly");
testObj.defaultMethod(DEFAULT_MTD_INVOKED_DIRECTLY);
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType mt = MethodType.methodType(void.class, String.class);
MethodHandle mh = lookup.findVirtual(Test8015436.class, "defaultMethod", mt);
mh.invokeExact(testObj, "invoked via a MethodHandle");
mh.invokeExact(testObj, DEFAULT_MTD_INVOKED_MH);
}
}
@ -66,7 +74,7 @@ interface InterfaceWithDefaultMethod {
public void someMethod();
default public void defaultMethod(String str){
System.out.println("defaultMethod() " + str);
System.out.println(str);
}
}
/*

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 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
* 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
* @key nmt
* @summary Running with NMT detail should produce expected stack traces.
* @library /testlibrary
* @modules java.base/jdk.internal.misc
* java.management
*/
import jdk.test.lib.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CheckForProperDetailStackTrace {
/* The stack trace we look for by default. Note that :: has been replaced by .*
to make sure it maches even if the symbol is not unmangled. */
public static String stackTraceDefault =
".*ModuleEntryTable.*new_entry.*\n" +
".*ModuleEntryTable.*locked_create_entry_or_null.*\n" +
".*Modules.*define_module.*\n" +
".*JVM_DefineModule.*\n";
/* The stack trace we look for on Solaris and Windows slowdebug builds. For some
reason ALWAYSINLINE for AllocateHeap is ignored, so it appears in the stack strace. */
public static String stackTraceAllocateHeap =
".*AllocateHeap.*\n" +
".*ModuleEntryTable.*new_entry.*\n" +
".*ModuleEntryTable.*locked_create_entry_or_null.*\n" +
".*Modules.*define_module.*\n";
/* A symbol that should always be present in NMT detail output. */
private static String expectedSymbol =
"locked_create_entry_or_null";
private static final String jdkDebug = System.getProperty("jdk.debug");
private static boolean isSlowDebugBuild() {
return (jdkDebug.toLowerCase().equals("slowdebug"));
}
public static void main(String args[]) throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockDiagnosticVMOptions",
"-XX:NativeMemoryTracking=detail",
"-XX:+PrintNMTStatistics",
"-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0);
// We should never see either of these frames because they are supposed to be skipped. */
output.shouldNotContain("NativeCallStack::NativeCallStack");
output.shouldNotContain("os::get_native_stack");
// AllocateHeap shouldn't be in the output because it is suppose to always be inlined.
// We check for that here, but allow it for Windows and Solaris slowdebug builds because
// the compiler ends up not inlining AllocateHeap.
Boolean okToHaveAllocateHeap =
isSlowDebugBuild() && (Platform.isSolaris() || Platform.isWindows());
if (!okToHaveAllocateHeap) {
output.shouldNotContain("AllocateHeap");
}
// See if we have any stack trace symbols in the output
boolean hasSymbols =
output.getStdout().contains(expectedSymbol) || output.getStderr().contains(expectedSymbol);
if (!hasSymbols) {
// It's ok for ARM not to have symbols, because it does not support NMT detail
// when targeting thumb2. It's also ok for Windows not to have symbols, because
// they are only available if the symbols file is included with the build.
if (Platform.isWindows() || Platform.isARM()) {
return; // we are done
}
output.reportDiagnosticSummary();
throw new RuntimeException("Expected symbol missing missing from output: " + expectedSymbol);
}
/* Make sure the expected NMT detail stack trace is found. */
String expectedStackTrace =
(okToHaveAllocateHeap ? stackTraceAllocateHeap : stackTraceDefault);
if (!stackTraceMatches(expectedStackTrace, output)) {
output.reportDiagnosticSummary();
throw new RuntimeException("Expected stack trace missing missing from output: " + expectedStackTrace);
}
}
public static boolean stackTraceMatches(String stackTrace, OutputAnalyzer output) {
Matcher stdoutMatcher = Pattern.compile(stackTrace, Pattern.MULTILINE).matcher(output.getStdout());
Matcher stderrMatcher = Pattern.compile(stackTrace, Pattern.MULTILINE).matcher(output.getStderr());
return (stdoutMatcher.find() || stderrMatcher.find());
}
}

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 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
* 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
* @summary Creates an anonymous class inside of an anonymous class.
* @library /testlibrary
* @modules java.base/jdk.internal.misc
* java.compiler
* java.management
* @run main NestedUnsafe
*/
import java.security.ProtectionDomain;
import java.io.InputStream;
import java.lang.*;
import jdk.test.lib.*;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
// package p;
public class NestedUnsafe {
// The String concatenation should create the nested anonymous class.
static byte klassbuf[] = InMemoryJavaCompiler.compile("TestClass",
"public class TestClass { " +
" public static void concat(String one, String two) throws Throwable { " +
" System.out.println(one + two);" +
" } } ");
public static void main(String args[]) throws Exception {
Unsafe unsafe = Utils.getUnsafe();
Class klass = unsafe.defineAnonymousClass(NestedUnsafe.class, klassbuf, new Object[0]);
unsafe.ensureClassInitialized(klass);
Class[] cArgs = new Class[2];
cArgs[0] = String.class;
cArgs[1] = String.class;
try {
klass.getMethod("concat", cArgs).invoke(null, "AA", "BB");
} catch (Throwable ex) {
throw new RuntimeException("Exception: " + ex.toString());
}
// The anonymous class calls defineAnonymousClass creating a nested anonymous class.
byte klassbuf2[] = InMemoryJavaCompiler.compile("TestClass2",
"import jdk.internal.misc.Unsafe; " +
"public class TestClass2 { " +
" public static void doit() throws Throwable { " +
" Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe(); " +
" Class klass2 = unsafe.defineAnonymousClass(TestClass2.class, NestedUnsafe.klassbuf, new Object[0]); " +
" unsafe.ensureClassInitialized(klass2); " +
" Class[] dArgs = new Class[2]; " +
" dArgs[0] = String.class; " +
" dArgs[1] = String.class; " +
" try { " +
" klass2.getMethod(\"concat\", dArgs).invoke(null, \"CC\", \"DD\"); " +
" } catch (Throwable ex) { " +
" throw new RuntimeException(\"Exception: \" + ex.toString()); " +
" } " +
"} } ",
"-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED");
Class klass2 = unsafe.defineAnonymousClass(NestedUnsafe.class, klassbuf2, new Object[0]);
try {
klass2.getMethod("doit").invoke(null);
} catch (Throwable ex) {
throw new RuntimeException("Exception: " + ex.toString());
}
}
}