mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8309390: [JVMCI] improve copying system properties into libgraal
Reviewed-by: never, kvn
This commit is contained in:
parent
63843b1153
commit
c0aa6bf4fe
19 changed files with 453 additions and 197 deletions
|
@ -754,7 +754,6 @@
|
||||||
do_alias(appendToClassPathForInstrumentation_signature, string_void_signature) \
|
do_alias(appendToClassPathForInstrumentation_signature, string_void_signature) \
|
||||||
template(serializePropertiesToByteArray_name, "serializePropertiesToByteArray") \
|
template(serializePropertiesToByteArray_name, "serializePropertiesToByteArray") \
|
||||||
template(serializeAgentPropertiesToByteArray_name, "serializeAgentPropertiesToByteArray") \
|
template(serializeAgentPropertiesToByteArray_name, "serializeAgentPropertiesToByteArray") \
|
||||||
template(serializeSavedPropertiesToByteArray_name, "serializeSavedPropertiesToByteArray") \
|
|
||||||
template(encodeThrowable_name, "encodeThrowable") \
|
template(encodeThrowable_name, "encodeThrowable") \
|
||||||
template(encodeThrowable_signature, "(Ljava/lang/Throwable;JI)I") \
|
template(encodeThrowable_signature, "(Ljava/lang/Throwable;JI)I") \
|
||||||
template(decodeAndThrowThrowable_name, "decodeAndThrowThrowable") \
|
template(decodeAndThrowThrowable_name, "decodeAndThrowThrowable") \
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "oops/typeArrayOop.inline.hpp"
|
#include "oops/typeArrayOop.inline.hpp"
|
||||||
#include "prims/jvmtiExport.hpp"
|
#include "prims/jvmtiExport.hpp"
|
||||||
#include "runtime/deoptimization.hpp"
|
#include "runtime/deoptimization.hpp"
|
||||||
|
#include "runtime/fieldDescriptor.inline.hpp"
|
||||||
#include "runtime/jniHandles.inline.hpp"
|
#include "runtime/jniHandles.inline.hpp"
|
||||||
#include "runtime/javaCalls.hpp"
|
#include "runtime/javaCalls.hpp"
|
||||||
#include "runtime/thread.inline.hpp"
|
#include "runtime/thread.inline.hpp"
|
||||||
|
@ -45,9 +46,6 @@
|
||||||
#include "jvmci/jvmciCompiler.hpp"
|
#include "jvmci/jvmciCompiler.hpp"
|
||||||
#include "jvmci/jvmciRuntime.hpp"
|
#include "jvmci/jvmciRuntime.hpp"
|
||||||
|
|
||||||
jbyte* JVMCIEnv::_serialized_saved_properties = nullptr;
|
|
||||||
int JVMCIEnv::_serialized_saved_properties_len = 0;
|
|
||||||
|
|
||||||
JVMCICompileState::JVMCICompileState(CompileTask* task, JVMCICompiler* compiler):
|
JVMCICompileState::JVMCICompileState(CompileTask* task, JVMCICompiler* compiler):
|
||||||
_task(task),
|
_task(task),
|
||||||
_compiler(compiler),
|
_compiler(compiler),
|
||||||
|
@ -117,76 +115,6 @@ bool JVMCICompileState::jvmti_state_changed() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
jbyte* JVMCIEnv::get_serialized_saved_properties(int& props_len, TRAPS) {
|
|
||||||
jbyte* props = _serialized_saved_properties;
|
|
||||||
if (props == nullptr) {
|
|
||||||
// load VMSupport
|
|
||||||
Symbol* klass = vmSymbols::jdk_internal_vm_VMSupport();
|
|
||||||
Klass* k = SystemDictionary::resolve_or_fail(klass, true, CHECK_NULL);
|
|
||||||
|
|
||||||
InstanceKlass* ik = InstanceKlass::cast(k);
|
|
||||||
if (ik->should_be_initialized()) {
|
|
||||||
ik->initialize(CHECK_NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// invoke the serializeSavedPropertiesToByteArray method
|
|
||||||
JavaValue result(T_OBJECT);
|
|
||||||
JavaCallArguments args;
|
|
||||||
|
|
||||||
Symbol* signature = vmSymbols::void_byte_array_signature();
|
|
||||||
JavaCalls::call_static(&result,
|
|
||||||
ik,
|
|
||||||
vmSymbols::serializeSavedPropertiesToByteArray_name(),
|
|
||||||
signature,
|
|
||||||
&args,
|
|
||||||
CHECK_NULL);
|
|
||||||
|
|
||||||
oop res = result.get_oop();
|
|
||||||
assert(res->is_typeArray(), "must be");
|
|
||||||
assert(TypeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "must be");
|
|
||||||
typeArrayOop ba = typeArrayOop(res);
|
|
||||||
props_len = ba->length();
|
|
||||||
|
|
||||||
// Copy serialized saved properties from HotSpot object into C heap
|
|
||||||
props = NEW_C_HEAP_ARRAY(jbyte, props_len, mtJVMCI);
|
|
||||||
memcpy(props, ba->byte_at_addr(0), props_len);
|
|
||||||
|
|
||||||
_serialized_saved_properties_len = props_len;
|
|
||||||
_serialized_saved_properties = props;
|
|
||||||
} else {
|
|
||||||
props_len = _serialized_saved_properties_len;
|
|
||||||
}
|
|
||||||
return props;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JVMCIEnv::copy_saved_properties(jbyte* properties, int properties_len, JVMCI_TRAPS) {
|
|
||||||
assert(!is_hotspot(), "can only copy saved properties from HotSpot to native image");
|
|
||||||
JavaThread* thread = JavaThread::current(); // For exception macros.
|
|
||||||
|
|
||||||
// Copy native buffer into shared library object
|
|
||||||
JVMCIPrimitiveArray buf = new_byteArray(properties_len, this);
|
|
||||||
if (has_pending_exception()) {
|
|
||||||
_runtime->fatal_exception(JVMCIENV, "Error in copy_saved_properties");
|
|
||||||
}
|
|
||||||
copy_bytes_from(properties, buf, 0, properties_len);
|
|
||||||
if (has_pending_exception()) {
|
|
||||||
_runtime->fatal_exception(JVMCIENV, "Error in copy_saved_properties");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize saved properties in shared library
|
|
||||||
jclass servicesClass = JNIJVMCI::Services::clazz();
|
|
||||||
jmethodID initializeSavedProperties = JNIJVMCI::Services::initializeSavedProperties_method();
|
|
||||||
bool exception = false;
|
|
||||||
{
|
|
||||||
JNIAccessMark jni(this, thread);
|
|
||||||
jni()->CallStaticVoidMethod(servicesClass, initializeSavedProperties, buf.as_jobject());
|
|
||||||
exception = jni()->ExceptionCheck();
|
|
||||||
}
|
|
||||||
if (exception) {
|
|
||||||
_runtime->fatal_exception(JVMCIENV, "Error calling jdk.vm.ci.services.Services.initializeSavedProperties");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env, bool jni_enomem_is_fatal) {
|
void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env, bool jni_enomem_is_fatal) {
|
||||||
assert(thread != nullptr, "npe");
|
assert(thread != nullptr, "npe");
|
||||||
_env = nullptr;
|
_env = nullptr;
|
||||||
|
@ -1937,7 +1865,7 @@ nmethod* JVMCIEnv::get_nmethod(JVMCIObject obj) {
|
||||||
}
|
}
|
||||||
#define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST)
|
#define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST)
|
||||||
#define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
|
#define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
|
||||||
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)
|
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName)
|
||||||
#define CONSTRUCTOR(className, signature)
|
#define CONSTRUCTOR(className, signature)
|
||||||
|
|
||||||
JVMCI_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, PRIMARRAY_FIELD, OBJECTARRAY_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECTARRAY_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR)
|
JVMCI_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, PRIMARRAY_FIELD, OBJECTARRAY_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECTARRAY_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR)
|
||||||
|
|
|
@ -183,12 +183,6 @@ class JVMCIEnv : public ResourceObj {
|
||||||
// The translated exception is pending in hotspot_env upon returning.
|
// The translated exception is pending in hotspot_env upon returning.
|
||||||
static void translate_from_jni_exception(JavaThread* THREAD, jthrowable throwable, JVMCIEnv* hotspot_env, JVMCIEnv* jni_env);
|
static void translate_from_jni_exception(JavaThread* THREAD, jthrowable throwable, JVMCIEnv* hotspot_env, JVMCIEnv* jni_env);
|
||||||
|
|
||||||
// Used by copy_saved_properties() to avoid OutOfMemoryErrors when
|
|
||||||
// initializing a libjvmci runtime in low HotSpot heap conditions.
|
|
||||||
// Must hold JVMCI_lock when initializing.
|
|
||||||
static jbyte* _serialized_saved_properties;
|
|
||||||
static int _serialized_saved_properties_len;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Opens a JVMCIEnv scope for a Java to VM call (e.g., via CompilerToVM).
|
// Opens a JVMCIEnv scope for a Java to VM call (e.g., via CompilerToVM).
|
||||||
// An exception occurring within the scope is left pending when the
|
// An exception occurring within the scope is left pending when the
|
||||||
|
@ -237,14 +231,6 @@ public:
|
||||||
return _runtime;
|
return _runtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the serialized saved properties from the HotSpot heap.
|
|
||||||
// The length of the returned array is saved in `len`.
|
|
||||||
jbyte* get_serialized_saved_properties(int& len, TRAPS);
|
|
||||||
|
|
||||||
// Initializes Services.savedProperties in the shared library from the given
|
|
||||||
// properties in the format produced by `get_serialized_saved_properties`.
|
|
||||||
void copy_saved_properties(jbyte* properties, int properties_len, JVMCI_TRAPS);
|
|
||||||
|
|
||||||
jboolean has_pending_exception();
|
jboolean has_pending_exception();
|
||||||
void clear_pending_exception();
|
void clear_pending_exception();
|
||||||
|
|
||||||
|
@ -509,7 +495,7 @@ public:
|
||||||
#define STATIC_BOOLEAN_FIELD(className, name) STATIC_FIELD(className, name, jboolean)
|
#define STATIC_BOOLEAN_FIELD(className, name) STATIC_FIELD(className, name, jboolean)
|
||||||
#define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObject, oop)
|
#define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObject, oop)
|
||||||
#define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, objArrayOop)
|
#define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, objArrayOop)
|
||||||
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)
|
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName)
|
||||||
#define CONSTRUCTOR(className, signature)
|
#define CONSTRUCTOR(className, signature)
|
||||||
|
|
||||||
JVMCI_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, PRIMARRAY_FIELD, OBJECTARRAY_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECTARRAY_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR)
|
JVMCI_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, PRIMARRAY_FIELD, OBJECTARRAY_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECTARRAY_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR)
|
||||||
|
|
|
@ -151,10 +151,10 @@ jmethodID JNIJVMCI::_HotSpotResolvedPrimitiveType_fromMetaspace_method;
|
||||||
#define STATIC_INT_FIELD(className, name) FIELD(className, name, "I", true)
|
#define STATIC_INT_FIELD(className, name) FIELD(className, name, "I", true)
|
||||||
#define STATIC_BOOLEAN_FIELD(className, name) FIELD(className, name, "Z", true)
|
#define STATIC_BOOLEAN_FIELD(className, name) FIELD(className, name, "Z", true)
|
||||||
#ifdef PRODUCT
|
#ifdef PRODUCT
|
||||||
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)
|
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName)
|
||||||
#define CONSTRUCTOR(className, signature)
|
#define CONSTRUCTOR(className, signature)
|
||||||
#else
|
#else
|
||||||
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) \
|
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName) \
|
||||||
check_resolve_method(#hsCallType, k, vmSymbols::methodName##_name(), vmSymbols::signatureSymbolName(), CHECK);
|
check_resolve_method(#hsCallType, k, vmSymbols::methodName##_name(), vmSymbols::signatureSymbolName(), CHECK);
|
||||||
#define CONSTRUCTOR(className, signature) { \
|
#define CONSTRUCTOR(className, signature) { \
|
||||||
TempNewSymbol sig = SymbolTable::new_symbol(signature); \
|
TempNewSymbol sig = SymbolTable::new_symbol(signature); \
|
||||||
|
@ -254,7 +254,7 @@ void HotSpotJVMCI::compute_offsets(TRAPS) {
|
||||||
|
|
||||||
#define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint)
|
#define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint)
|
||||||
#define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean)
|
#define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean)
|
||||||
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)
|
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName)
|
||||||
#define CONSTRUCTOR(className, signature)
|
#define CONSTRUCTOR(className, signature)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -393,7 +393,7 @@ void JNIJVMCI::initialize_field_id(JNIEnv* env, jfieldID &fieldid, jclass clazz,
|
||||||
#define GET_JNI_CONSTRUCTOR(clazz, signature) \
|
#define GET_JNI_CONSTRUCTOR(clazz, signature) \
|
||||||
GET_JNI_METHOD(GetMethodID, JNIJVMCI::clazz::_constructor, clazz::_class, "<init>", signature) \
|
GET_JNI_METHOD(GetMethodID, JNIJVMCI::clazz::_constructor, clazz::_class, "<init>", signature) \
|
||||||
|
|
||||||
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) \
|
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName) \
|
||||||
GET_JNI_METHOD(jniGetMethod, \
|
GET_JNI_METHOD(jniGetMethod, \
|
||||||
className::_##methodName##_method, \
|
className::_##methodName##_method, \
|
||||||
className::clazz(), \
|
className::clazz(), \
|
||||||
|
@ -406,6 +406,7 @@ void JNIJVMCI::initialize_field_id(JNIEnv* env, jfieldID &fieldid, jclass clazz,
|
||||||
extern "C" {
|
extern "C" {
|
||||||
void JNICALL JVM_RegisterJVMCINatives(JNIEnv *env, jclass compilerToVMClass);
|
void JNICALL JVM_RegisterJVMCINatives(JNIEnv *env, jclass compilerToVMClass);
|
||||||
jobject JNICALL JVM_GetJVMCIRuntime(JNIEnv *env, jclass c);
|
jobject JNICALL JVM_GetJVMCIRuntime(JNIEnv *env, jclass c);
|
||||||
|
jlong JNICALL JVM_ReadSystemPropertiesInfo(JNIEnv *env, jclass c, jintArray offsets_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dumps symbols for public <init>() and <init>(String) methods of
|
// Dumps symbols for public <init>() and <init>(String) methods of
|
||||||
|
@ -566,9 +567,11 @@ void JNIJVMCI::register_natives(JNIEnv* env) {
|
||||||
if (env != JavaThread::current()->jni_environment()) {
|
if (env != JavaThread::current()->jni_environment()) {
|
||||||
JNINativeMethod CompilerToVM_nmethods[] = {{ CC"registerNatives", CC"()V", FN_PTR(JVM_RegisterJVMCINatives) }};
|
JNINativeMethod CompilerToVM_nmethods[] = {{ CC"registerNatives", CC"()V", FN_PTR(JVM_RegisterJVMCINatives) }};
|
||||||
JNINativeMethod JVMCI_nmethods[] = {{ CC"initializeRuntime", CC"()Ljdk/vm/ci/runtime/JVMCIRuntime;", FN_PTR(JVM_GetJVMCIRuntime) }};
|
JNINativeMethod JVMCI_nmethods[] = {{ CC"initializeRuntime", CC"()Ljdk/vm/ci/runtime/JVMCIRuntime;", FN_PTR(JVM_GetJVMCIRuntime) }};
|
||||||
|
JNINativeMethod Services_nmethods[] = {{ CC"readSystemPropertiesInfo", CC"([I)J", FN_PTR(JVM_ReadSystemPropertiesInfo) }};
|
||||||
|
|
||||||
register_natives_for_class(env, nullptr, "jdk/vm/ci/hotspot/CompilerToVM", CompilerToVM_nmethods, 1);
|
register_natives_for_class(env, nullptr, "jdk/vm/ci/hotspot/CompilerToVM", CompilerToVM_nmethods, 1);
|
||||||
register_natives_for_class(env, JVMCI::clazz(), "jdk/vm/ci/runtime/JVMCI", JVMCI_nmethods, 1);
|
register_natives_for_class(env, JVMCI::clazz(), "jdk/vm/ci/runtime/JVMCI", JVMCI_nmethods, 1);
|
||||||
|
register_natives_for_class(env, Services::clazz(), "jdk/vm/ci/services/Services", Services_nmethods, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,7 +586,7 @@ void JNIJVMCI::register_natives(JNIEnv* env) {
|
||||||
#define FIELD2(className, name) \
|
#define FIELD2(className, name) \
|
||||||
jfieldID JNIJVMCI::className::_##name##_field_id = 0; \
|
jfieldID JNIJVMCI::className::_##name##_field_id = 0; \
|
||||||
int HotSpotJVMCI::className::_##name##_offset = 0;
|
int HotSpotJVMCI::className::_##name##_offset = 0;
|
||||||
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)
|
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName)
|
||||||
#define CONSTRUCTOR(className, signature)
|
#define CONSTRUCTOR(className, signature)
|
||||||
|
|
||||||
// Generates the definitions of static fields used by the accessors. For example:
|
// Generates the definitions of static fields used by the accessors. For example:
|
||||||
|
@ -689,7 +692,7 @@ JVMCI_CLASSES_DO(EMPTY2, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3,
|
||||||
|
|
||||||
#define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST)
|
#define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST)
|
||||||
#define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
|
#define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
|
||||||
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) \
|
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName) \
|
||||||
jmethodID JNIJVMCI::className::_##methodName##_method;
|
jmethodID JNIJVMCI::className::_##methodName##_method;
|
||||||
|
|
||||||
#define CONSTRUCTOR(className, signature) \
|
#define CONSTRUCTOR(className, signature) \
|
||||||
|
|
|
@ -56,9 +56,6 @@
|
||||||
static_boolean_field, \
|
static_boolean_field, \
|
||||||
jvmci_method, \
|
jvmci_method, \
|
||||||
jvmci_constructor) \
|
jvmci_constructor) \
|
||||||
start_class(Services, jdk_vm_ci_services_Services) \
|
|
||||||
jvmci_method(CallStaticVoidMethod, GetStaticMethodID, call_static, void, Services, initializeSavedProperties, byte_array_void_signature, (JVMCIObject serializedProperties)) \
|
|
||||||
end_class \
|
|
||||||
start_class(Architecture, jdk_vm_ci_code_Architecture) \
|
start_class(Architecture, jdk_vm_ci_code_Architecture) \
|
||||||
object_field(Architecture, wordKind, "Ljdk/vm/ci/meta/PlatformKind;") \
|
object_field(Architecture, wordKind, "Ljdk/vm/ci/meta/PlatformKind;") \
|
||||||
end_class \
|
end_class \
|
||||||
|
@ -160,7 +157,7 @@
|
||||||
start_class(JavaConstant, jdk_vm_ci_meta_JavaConstant) \
|
start_class(JavaConstant, jdk_vm_ci_meta_JavaConstant) \
|
||||||
static_object_field(JavaConstant, ILLEGAL, "Ljdk/vm/ci/meta/PrimitiveConstant;") \
|
static_object_field(JavaConstant, ILLEGAL, "Ljdk/vm/ci/meta/PrimitiveConstant;") \
|
||||||
static_object_field(JavaConstant, NULL_POINTER, "Ljdk/vm/ci/meta/JavaConstant;") \
|
static_object_field(JavaConstant, NULL_POINTER, "Ljdk/vm/ci/meta/JavaConstant;") \
|
||||||
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, JavaConstant, forPrimitive, forPrimitive_signature, (JVMCIObject kind, jlong value, JVMCI_TRAPS)) \
|
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, JavaConstant, forPrimitive, forPrimitive_signature) \
|
||||||
end_class \
|
end_class \
|
||||||
start_class(ResolvedJavaMethod, jdk_vm_ci_meta_ResolvedJavaMethod) \
|
start_class(ResolvedJavaMethod, jdk_vm_ci_meta_ResolvedJavaMethod) \
|
||||||
end_class \
|
end_class \
|
||||||
|
@ -200,34 +197,36 @@
|
||||||
end_class \
|
end_class \
|
||||||
start_class(HotSpotJVMCIRuntime, jdk_vm_ci_hotspot_HotSpotJVMCIRuntime) \
|
start_class(HotSpotJVMCIRuntime, jdk_vm_ci_hotspot_HotSpotJVMCIRuntime) \
|
||||||
objectarray_field(HotSpotJVMCIRuntime, excludeFromJVMCICompilation, "[Ljava/lang/Module;") \
|
objectarray_field(HotSpotJVMCIRuntime, excludeFromJVMCICompilation, "[Ljava/lang/Module;") \
|
||||||
jvmci_method(CallNonvirtualObjectMethod, GetMethodID, call_special, JVMCIObject, HotSpotJVMCIRuntime, compileMethod, compileMethod_signature, (JVMCIObject runtime, JVMCIObject method, int entry_bci, jlong env, int id)) \
|
jvmci_method(CallNonvirtualObjectMethod, GetMethodID, call_special, JVMCIObject, HotSpotJVMCIRuntime, compileMethod, compileMethod_signature) \
|
||||||
jvmci_method(CallNonvirtualObjectMethod, GetMethodID, call_special, JVMCIObject, HotSpotJVMCIRuntime, isGCSupported, int_bool_signature, (JVMCIObject runtime, int gcIdentifier)) \
|
jvmci_method(CallNonvirtualObjectMethod, GetMethodID, call_special, JVMCIObject, HotSpotJVMCIRuntime, isGCSupported, int_bool_signature) \
|
||||||
jvmci_method(CallNonvirtualVoidMethod, GetMethodID, call_special, void, HotSpotJVMCIRuntime, bootstrapFinished, void_method_signature, (JVMCIObject runtime, JVMCI_TRAPS)) \
|
jvmci_method(CallNonvirtualVoidMethod, GetMethodID, call_special, void, HotSpotJVMCIRuntime, bootstrapFinished, void_method_signature) \
|
||||||
jvmci_method(CallNonvirtualVoidMethod, GetMethodID, call_special, void, HotSpotJVMCIRuntime, shutdown, void_method_signature, (JVMCIObject runtime)) \
|
jvmci_method(CallNonvirtualVoidMethod, GetMethodID, call_special, void, HotSpotJVMCIRuntime, shutdown, void_method_signature) \
|
||||||
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, HotSpotJVMCIRuntime, runtime, runtime_signature, (JVMCI_TRAPS)) \
|
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, HotSpotJVMCIRuntime, runtime, runtime_signature) \
|
||||||
jvmci_method(CallObjectMethod, GetMethodID, call_virtual, JVMCIObject, HotSpotJVMCIRuntime, getCompiler, getCompiler_signature, (JVMCIObject runtime, JVMCI_TRAPS)) \
|
jvmci_method(CallObjectMethod, GetMethodID, call_virtual, JVMCIObject, HotSpotJVMCIRuntime, getCompiler, getCompiler_signature) \
|
||||||
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, HotSpotJVMCIRuntime, exceptionToString, exceptionToString_signature, (JVMCIObject object, bool toString, bool stackTrace, JVMCI_TRAPS)) \
|
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, HotSpotJVMCIRuntime, exceptionToString, exceptionToString_signature) \
|
||||||
jvmci_method(CallStaticVoidMethod, GetStaticMethodID, call_static, void, HotSpotJVMCIRuntime, postTranslation, object_void_signature, (JVMCIObject object, JVMCI_TRAPS)) \
|
jvmci_method(CallStaticVoidMethod, GetStaticMethodID, call_static, void, HotSpotJVMCIRuntime, postTranslation, object_void_signature) \
|
||||||
end_class \
|
end_class \
|
||||||
start_class(JVMCIError, jdk_vm_ci_common_JVMCIError) \
|
start_class(JVMCIError, jdk_vm_ci_common_JVMCIError) \
|
||||||
jvmci_constructor(JVMCIError, "(Ljava/lang/String;)V") \
|
jvmci_constructor(JVMCIError, "(Ljava/lang/String;)V") \
|
||||||
end_class \
|
end_class \
|
||||||
start_class(InspectedFrameVisitor, jdk_vm_ci_code_stack_InspectedFrameVisitor) \
|
start_class(InspectedFrameVisitor, jdk_vm_ci_code_stack_InspectedFrameVisitor) \
|
||||||
end_class \
|
end_class \
|
||||||
|
start_class(Services, jdk_vm_ci_services_Services) \
|
||||||
|
end_class \
|
||||||
start_class(JVMCI, jdk_vm_ci_runtime_JVMCI) \
|
start_class(JVMCI, jdk_vm_ci_runtime_JVMCI) \
|
||||||
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, JVMCI, getRuntime, getRuntime_signature, (JVMCI_TRAPS)) \
|
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, JVMCI, getRuntime, getRuntime_signature) \
|
||||||
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, JVMCI, initializeRuntime, initializeRuntime_signature, (JVMCI_TRAPS)) \
|
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, JVMCI, initializeRuntime, initializeRuntime_signature) \
|
||||||
end_class \
|
end_class \
|
||||||
start_class(Object, java_lang_Object) \
|
start_class(Object, java_lang_Object) \
|
||||||
end_class \
|
end_class \
|
||||||
start_class(String, java_lang_String) \
|
start_class(String, java_lang_String) \
|
||||||
end_class \
|
end_class \
|
||||||
start_class(Class, java_lang_Class) \
|
start_class(Class, java_lang_Class) \
|
||||||
jvmci_method(CallObjectMethod, GetMethodID, call_virtual, JVMCIObject, Class, getName, void_string_signature, (JVMCI_TRAPS)) \
|
jvmci_method(CallObjectMethod, GetMethodID, call_virtual, JVMCIObject, Class, getName, void_string_signature) \
|
||||||
end_class \
|
end_class \
|
||||||
start_class(VMSupport, jdk_internal_vm_VMSupport) \
|
start_class(VMSupport, jdk_internal_vm_VMSupport) \
|
||||||
jvmci_method(CallStaticIntMethod, GetStaticMethodID, call_static, int, VMSupport, encodeThrowable, encodeThrowable_signature, (JVMCIObject throwable, jlong buffer, int buffer_size)) \
|
jvmci_method(CallStaticIntMethod, GetStaticMethodID, call_static, int, VMSupport, encodeThrowable, encodeThrowable_signature) \
|
||||||
jvmci_method(CallStaticVoidMethod, GetStaticMethodID, call_static, void, VMSupport, decodeAndThrowThrowable, decodeAndThrowThrowable_signature, (jlong buffer)) \
|
jvmci_method(CallStaticVoidMethod, GetStaticMethodID, call_static, void, VMSupport, decodeAndThrowThrowable, decodeAndThrowThrowable_signature) \
|
||||||
end_class \
|
end_class \
|
||||||
start_class(ArrayIndexOutOfBoundsException, java_lang_ArrayIndexOutOfBoundsException) \
|
start_class(ArrayIndexOutOfBoundsException, java_lang_ArrayIndexOutOfBoundsException) \
|
||||||
jvmci_constructor(ArrayIndexOutOfBoundsException, "(Ljava/lang/String;)V") \
|
jvmci_constructor(ArrayIndexOutOfBoundsException, "(Ljava/lang/String;)V") \
|
||||||
|
@ -342,7 +341,7 @@ class JVMCIEnv;
|
||||||
static hstype name(JVMCIEnv* env); \
|
static hstype name(JVMCIEnv* env); \
|
||||||
static void set_ ## name(JVMCIEnv* env, hstype hstype);
|
static void set_ ## name(JVMCIEnv* env, hstype hstype);
|
||||||
|
|
||||||
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, simpleClassName, methodName, signatureSymbolName, args)
|
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, simpleClassName, methodName, signatureSymbolName)
|
||||||
#define CONSTRUCTOR(className, signature)
|
#define CONSTRUCTOR(className, signature)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -435,7 +434,7 @@ public:
|
||||||
#define STATIC_OOPISH_FIELD(simpleClassName, name, type, hstype) \
|
#define STATIC_OOPISH_FIELD(simpleClassName, name, type, hstype) \
|
||||||
STATIC_FIELD(simpleClassName, name, type)
|
STATIC_FIELD(simpleClassName, name, type)
|
||||||
|
|
||||||
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) \
|
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName) \
|
||||||
public: \
|
public: \
|
||||||
static jmethodID methodName##_method() { return _##methodName##_method; } \
|
static jmethodID methodName##_method() { return _##methodName##_method; } \
|
||||||
private: \
|
private: \
|
||||||
|
|
|
@ -754,6 +754,21 @@ JVM_ENTRY_NO_ENV(jobject, JVM_GetJVMCIRuntime(JNIEnv *env, jclass c))
|
||||||
return JVMCIENV->get_jobject(runtime);
|
return JVMCIENV->get_jobject(runtime);
|
||||||
JVM_END
|
JVM_END
|
||||||
|
|
||||||
|
// private static long Services.readSystemPropertiesInfo(int[] offsets)
|
||||||
|
JVM_ENTRY_NO_ENV(jlong, JVM_ReadSystemPropertiesInfo(JNIEnv *env, jclass c, jintArray offsets_handle))
|
||||||
|
JNI_JVMCIENV(thread, env);
|
||||||
|
if (!EnableJVMCI) {
|
||||||
|
JVMCI_THROW_MSG_0(InternalError, "JVMCI is not enabled");
|
||||||
|
}
|
||||||
|
JVMCIPrimitiveArray offsets = JVMCIENV->wrap(offsets_handle);
|
||||||
|
JVMCIENV->put_int_at(offsets, 0, SystemProperty::next_offset_in_bytes());
|
||||||
|
JVMCIENV->put_int_at(offsets, 1, SystemProperty::key_offset_in_bytes());
|
||||||
|
JVMCIENV->put_int_at(offsets, 2, PathString::value_offset_in_bytes());
|
||||||
|
|
||||||
|
return (jlong) Arguments::system_properties();
|
||||||
|
JVM_END
|
||||||
|
|
||||||
|
|
||||||
void JVMCIRuntime::call_getCompiler(TRAPS) {
|
void JVMCIRuntime::call_getCompiler(TRAPS) {
|
||||||
THREAD_JVMCIENV(JavaThread::current());
|
THREAD_JVMCIENV(JavaThread::current());
|
||||||
JVMCIObject jvmciRuntime = JVMCIRuntime::get_HotSpotJVMCIRuntime(JVMCI_CHECK);
|
JVMCIObject jvmciRuntime = JVMCIRuntime::get_HotSpotJVMCIRuntime(JVMCI_CHECK);
|
||||||
|
@ -1399,9 +1414,6 @@ void JVMCIRuntime::initialize(JVMCI_TRAPS) {
|
||||||
|
|
||||||
JavaThread* THREAD = JavaThread::current();
|
JavaThread* THREAD = JavaThread::current();
|
||||||
|
|
||||||
int properties_len = 0;
|
|
||||||
jbyte* properties = nullptr;
|
|
||||||
|
|
||||||
MutexLocker locker(_lock);
|
MutexLocker locker(_lock);
|
||||||
// Check again under _lock
|
// Check again under _lock
|
||||||
if (_init_state == fully_initialized) {
|
if (_init_state == fully_initialized) {
|
||||||
|
@ -1464,16 +1476,6 @@ void JVMCIRuntime::initialize(JVMCI_TRAPS) {
|
||||||
create_jvmci_primitive_type(T_VOID, JVMCI_CHECK_EXIT_((void)0));
|
create_jvmci_primitive_type(T_VOID, JVMCI_CHECK_EXIT_((void)0));
|
||||||
|
|
||||||
DEBUG_ONLY(CodeInstaller::verify_bci_constants(JVMCIENV);)
|
DEBUG_ONLY(CodeInstaller::verify_bci_constants(JVMCIENV);)
|
||||||
|
|
||||||
if (!JVMCIENV->is_hotspot()) {
|
|
||||||
Handle properties_exception;
|
|
||||||
properties = JVMCIENV->get_serialized_saved_properties(properties_len, THREAD);
|
|
||||||
if (JVMCIEnv::transfer_pending_exception_to_jni(THREAD, nullptr, JVMCIENV)) {
|
|
||||||
JVMCI_event_1("error initializing system properties for JVMCI runtime %d", _id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
JVMCIENV->copy_saved_properties(properties, properties_len, JVMCI_CHECK);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_init_state = fully_initialized;
|
_init_state = fully_initialized;
|
||||||
|
|
|
@ -102,7 +102,6 @@
|
||||||
template(forPrimitive_name, "forPrimitive") \
|
template(forPrimitive_name, "forPrimitive") \
|
||||||
template(forPrimitive_signature, "(CJ)Ljdk/vm/ci/meta/PrimitiveConstant;") \
|
template(forPrimitive_signature, "(CJ)Ljdk/vm/ci/meta/PrimitiveConstant;") \
|
||||||
template(method_string_bool_long_signature, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;Ljava/lang/String;ZJ)V") \
|
template(method_string_bool_long_signature, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;Ljava/lang/String;ZJ)V") \
|
||||||
template(initializeSavedProperties_name, "initializeSavedProperties") \
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -210,6 +210,7 @@ extern "C" {
|
||||||
void JNICALL JVM_RegisterVectorSupportMethods(JNIEnv *env, jclass vsclass);
|
void JNICALL JVM_RegisterVectorSupportMethods(JNIEnv *env, jclass vsclass);
|
||||||
#if INCLUDE_JVMCI
|
#if INCLUDE_JVMCI
|
||||||
jobject JNICALL JVM_GetJVMCIRuntime(JNIEnv *env, jclass c);
|
jobject JNICALL JVM_GetJVMCIRuntime(JNIEnv *env, jclass c);
|
||||||
|
jlong JNICALL JVM_ReadSystemPropertiesInfo(JNIEnv *env, jclass c, jintArray offsets);
|
||||||
void JNICALL JVM_RegisterJVMCINatives(JNIEnv *env, jclass compilerToVMClass);
|
void JNICALL JVM_RegisterJVMCINatives(JNIEnv *env, jclass compilerToVMClass);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -229,6 +230,7 @@ static JNINativeMethod lookup_special_native_methods[] = {
|
||||||
{ CC"Java_jdk_internal_vm_vector_VectorSupport_registerNatives", nullptr, FN_PTR(JVM_RegisterVectorSupportMethods)},
|
{ CC"Java_jdk_internal_vm_vector_VectorSupport_registerNatives", nullptr, FN_PTR(JVM_RegisterVectorSupportMethods)},
|
||||||
#if INCLUDE_JVMCI
|
#if INCLUDE_JVMCI
|
||||||
{ CC"Java_jdk_vm_ci_runtime_JVMCI_initializeRuntime", nullptr, FN_PTR(JVM_GetJVMCIRuntime) },
|
{ CC"Java_jdk_vm_ci_runtime_JVMCI_initializeRuntime", nullptr, FN_PTR(JVM_GetJVMCIRuntime) },
|
||||||
|
{ CC"Java_jdk_vm_ci_services_Services_readSystemPropertiesInfo", nullptr, FN_PTR(JVM_ReadSystemPropertiesInfo) },
|
||||||
{ CC"Java_jdk_vm_ci_hotspot_CompilerToVM_registerNatives", nullptr, FN_PTR(JVM_RegisterJVMCINatives) },
|
{ CC"Java_jdk_vm_ci_hotspot_CompilerToVM_registerNatives", nullptr, FN_PTR(JVM_RegisterJVMCINatives) },
|
||||||
#endif
|
#endif
|
||||||
#if INCLUDE_JFR
|
#if INCLUDE_JFR
|
||||||
|
|
|
@ -75,6 +75,9 @@ class PathString : public CHeapObj<mtArguments> {
|
||||||
|
|
||||||
PathString(const char* value);
|
PathString(const char* value);
|
||||||
~PathString();
|
~PathString();
|
||||||
|
|
||||||
|
// for JVM_ReadSystemPropertiesInfo
|
||||||
|
static int value_offset_in_bytes() { return (int)offset_of(PathString, _value); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// ModulePatchPath records the module/path pair as specified to --patch-module.
|
// ModulePatchPath records the module/path pair as specified to --patch-module.
|
||||||
|
@ -136,6 +139,10 @@ class SystemProperty : public PathString {
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
SystemProperty(const char* key, const char* value, bool writeable, bool internal = false);
|
SystemProperty(const char* key, const char* value, bool writeable, bool internal = false);
|
||||||
|
|
||||||
|
// for JVM_ReadSystemPropertiesInfo
|
||||||
|
static int key_offset_in_bytes() { return (int)offset_of(SystemProperty, _key); }
|
||||||
|
static int next_offset_in_bytes() { return (int)offset_of(SystemProperty, _next); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper class for controlling the lifetime of JavaVMInitArgs objects.
|
// Helper class for controlling the lifetime of JavaVMInitArgs objects.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -101,19 +101,6 @@ public class VMSupport {
|
||||||
return serializePropertiesToByteArray(onlyStrings(getAgentProperties()));
|
return serializePropertiesToByteArray(onlyStrings(getAgentProperties()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Serializes {@link VM#getSavedProperties()} to a byte array.
|
|
||||||
*
|
|
||||||
* Used by JVMCI to copy properties into libjvmci.
|
|
||||||
*/
|
|
||||||
public static byte[] serializeSavedPropertiesToByteArray() throws IOException {
|
|
||||||
Properties props = new Properties();
|
|
||||||
for (var e : VM.getSavedProperties().entrySet()) {
|
|
||||||
props.put(e.getKey(), e.getValue());
|
|
||||||
}
|
|
||||||
return serializePropertiesToByteArray(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the temporary directory that the VM uses for the attach
|
* Return the temporary directory that the VM uses for the attach
|
||||||
* and perf data files.
|
* and perf data files.
|
||||||
|
|
|
@ -278,6 +278,7 @@ module java.base {
|
||||||
java.security.jgss,
|
java.security.jgss,
|
||||||
java.smartcardio,
|
java.smartcardio,
|
||||||
jdk.charsets,
|
jdk.charsets,
|
||||||
|
jdk.internal.vm.ci,
|
||||||
jdk.jlink,
|
jdk.jlink,
|
||||||
jdk.jpackage,
|
jdk.jpackage,
|
||||||
jdk.net;
|
jdk.net;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -26,6 +26,7 @@ import static jdk.vm.ci.meta.MetaUtil.identityHashCodeString;
|
||||||
|
|
||||||
import jdk.vm.ci.meta.JavaKind;
|
import jdk.vm.ci.meta.JavaKind;
|
||||||
import jdk.vm.ci.services.Services;
|
import jdk.vm.ci.services.Services;
|
||||||
|
import jdk.internal.util.OperatingSystem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the target machine for a compiler, including the CPU architecture, the size of
|
* Represents the target machine for a compiler, including the CPU architecture, the size of
|
||||||
|
@ -33,8 +34,8 @@ import jdk.vm.ci.services.Services;
|
||||||
*/
|
*/
|
||||||
public class TargetDescription {
|
public class TargetDescription {
|
||||||
|
|
||||||
public final boolean linuxOs = Services.getSavedProperty("os.name", "").startsWith("Linux");
|
public final boolean linuxOs = OperatingSystem.isLinux();
|
||||||
public final boolean macOs = Services.getSavedProperty("os.name", "").startsWith("Mac");
|
public final boolean macOs = OperatingSystem.isMacOS();
|
||||||
|
|
||||||
public final Architecture arch;
|
public final Architecture arch;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
|
|
@ -28,6 +28,7 @@ import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
|
||||||
import jdk.vm.ci.common.JVMCIError;
|
import jdk.vm.ci.common.JVMCIError;
|
||||||
import jdk.vm.ci.services.Services;
|
import jdk.vm.ci.services.Services;
|
||||||
import jdk.internal.misc.Unsafe;
|
import jdk.internal.misc.Unsafe;
|
||||||
|
import jdk.internal.util.Architecture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to access native configuration details.
|
* Used to access native configuration details.
|
||||||
|
@ -43,8 +44,6 @@ class HotSpotVMConfig extends HotSpotVMConfigAccess {
|
||||||
return runtime().getConfig();
|
return runtime().getConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String osArch = getHostArchitectureName();
|
|
||||||
|
|
||||||
HotSpotVMConfig(HotSpotVMConfigStore store) {
|
HotSpotVMConfig(HotSpotVMConfigStore store) {
|
||||||
super(store);
|
super(store);
|
||||||
|
|
||||||
|
@ -57,13 +56,10 @@ class HotSpotVMConfig extends HotSpotVMConfigAccess {
|
||||||
* {@linkplain HotSpotJVMCIBackendFactory backend}.
|
* {@linkplain HotSpotJVMCIBackendFactory backend}.
|
||||||
*/
|
*/
|
||||||
String getHostArchitectureName() {
|
String getHostArchitectureName() {
|
||||||
String arch = Services.getSavedProperty("os.arch");
|
Architecture arch = Architecture.current();
|
||||||
switch (arch) {
|
switch (arch) {
|
||||||
case "x86_64":
|
case X64: return "amd64";
|
||||||
return "amd64";
|
default: return arch.name().toLowerCase();
|
||||||
|
|
||||||
default:
|
|
||||||
return arch;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +130,7 @@ class HotSpotVMConfig extends HotSpotVMConfigAccess {
|
||||||
final int jvmMiscFlagsDeclaresDefaultMethods = getConstant("InstanceKlassFlags::_misc_declares_nonstatic_concrete_methods", Integer.class);
|
final int jvmMiscFlagsDeclaresDefaultMethods = getConstant("InstanceKlassFlags::_misc_declares_nonstatic_concrete_methods", Integer.class);
|
||||||
|
|
||||||
// This is only valid on AMD64.
|
// This is only valid on AMD64.
|
||||||
final int runtimeCallStackSize = getConstant("frame::arg_reg_save_area_bytes", Integer.class, osArch.equals("amd64") ? null : 0);
|
final int runtimeCallStackSize = getConstant("frame::arg_reg_save_area_bytes", Integer.class, Architecture.isX64() ? null : 0);
|
||||||
|
|
||||||
private final int markWordNoHashInPlace = getConstant("markWord::no_hash_in_place", Integer.class);
|
private final int markWordNoHashInPlace = getConstant("markWord::no_hash_in_place", Integer.class);
|
||||||
private final int markWordNoLockInPlace = getConstant("markWord::no_lock_in_place", Integer.class);
|
private final int markWordNoLockInPlace = getConstant("markWord::no_lock_in_place", Integer.class);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -25,6 +25,7 @@ package jdk.vm.ci.hotspot.amd64;
|
||||||
import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
|
import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
|
||||||
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
|
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
|
||||||
import jdk.vm.ci.services.Services;
|
import jdk.vm.ci.services.Services;
|
||||||
|
import jdk.internal.util.OperatingSystem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to access AMD64 specific native configuration details.
|
* Used to access AMD64 specific native configuration details.
|
||||||
|
@ -35,7 +36,7 @@ class AMD64HotSpotVMConfig extends HotSpotVMConfigAccess {
|
||||||
super(config);
|
super(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean windowsOs = Services.getSavedProperty("os.name", "").startsWith("Windows");
|
final boolean windowsOs = OperatingSystem.isWindows();
|
||||||
|
|
||||||
final boolean useCountLeadingZerosInstruction = getFlag("UseCountLeadingZerosInstruction", Boolean.class);
|
final boolean useCountLeadingZerosInstruction = getFlag("UseCountLeadingZerosInstruction", Boolean.class);
|
||||||
final boolean useCountTrailingZerosInstruction = getFlag("UseCountTrailingZerosInstruction", Boolean.class);
|
final boolean useCountTrailingZerosInstruction = getFlag("UseCountTrailingZerosInstruction", Boolean.class);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -25,6 +25,7 @@ package jdk.vm.ci.hotspot.riscv64;
|
||||||
import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
|
import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
|
||||||
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
|
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
|
||||||
import jdk.vm.ci.services.Services;
|
import jdk.vm.ci.services.Services;
|
||||||
|
import jdk.internal.util.OperatingSystem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to access native configuration details.
|
* Used to access native configuration details.
|
||||||
|
@ -37,7 +38,7 @@ class RISCV64HotSpotVMConfig extends HotSpotVMConfigAccess {
|
||||||
super(config);
|
super(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean linuxOs = Services.getSavedProperty("os.name", "").startsWith("Linux");
|
final boolean linuxOs = OperatingSystem.isLinux();
|
||||||
|
|
||||||
final boolean useCompressedOops = getFlag("UseCompressedOops", Boolean.class);
|
final boolean useCompressedOops = getFlag("UseCompressedOops", Boolean.class);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -22,16 +22,12 @@
|
||||||
*/
|
*/
|
||||||
package jdk.vm.ci.services;
|
package jdk.vm.ci.services;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Formatter;
|
import java.util.Formatter;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
@ -39,6 +35,9 @@ import java.util.function.Supplier;
|
||||||
|
|
||||||
import jdk.internal.misc.TerminatingThreadLocal;
|
import jdk.internal.misc.TerminatingThreadLocal;
|
||||||
import jdk.internal.misc.VM;
|
import jdk.internal.misc.VM;
|
||||||
|
import jdk.internal.misc.Unsafe;
|
||||||
|
import jdk.internal.util.Architecture;
|
||||||
|
import jdk.internal.util.OperatingSystem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides utilities needed by JVMCI clients.
|
* Provides utilities needed by JVMCI clients.
|
||||||
|
@ -71,7 +70,7 @@ public final class Services {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In a native image, this field is initialized by {@link #initializeSavedProperties(byte[])}.
|
* Lazily initialized in {@link #getSavedProperties}.
|
||||||
*/
|
*/
|
||||||
private static volatile Map<String, String> savedProperties;
|
private static volatile Map<String, String> savedProperties;
|
||||||
|
|
||||||
|
@ -87,25 +86,17 @@ public final class Services {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets an unmodifiable copy of the system properties saved when {@link System} is initialized.
|
* Gets an unmodifiable copy of the system properties parsed by {@code arguments.cpp}
|
||||||
|
* plus {@code java.specification.version}, {@code os.name} and {@code os.arch}.
|
||||||
|
* The latter two are forced to be the real OS and architecture. That is, values
|
||||||
|
* for these two properties set on the command line are ignored.
|
||||||
*/
|
*/
|
||||||
public static Map<String, String> getSavedProperties() {
|
public static Map<String, String> getSavedProperties() {
|
||||||
checkJVMCIEnabled();
|
checkJVMCIEnabled();
|
||||||
if (IS_IN_NATIVE_IMAGE) {
|
|
||||||
if (savedProperties == null) {
|
|
||||||
throw new InternalError("Saved properties not initialized");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (savedProperties == null) {
|
if (savedProperties == null) {
|
||||||
synchronized (Services.class) {
|
synchronized (Services.class) {
|
||||||
if (savedProperties == null) {
|
if (savedProperties == null) {
|
||||||
@SuppressWarnings("removal")
|
savedProperties = initProperties();
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
sm.checkPermission(new JVMCIPermission());
|
|
||||||
}
|
|
||||||
savedProperties = VM.getSavedProperties();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,22 +252,128 @@ public final class Services {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static String toJavaString(Unsafe unsafe, long cstring) {
|
||||||
* Initializes {@link #savedProperties} from the byte array returned by
|
if (cstring == 0) {
|
||||||
* {@code jdk.internal.vm.VMSupport.serializeSavedPropertiesToByteArray()}.
|
return null;
|
||||||
*/
|
|
||||||
@VMEntryPoint
|
|
||||||
private static void initializeSavedProperties(byte[] serializedProperties) throws IOException {
|
|
||||||
if (!IS_IN_NATIVE_IMAGE) {
|
|
||||||
throw new InternalError("Can only initialize saved properties in JVMCI shared library runtime");
|
|
||||||
}
|
}
|
||||||
Properties props = new Properties();
|
int len = 0;
|
||||||
props.load(new ByteArrayInputStream(serializedProperties));
|
for (long p = cstring; unsafe.getByte(p) != 0; p++) {
|
||||||
Map<String, String> map = new HashMap<>(props.size());
|
len++;
|
||||||
for (var e : props.entrySet()) {
|
}
|
||||||
map.put((String) e.getKey(), (String) e.getValue());
|
byte[] buf = new byte[len];
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
buf[i] = unsafe.getByte(cstring + i);
|
||||||
|
}
|
||||||
|
return new String(buf, java.nio.charset.StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
savedProperties = Collections.unmodifiableMap(map);
|
/**
|
||||||
|
* Gets the value of {@code Arguments::systemProperties()} and puts the offsets
|
||||||
|
* of {@code SystemProperty} fields into {@code offsets}. The values returned in
|
||||||
|
* {@code offsets} are:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* [ next, // SystemProperty::next_offset_in_bytes()
|
||||||
|
* key, // SystemProperty::key_offset_in_bytes()
|
||||||
|
* value // PathString::value_offset_in_bytes()
|
||||||
|
* ]
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* Ideally this would be done with vmstructs but that code is in {@code jdk.vm.ci.hotspot}.
|
||||||
|
*/
|
||||||
|
private static native long readSystemPropertiesInfo(int[] offsets);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the native {@code Arguments::systemProperties()} data structure using Unsafe to
|
||||||
|
* create a properties map. This parsing is safe as argument parsing in completed in
|
||||||
|
* early VM start before this code can be executed, making {@code Arguments::systemProperties()}
|
||||||
|
* effectively read-only by now.
|
||||||
|
*/
|
||||||
|
private static Map<String, String> initProperties() {
|
||||||
|
int[] offsets = new int[3];
|
||||||
|
long systemProperties = readSystemPropertiesInfo(offsets);
|
||||||
|
int nextOffset = offsets[0];
|
||||||
|
int keyOffset = offsets[1];
|
||||||
|
int valueOffset = offsets[2];
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
Unsafe unsafe = Unsafe.getUnsafe();
|
||||||
|
for (long prop = systemProperties; prop != 0; prop = unsafe.getLong(prop + nextOffset)) {
|
||||||
|
if (unsafe.getLong(prop + valueOffset) != 0) {
|
||||||
|
count++;
|
||||||
|
} else {
|
||||||
|
// Some internal properties (e.g. jdk.boot.class.path.append) can have a null
|
||||||
|
// value and should just be ignored. Note that null is different than the empty string.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Map<String, SystemProperties.Value> props = new HashMap<>(count + 1);
|
||||||
|
int i = 0;
|
||||||
|
for (long prop = systemProperties; prop != 0; prop = unsafe.getLong(prop + nextOffset)) {
|
||||||
|
String key = toJavaString(unsafe, unsafe.getLong(prop + keyOffset));
|
||||||
|
long valueAddress = unsafe.getLong(prop + valueOffset);
|
||||||
|
if (valueAddress != 0) {
|
||||||
|
props.put(key, new SystemProperties.Value(unsafe, valueAddress));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i != count) {
|
||||||
|
throw new InternalError(i + " != " + count);
|
||||||
|
}
|
||||||
|
if (!props.containsKey("java.specification.version")) {
|
||||||
|
SystemProperties.Value v = Objects.requireNonNull(props.get("java.vm.specification.version"));
|
||||||
|
props.put("java.specification.version", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemProperties res = new SystemProperties(unsafe, sanitizeOSArch(props));
|
||||||
|
if ("true".equals(res.get("debug.jvmci.PrintSavedProperties"))) {
|
||||||
|
System.out.println("[Saved system properties]");
|
||||||
|
for (Map.Entry<String, String> e : res.entrySet()) {
|
||||||
|
System.out.printf("%s=%s%n", e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force os.name and os.arch to reflect the actual OS and architecture.
|
||||||
|
// JVMCI configures itself based on these values and needs to be isolated
|
||||||
|
// from apps that set them on the command line.
|
||||||
|
private static Map<String, SystemProperties.Value> sanitizeOSArch(Map<String, SystemProperties.Value> props) {
|
||||||
|
props.put("os.arch", new SystemProperties.Value(realArch()));
|
||||||
|
props.put("os.name", new SystemProperties.Value(realOS()));
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String realOS() {
|
||||||
|
OperatingSystem os = OperatingSystem.current();
|
||||||
|
switch (os) {
|
||||||
|
case LINUX: return "Linux";
|
||||||
|
case MACOS: return "Mac OS X";
|
||||||
|
case AIX: return "AIX";
|
||||||
|
case WINDOWS: {
|
||||||
|
String osName = System.getProperty("os.name");
|
||||||
|
if (osName.startsWith("Windows")) {
|
||||||
|
// Use original value which is often more "complete"
|
||||||
|
// E.g. "Windows Server 2012"
|
||||||
|
return osName;
|
||||||
|
}
|
||||||
|
return "Windows";
|
||||||
|
}
|
||||||
|
default: throw new InternalError("missing case for " + os);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String realArch() {
|
||||||
|
Architecture arch = Architecture.current();
|
||||||
|
switch (arch) {
|
||||||
|
case X64: return "x86_64";
|
||||||
|
case X86: return "x86";
|
||||||
|
case AARCH64: return "aarch64";
|
||||||
|
case RISCV64: return "riscv64";
|
||||||
|
case ARM: return "arm";
|
||||||
|
case S390: return "s390";
|
||||||
|
case PPC64: return "ppc64";
|
||||||
|
case OTHER: return "other";
|
||||||
|
default: throw new InternalError("missing case for " + arch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, 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 jdk.vm.ci.services;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import jdk.internal.misc.Unsafe;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unmodifiable map for storing system properties read from native memory whose values have their
|
||||||
|
* string representation constructed on first access.
|
||||||
|
*/
|
||||||
|
final class SystemProperties implements Map<String, String> {
|
||||||
|
|
||||||
|
private final Unsafe unsafe;
|
||||||
|
private final Map<String, Value> entries;
|
||||||
|
private Set<Entry<String, String>> entrySet;
|
||||||
|
private Collection<String> values;
|
||||||
|
|
||||||
|
SystemProperties(Unsafe unsafe, Map<String, Value> entries) {
|
||||||
|
this.unsafe = unsafe;
|
||||||
|
this.entries = entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return entries.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return entries.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsKey(Object key) {
|
||||||
|
return entries.containsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsValue(Object value) {
|
||||||
|
for (Value v : entries.values()) {
|
||||||
|
if (v.getString(unsafe).equals(value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String get(Object key) {
|
||||||
|
Value v = entries.get(key);
|
||||||
|
if (v != null) {
|
||||||
|
return v.getString(unsafe);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String put(String key, String value) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String remove(Object key) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putAll(Map<? extends String, ? extends String> m) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> keySet() {
|
||||||
|
return entries.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> values() {
|
||||||
|
if (values == null) {
|
||||||
|
values = entries.values().stream().map(v -> v.getString(unsafe)).collect(Collectors.toUnmodifiableList());
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Property implements Map.Entry<String, String> {
|
||||||
|
private final Unsafe unsafe;
|
||||||
|
private final String key;
|
||||||
|
private final Value value;
|
||||||
|
|
||||||
|
Property(Unsafe unsafe, Map.Entry<String, Value> e) {
|
||||||
|
this.unsafe = unsafe;
|
||||||
|
this.key = e.getKey();
|
||||||
|
this.value = e.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValue() {
|
||||||
|
return value.getString(unsafe);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String setValue(String value) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Entry<String, String>> entrySet() {
|
||||||
|
if (entrySet == null) {
|
||||||
|
entrySet = entries.entrySet().stream().map(e -> new Property(unsafe, e)).collect(Collectors.toUnmodifiableSet());
|
||||||
|
}
|
||||||
|
return entrySet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a value in {@link SystemProperties}.
|
||||||
|
*/
|
||||||
|
static class Value {
|
||||||
|
private final long cstring;
|
||||||
|
private volatile String string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a value whose string representation will be lazily constructed from {@code cstring}.
|
||||||
|
*/
|
||||||
|
Value(Unsafe unsafe, long cstring) {
|
||||||
|
this.cstring = cstring;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a value whose string representation is known at construction time.
|
||||||
|
*/
|
||||||
|
Value(String string) {
|
||||||
|
this.cstring = 0;
|
||||||
|
this.string = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getString(Unsafe unsafe) {
|
||||||
|
if (string == null) {
|
||||||
|
// Racy but it doesn't matter.
|
||||||
|
string = Services.toJavaString(unsafe, cstring);
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, 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 TestJVMCISavedProperties
|
||||||
|
* @bug 8309390
|
||||||
|
* @summary Ensures Services.getSavedProperties() includes properties set on
|
||||||
|
* the command line as well some specified properties but not
|
||||||
|
* properties set programmatically.
|
||||||
|
* @requires vm.flagless
|
||||||
|
* @requires vm.jvmci
|
||||||
|
* @library /test/lib
|
||||||
|
* @run driver TestJVMCISavedProperties
|
||||||
|
*/
|
||||||
|
|
||||||
|
import jdk.test.lib.Asserts;
|
||||||
|
import jdk.test.lib.process.ProcessTools;
|
||||||
|
import jdk.test.lib.process.OutputAnalyzer;
|
||||||
|
|
||||||
|
public class TestJVMCISavedProperties {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
if (args.length != 0) {
|
||||||
|
System.setProperty("app3.NotPresentInSavedProperties", "42");
|
||||||
|
System.out.println("DONE IN MAIN");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
|
||||||
|
"-XX:+UnlockExperimentalVMOptions",
|
||||||
|
"-XX:+EagerJVMCI",
|
||||||
|
"-XX:+UseJVMCICompiler",
|
||||||
|
"-Djvmci.Compiler=null",
|
||||||
|
"-Ddebug.jvmci.PrintSavedProperties=true",
|
||||||
|
"-Dapp1.propX=true",
|
||||||
|
"-Dapp2.propY=SomeStringValue",
|
||||||
|
"TestJVMCISavedProperties", "true");
|
||||||
|
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||||
|
output.stdoutShouldContain("debug.jvmci.PrintSavedProperties=true");
|
||||||
|
output.stdoutShouldContain("jvmci.Compiler=null");
|
||||||
|
output.stdoutShouldContain("app1.propX=true");
|
||||||
|
output.stdoutShouldContain("app2.propY=SomeStringValue");
|
||||||
|
output.stdoutShouldContain("java.specification.version=" + Runtime.version().feature());
|
||||||
|
output.stdoutShouldContain("os.name=");
|
||||||
|
output.stdoutShouldContain("os.arch=");
|
||||||
|
output.stdoutShouldNotContain("NotPresentInSavedProperties");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue