8219403: JVMCIRuntime::adjust_comp_level should be replaced

Reviewed-by: kvn, dnsimon, never
This commit is contained in:
Dean Long 2019-04-24 09:10:45 -07:00
parent c73580342f
commit 61f35bf898
13 changed files with 104 additions and 186 deletions

View File

@ -23,6 +23,7 @@
#include "precompiled.hpp"
#include "jvm.h"
#include "classfile/moduleEntry.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
@ -190,15 +191,6 @@ void JVMCICompiler::compile_method(const methodHandle& method, int entry_bci, JV
}
}
CompLevel JVMCIRuntime::adjust_comp_level(const methodHandle& method, bool is_osr, CompLevel level, JavaThread* thread) {
if (!thread->adjusting_comp_level()) {
thread->set_adjusting_comp_level(true);
level = adjust_comp_level_inner(method, is_osr, level, thread);
thread->set_adjusting_comp_level(false);
}
return level;
}
void JVMCICompiler::exit_on_pending_exception(oop exception, const char* message) {
JavaThread* THREAD = JavaThread::current();
CLEAR_PENDING_EXCEPTION;
@ -235,3 +227,33 @@ void JVMCICompiler::print_compilation_timers() {
TRACE_jvmci_1("JVMCICompiler::print_timers");
tty->print_cr(" JVMCI code install time: %6.3f s", _codeInstallTimer.seconds());
}
bool JVMCICompiler::force_comp_at_level_simple(Method *method) {
JVMCI_EXCEPTION_CONTEXT
if (_bootstrapping) {
// When bootstrapping, the JVMCI compiler can compile its own methods.
return false;
}
if (!JVMCIRuntime::is_HotSpotJVMCIRuntime_initialized()) {
// JVMCI cannot participate in compilation scheduling until
// JVMCI is initialized and indicates it wants to participate.
return false;
}
// Support for graal.CompileGraalWithC1Only
HandleMark hm(thread);
jobject runtime = JVMCIRuntime::get_HotSpotJVMCIRuntime_jobject(CATCH);
objArrayHandle excludeFromJVMCICompilation(thread, HotSpotJVMCIRuntime::excludeFromJVMCICompilation(runtime));
if (excludeFromJVMCICompilation.is_null()) {
return false;
}
ModuleEntry *module = method->method_holder()->module();
for (int i = 0; i < excludeFromJVMCICompilation->length(); ++i) {
if (module->module() == excludeFromJVMCICompilation->obj_at(i)) {
return true;
}
}
return false;
}

View File

@ -85,6 +85,9 @@ public:
*/
void bootstrap(TRAPS);
// Should force compilation of method at CompLevel_simple?
bool force_comp_at_level_simple(Method* method);
bool is_bootstrapping() const { return _bootstrapping; }
// Compilation entry point for methods

View File

@ -312,7 +312,7 @@ class JVMCIJavaClasses : AllStatic {
long_field(HotSpotConstantPool, metaspaceConstantPool) \
end_class \
start_class(HotSpotJVMCIRuntime) \
int_field(HotSpotJVMCIRuntime, compilationLevelAdjustment) \
objArrayOop_field(HotSpotJVMCIRuntime, excludeFromJVMCICompilation, "[Ljava/lang/Module;") \
end_class \
/* end*/

View File

@ -25,6 +25,7 @@
#include "jvm.h"
#include "asm/codeBuffer.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "classfile/moduleEntry.hpp"
#include "code/codeCache.hpp"
#include "code/compiledMethod.inline.hpp"
#include "compiler/compileBroker.hpp"
@ -60,9 +61,7 @@
#endif
jobject JVMCIRuntime::_HotSpotJVMCIRuntime_instance = NULL;
bool JVMCIRuntime::_HotSpotJVMCIRuntime_initialized = false;
bool JVMCIRuntime::_well_known_classes_initialized = false;
JVMCIRuntime::CompLevelAdjustment JVMCIRuntime::_comp_level_adjustment = JVMCIRuntime::none;
bool JVMCIRuntime::_shutdown_called = false;
BasicType JVMCIRuntime::kindToBasicType(Handle kind, TRAPS) {
@ -740,7 +739,7 @@ Handle JVMCIRuntime::get_HotSpotJVMCIRuntime(TRAPS) {
}
void JVMCIRuntime::initialize_HotSpotJVMCIRuntime(TRAPS) {
guarantee(!_HotSpotJVMCIRuntime_initialized, "cannot reinitialize HotSpotJVMCIRuntime");
guarantee(!is_HotSpotJVMCIRuntime_initialized(), "cannot reinitialize HotSpotJVMCIRuntime");
JVMCIRuntime::initialize_well_known_classes(CHECK);
// This should only be called in the context of the JVMCI class being initialized
InstanceKlass* klass = SystemDictionary::JVMCI_klass();
@ -750,12 +749,6 @@ void JVMCIRuntime::initialize_HotSpotJVMCIRuntime(TRAPS) {
Handle result = callStatic("jdk/vm/ci/hotspot/HotSpotJVMCIRuntime",
"runtime",
"()Ljdk/vm/ci/hotspot/HotSpotJVMCIRuntime;", NULL, CHECK);
int adjustment = HotSpotJVMCIRuntime::compilationLevelAdjustment(result);
assert(adjustment >= JVMCIRuntime::none &&
adjustment <= JVMCIRuntime::by_full_signature,
"compilation level adjustment out of bounds");
_comp_level_adjustment = (CompLevelAdjustment) adjustment;
_HotSpotJVMCIRuntime_initialized = true;
_HotSpotJVMCIRuntime_instance = JNIHandles::make_global(result);
}
@ -765,7 +758,7 @@ void JVMCIRuntime::initialize_JVMCI(TRAPS) {
"getRuntime",
"()Ljdk/vm/ci/runtime/JVMCIRuntime;", NULL, CHECK);
}
assert(_HotSpotJVMCIRuntime_initialized == true, "what?");
assert(is_HotSpotJVMCIRuntime_initialized(), "what?");
}
bool JVMCIRuntime::can_initialize_JVMCI() {
@ -894,73 +887,6 @@ void JVMCIRuntime::shutdown(TRAPS) {
}
}
CompLevel JVMCIRuntime::adjust_comp_level_inner(const methodHandle& method, bool is_osr, CompLevel level, JavaThread* thread) {
JVMCICompiler* compiler = JVMCICompiler::instance(false, thread);
if (compiler != NULL && compiler->is_bootstrapping()) {
return level;
}
if (!is_HotSpotJVMCIRuntime_initialized() || _comp_level_adjustment == JVMCIRuntime::none) {
// JVMCI cannot participate in compilation scheduling until
// JVMCI is initialized and indicates it wants to participate.
return level;
}
#define CHECK_RETURN THREAD); \
if (HAS_PENDING_EXCEPTION) { \
Handle exception(THREAD, PENDING_EXCEPTION); \
CLEAR_PENDING_EXCEPTION; \
\
if (exception->is_a(SystemDictionary::ThreadDeath_klass())) { \
/* In the special case of ThreadDeath, we need to reset the */ \
/* pending async exception so that it is propagated. */ \
thread->set_pending_async_exception(exception()); \
return level; \
} \
tty->print("Uncaught exception while adjusting compilation level: "); \
java_lang_Throwable::print(exception(), tty); \
tty->cr(); \
java_lang_Throwable::print_stack_trace(exception, tty); \
if (HAS_PENDING_EXCEPTION) { \
CLEAR_PENDING_EXCEPTION; \
} \
return level; \
} \
(void)(0
Thread* THREAD = thread;
HandleMark hm;
Handle receiver = JVMCIRuntime::get_HotSpotJVMCIRuntime(CHECK_RETURN);
Handle name;
Handle sig;
if (_comp_level_adjustment == JVMCIRuntime::by_full_signature) {
name = java_lang_String::create_from_symbol(method->name(), CHECK_RETURN);
sig = java_lang_String::create_from_symbol(method->signature(), CHECK_RETURN);
} else {
name = Handle();
sig = Handle();
}
JavaValue result(T_INT);
JavaCallArguments args;
args.push_oop(receiver);
args.push_oop(Handle(THREAD, method->method_holder()->java_mirror()));
args.push_oop(name);
args.push_oop(sig);
args.push_int(is_osr);
args.push_int(level);
JavaCalls::call_special(&result, receiver->klass(), vmSymbols::adjustCompilationLevel_name(),
vmSymbols::adjustCompilationLevel_signature(), &args, CHECK_RETURN);
int comp_level = result.get_jint();
if (comp_level < CompLevel_none || comp_level > CompLevel_full_optimization) {
assert(false, "compilation level out of bounds");
return level;
}
return (CompLevel) comp_level;
#undef CHECK_RETURN
}
void JVMCIRuntime::bootstrap_finished(TRAPS) {
HandleMark hm(THREAD);
Handle receiver = get_HotSpotJVMCIRuntime(CHECK);

View File

@ -53,18 +53,13 @@ class JVMCIRuntime: public AllStatic {
private:
static jobject _HotSpotJVMCIRuntime_instance;
static bool _HotSpotJVMCIRuntime_initialized;
static bool _well_known_classes_initialized;
static CompLevelAdjustment _comp_level_adjustment;
static bool _shutdown_called;
static CompLevel adjust_comp_level_inner(const methodHandle& method, bool is_osr, CompLevel level, JavaThread* thread);
public:
static bool is_HotSpotJVMCIRuntime_initialized() {
return _HotSpotJVMCIRuntime_initialized;
return _HotSpotJVMCIRuntime_instance != NULL;
}
/**
@ -74,7 +69,7 @@ class JVMCIRuntime: public AllStatic {
static jobject get_HotSpotJVMCIRuntime_jobject(TRAPS) {
initialize_JVMCI(CHECK_NULL);
assert(_HotSpotJVMCIRuntime_initialized, "must be");
assert(_HotSpotJVMCIRuntime_instance != NULL, "must be");
return _HotSpotJVMCIRuntime_instance;
}
@ -107,18 +102,6 @@ class JVMCIRuntime: public AllStatic {
return _shutdown_called;
}
/**
* Lets JVMCI modify the compilation level currently selected for a method by
* the VM compilation policy.
*
* @param method the method being scheduled for compilation
* @param is_osr specifies if the compilation is an OSR compilation
* @param level the compilation level currently selected by the VM compilation policy
* @param thread the current thread
* @return the compilation level to use for the compilation
*/
static CompLevel adjust_comp_level(const methodHandle& method, bool is_osr, CompLevel level, JavaThread* thread);
static BasicType kindToBasicType(Handle kind, TRAPS);
static void new_instance_common(JavaThread* thread, Klass* klass, bool null_on_fail);

View File

@ -94,8 +94,6 @@
template(jdk_vm_ci_common_JVMCIError, "jdk/vm/ci/common/JVMCIError") \
template(visitFrame_name, "visitFrame") \
template(visitFrame_signature, "(Ljdk/vm/ci/code/stack/InspectedFrame;)Ljava/lang/Object;") \
template(adjustCompilationLevel_name, "adjustCompilationLevel") \
template(adjustCompilationLevel_signature, "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;ZI)I") \
template(compileMethod_name, "compileMethod") \
template(compileMethod_signature, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;IJI)Ljdk/vm/ci/hotspot/HotSpotCompilationRequestResult;") \
template(fromMetaspace_name, "fromMetaspace") \

View File

@ -1628,7 +1628,6 @@ void JavaThread::initialize() {
_pending_deoptimization = -1;
_pending_failed_speculation = 0;
_pending_transfer_to_interpreter = false;
_adjusting_comp_level = false;
_in_retryable_allocation = false;
_jvmci._alternate_call_target = NULL;
assert(_jvmci._implicit_exception_pc == NULL, "must be");

View File

@ -1126,9 +1126,6 @@ class JavaThread: public Thread {
// Specifies if the DeoptReason for the last uncommon trap was Reason_transfer_to_interpreter
bool _pending_transfer_to_interpreter;
// Guard for re-entrant call to JVMCIRuntime::adjust_comp_level
bool _adjusting_comp_level;
// True if in a runtime call from compiled code that will deoptimize
// and re-execute a failed heap allocation in the interpreter.
bool _in_retryable_allocation;
@ -1536,8 +1533,6 @@ class JavaThread: public Thread {
#if INCLUDE_JVMCI
int pending_deoptimization() const { return _pending_deoptimization; }
long pending_failed_speculation() const { return _pending_failed_speculation; }
bool adjusting_comp_level() const { return _adjusting_comp_level; }
void set_adjusting_comp_level(bool b) { _adjusting_comp_level = b; }
bool has_pending_monitorenter() const { return _pending_monitorenter; }
void set_pending_monitorenter(bool b) { _pending_monitorenter = b; }
void set_pending_deoptimization(int reason) { _pending_deoptimization = reason; }

View File

@ -91,6 +91,21 @@ bool TieredThresholdPolicy::is_trivial(Method* method) {
return false;
}
bool TieredThresholdPolicy::should_compile_at_level_simple(Method* method) {
if (TieredThresholdPolicy::is_trivial(method)) {
return true;
}
#if INCLUDE_JVMCI
if (UseJVMCICompiler) {
AbstractCompiler* comp = CompileBroker::compiler(CompLevel_full_optimization);
if (comp != NULL && comp->is_jvmci() && ((JVMCICompiler*) comp)->force_comp_at_level_simple(method)) {
return true;
}
}
#endif
return false;
}
CompLevel TieredThresholdPolicy::comp_level(Method* method) {
CompiledMethod *nm = method->code();
if (nm != NULL && nm->is_in_use()) {
@ -613,7 +628,7 @@ bool TieredThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level, Me
// Determine is a method is mature.
bool TieredThresholdPolicy::is_mature(Method* method) {
if (is_trivial(method)) return true;
if (should_compile_at_level_simple(method)) return true;
MethodData* mdo = method->method_data();
if (mdo != NULL) {
int i = mdo->invocation_count();
@ -709,7 +724,7 @@ CompLevel TieredThresholdPolicy::common(Predicate p, Method* method, CompLevel c
int i = method->invocation_count();
int b = method->backedge_count();
if (is_trivial(method)) {
if (should_compile_at_level_simple(method)) {
next_level = CompLevel_simple;
} else {
switch(cur_level) {
@ -825,11 +840,6 @@ CompLevel TieredThresholdPolicy::call_event(Method* method, CompLevel cur_level,
} else {
next_level = MAX2(osr_level, next_level);
}
#if INCLUDE_JVMCI
if (UseJVMCICompiler) {
next_level = JVMCIRuntime::adjust_comp_level(method, false, next_level, thread);
}
#endif
return next_level;
}
@ -844,11 +854,6 @@ CompLevel TieredThresholdPolicy::loop_event(Method* method, CompLevel cur_level,
return osr_level;
}
}
#if INCLUDE_JVMCI
if (UseJVMCICompiler) {
next_level = JVMCIRuntime::adjust_comp_level(method, true, next_level, thread);
}
#endif
return next_level;
}

View File

@ -231,7 +231,9 @@ protected:
virtual void submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread);
// Simple methods are as good being compiled with C1 as C2.
// This function tells if it's such a function.
inline bool is_trivial(Method* method);
inline static bool is_trivial(Method* method);
// Force method to be compiled at CompLevel_simple?
inline static bool should_compile_at_level_simple(Method* method);
// Predicate helpers are used by .*_predicate() methods as well as others.
// They check the given counter values, multiplied by the scale against the thresholds.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, 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
@ -46,7 +46,7 @@ import jdk.vm.ci.code.CompiledCode;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.common.InitTimer;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory.CompilationLevel;
import jdk.vm.ci.common.NativeImageReinitialize;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaType;
@ -58,6 +58,8 @@ import jdk.vm.ci.runtime.JVMCICompilerFactory;
import jdk.vm.ci.runtime.JVMCIRuntime;
import jdk.vm.ci.services.JVMCIServiceLocator;
import static jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory.CompilationLevelAdjustment.None;
/**
* HotSpot implementation of a JVMCI runtime.
*
@ -251,10 +253,11 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime {
final HotSpotJVMCIMetaAccessContext metaAccessContext;
/**
* Stores the result of {@link HotSpotJVMCICompilerFactory#getCompilationLevelAdjustment} so
* that it can be read from the VM.
* Stores the value set by {@link #excludeFromJVMCICompilation(Module...)} so that it can
* be read from the VM.
*/
@SuppressWarnings("unused") private final int compilationLevelAdjustment;
@SuppressWarnings("unused") @NativeImageReinitialize private Module[] excludeFromJVMCICompilation;
private final Map<Class<? extends Architecture>, JVMCIBackend> backends = new HashMap<>();
@ -296,23 +299,14 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime {
compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory();
if (compilerFactory instanceof HotSpotJVMCICompilerFactory) {
hsCompilerFactory = (HotSpotJVMCICompilerFactory) compilerFactory;
switch (hsCompilerFactory.getCompilationLevelAdjustment()) {
case None:
compilationLevelAdjustment = config.compLevelAdjustmentNone;
break;
case ByHolder:
compilationLevelAdjustment = config.compLevelAdjustmentByHolder;
break;
case ByFullSignature:
compilationLevelAdjustment = config.compLevelAdjustmentByFullSignature;
break;
default:
compilationLevelAdjustment = config.compLevelAdjustmentNone;
break;
if (hsCompilerFactory.getCompilationLevelAdjustment() != None) {
String name = HotSpotJVMCICompilerFactory.class.getName();
String msg = String.format("%s.getCompilationLevelAdjustment() is no longer supported. " +
"Use %s.excludeFromJVMCICompilation() instead.", name, name);
throw new UnsupportedOperationException(msg);
}
} else {
hsCompilerFactory = null;
compilationLevelAdjustment = config.compLevelAdjustmentNone;
}
if (config.getFlag("JVMCIPrintProperties", Boolean.class)) {
@ -480,42 +474,6 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime {
return Collections.unmodifiableMap(backends);
}
/**
* Called from the VM.
*/
@SuppressWarnings({"unused"})
private int adjustCompilationLevel(Class<?> declaringClass, String name, String signature, boolean isOsr, int level) {
CompilationLevel curLevel;
if (level == config.compilationLevelNone) {
curLevel = CompilationLevel.None;
} else if (level == config.compilationLevelSimple) {
curLevel = CompilationLevel.Simple;
} else if (level == config.compilationLevelLimitedProfile) {
curLevel = CompilationLevel.LimitedProfile;
} else if (level == config.compilationLevelFullProfile) {
curLevel = CompilationLevel.FullProfile;
} else if (level == config.compilationLevelFullOptimization) {
curLevel = CompilationLevel.FullOptimization;
} else {
throw JVMCIError.shouldNotReachHere();
}
switch (hsCompilerFactory.adjustCompilationLevel(declaringClass, name, signature, isOsr, curLevel)) {
case None:
return config.compilationLevelNone;
case Simple:
return config.compilationLevelSimple;
case LimitedProfile:
return config.compilationLevelLimitedProfile;
case FullProfile:
return config.compilationLevelFullProfile;
case FullOptimization:
return config.compilationLevelFullOptimization;
default:
return level;
}
}
/**
* Called from the VM.
*/
@ -730,4 +688,14 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime {
public void registerNativeMethods(Class<?> clazz) {
throw new UnsatisfiedLinkError("SVM library is not available");
}
/**
* Informs HotSpot that no method whose module is in {@code modules} is to be compiled
* with {@link #compileMethod}.
*
* @param modules the set of modules containing JVMCI compiler classes
*/
public void excludeFromJVMCICompilation(Module...modules) {
this.excludeFromJVMCICompilation = modules.clone();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2019, 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,10 @@
package org.graalvm.compiler.hotspot;
import static jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory.CompilationLevelAdjustment.None;
import org.graalvm.compiler.debug.GraalError;
import jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
@ -56,16 +60,17 @@ class IsGraalPredicate extends IsGraalPredicateBase {
@Override
void onCompilerConfigurationFactorySelection(HotSpotJVMCIRuntime runtime, CompilerConfigurationFactory factory) {
compilerConfigurationModule = factory.getClass().getModule();
runtime.excludeFromJVMCICompilation(jvmciModule, graalModule, compilerConfigurationModule);
}
@Override
boolean apply(Class<?> declaringClass) {
Module module = declaringClass.getModule();
return jvmciModule == module || graalModule == module || compilerConfigurationModule == module;
throw GraalError.shouldNotReachHere();
}
@Override
HotSpotJVMCICompilerFactory.CompilationLevelAdjustment getCompilationLevelAdjustment() {
return HotSpotJVMCICompilerFactory.CompilationLevelAdjustment.ByHolder;
return None;
}
}

View File

@ -221,6 +221,18 @@ compiler/jsr292/InvokerSignatureMismatch.java 8221577 generic-all
compiler/arguments/TestScavengeRootsInCode.java 8207267 generic-all
compiler/loopopts/TestOverunrolling.java 8207267 generic-all
runtime/exceptionMsgs/AbstractMethodError/AbstractMethodErrorTest.java 8222582 generic-all
vmTestbase/nsk/jdi/ObjectReference/referringObjects/referringObjects002/referringObjects002.java 8220032 generic-all
vmTestbase/nsk/jdi/VirtualMachine/instanceCounts/instancecounts003/instancecounts003.java 8220032 generic-all
vmTestbase/nsk/jdi/ClassLoaderReference/definedClasses/definedclasses003/TestDescription.java 8222422 generic-all
vmTestbase/nsk/jdi/ClassLoaderReference/definedClasses/definedclasses005/TestDescription.java 8222422 generic-all
runtime/exceptionMsgs/ArrayIndexOutOfBoundsException/ArrayIndexOutOfBoundsExceptionTest.java 8222292 generic-all
serviceability/dcmd/compiler/CodelistTest.java 8220449 generic-all
# Graal unit tests
org.graalvm.compiler.core.test.CheckGraalInvariants 8205081
org.graalvm.compiler.core.test.OptionsVerifierTest 8205081