::store_at(as_oop(), offset, jboolean(value & 1)); }
inline jshort oopDesc::short_field(int offset) const { return HeapAccess<>::load_at(as_oop(), offset); }
inline void oopDesc::short_field_put(int offset, jshort value) { HeapAccess<>::store_at(as_oop(), offset, value); }
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/opto/c2compiler.cpp
--- a/src/hotspot/share/opto/c2compiler.cpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/opto/c2compiler.cpp Mon Nov 04 11:25:55 2019 +0000
@@ -582,7 +582,6 @@
case vmIntrinsics::_storeFence:
case vmIntrinsics::_fullFence:
case vmIntrinsics::_currentThread:
- case vmIntrinsics::_isInterrupted:
#ifdef JFR_HAVE_INTRINSICS
case vmIntrinsics::_counterTime:
case vmIntrinsics::_getClassId:
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/opto/library_call.cpp
--- a/src/hotspot/share/opto/library_call.cpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/opto/library_call.cpp Mon Nov 04 11:25:55 2019 +0000
@@ -264,7 +264,6 @@
bool inline_native_classID();
bool inline_native_getEventWriter();
#endif
- bool inline_native_isInterrupted();
bool inline_native_Class_query(vmIntrinsics::ID id);
bool inline_native_subtype_check();
bool inline_native_getLength();
@@ -752,7 +751,6 @@
case vmIntrinsics::_onSpinWait: return inline_onspinwait();
case vmIntrinsics::_currentThread: return inline_native_currentThread();
- case vmIntrinsics::_isInterrupted: return inline_native_isInterrupted();
#ifdef JFR_HAVE_INTRINSICS
case vmIntrinsics::_counterTime: return inline_native_time_funcs(CAST_FROM_FN_PTR(address, JFR_TIME_FUNCTION), "counterTime");
@@ -3041,128 +3039,6 @@
return true;
}
-//------------------------inline_native_isInterrupted------------------
-// private native boolean java.lang.Thread.isInterrupted(boolean ClearInterrupted);
-bool LibraryCallKit::inline_native_isInterrupted() {
- // Add a fast path to t.isInterrupted(clear_int):
- // (t == Thread.current() &&
- // (!TLS._osthread._interrupted || WINDOWS_ONLY(false) NOT_WINDOWS(!clear_int)))
- // ? TLS._osthread._interrupted : /*slow path:*/ t.isInterrupted(clear_int)
- // So, in the common case that the interrupt bit is false,
- // we avoid making a call into the VM. Even if the interrupt bit
- // is true, if the clear_int argument is false, we avoid the VM call.
- // However, if the receiver is not currentThread, we must call the VM,
- // because there must be some locking done around the operation.
-
- // We only go to the fast case code if we pass two guards.
- // Paths which do not pass are accumulated in the slow_region.
-
- enum {
- no_int_result_path = 1, // t == Thread.current() && !TLS._osthread._interrupted
- no_clear_result_path = 2, // t == Thread.current() && TLS._osthread._interrupted && !clear_int
- slow_result_path = 3, // slow path: t.isInterrupted(clear_int)
- PATH_LIMIT
- };
-
- // Ensure that it's not possible to move the load of TLS._osthread._interrupted flag
- // out of the function.
- insert_mem_bar(Op_MemBarCPUOrder);
-
- RegionNode* result_rgn = new RegionNode(PATH_LIMIT);
- PhiNode* result_val = new PhiNode(result_rgn, TypeInt::BOOL);
-
- RegionNode* slow_region = new RegionNode(1);
- record_for_igvn(slow_region);
-
- // (a) Receiving thread must be the current thread.
- Node* rec_thr = argument(0);
- Node* tls_ptr = NULL;
- Node* cur_thr = generate_current_thread(tls_ptr);
-
- // Resolve oops to stable for CmpP below.
- cur_thr = access_resolve(cur_thr, 0);
- rec_thr = access_resolve(rec_thr, 0);
-
- Node* cmp_thr = _gvn.transform(new CmpPNode(cur_thr, rec_thr));
- Node* bol_thr = _gvn.transform(new BoolNode(cmp_thr, BoolTest::ne));
-
- generate_slow_guard(bol_thr, slow_region);
-
- // (b) Interrupt bit on TLS must be false.
- Node* p = basic_plus_adr(top()/*!oop*/, tls_ptr, in_bytes(JavaThread::osthread_offset()));
- Node* osthread = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS, MemNode::unordered);
- p = basic_plus_adr(top()/*!oop*/, osthread, in_bytes(OSThread::interrupted_offset()));
-
- // Set the control input on the field _interrupted read to prevent it floating up.
- Node* int_bit = make_load(control(), p, TypeInt::BOOL, T_INT, MemNode::unordered);
- Node* cmp_bit = _gvn.transform(new CmpINode(int_bit, intcon(0)));
- Node* bol_bit = _gvn.transform(new BoolNode(cmp_bit, BoolTest::ne));
-
- IfNode* iff_bit = create_and_map_if(control(), bol_bit, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
-
- // First fast path: if (!TLS._interrupted) return false;
- Node* false_bit = _gvn.transform(new IfFalseNode(iff_bit));
- result_rgn->init_req(no_int_result_path, false_bit);
- result_val->init_req(no_int_result_path, intcon(0));
-
- // drop through to next case
- set_control( _gvn.transform(new IfTrueNode(iff_bit)));
-
-#ifndef _WINDOWS
- // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path.
- Node* clr_arg = argument(1);
- Node* cmp_arg = _gvn.transform(new CmpINode(clr_arg, intcon(0)));
- Node* bol_arg = _gvn.transform(new BoolNode(cmp_arg, BoolTest::ne));
- IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN);
-
- // Second fast path: ... else if (!clear_int) return true;
- Node* false_arg = _gvn.transform(new IfFalseNode(iff_arg));
- result_rgn->init_req(no_clear_result_path, false_arg);
- result_val->init_req(no_clear_result_path, intcon(1));
-
- // drop through to next case
- set_control( _gvn.transform(new IfTrueNode(iff_arg)));
-#else
- // To return true on Windows you must read the _interrupted field
- // and check the event state i.e. take the slow path.
-#endif // _WINDOWS
-
- // (d) Otherwise, go to the slow path.
- slow_region->add_req(control());
- set_control( _gvn.transform(slow_region));
-
- if (stopped()) {
- // There is no slow path.
- result_rgn->init_req(slow_result_path, top());
- result_val->init_req(slow_result_path, top());
- } else {
- // non-virtual because it is a private non-static
- CallJavaNode* slow_call = generate_method_call(vmIntrinsics::_isInterrupted);
-
- Node* slow_val = set_results_for_java_call(slow_call);
- // this->control() comes from set_results_for_java_call
-
- Node* fast_io = slow_call->in(TypeFunc::I_O);
- Node* fast_mem = slow_call->in(TypeFunc::Memory);
-
- // These two phis are pre-filled with copies of of the fast IO and Memory
- PhiNode* result_mem = PhiNode::make(result_rgn, fast_mem, Type::MEMORY, TypePtr::BOTTOM);
- PhiNode* result_io = PhiNode::make(result_rgn, fast_io, Type::ABIO);
-
- result_rgn->init_req(slow_result_path, control());
- result_io ->init_req(slow_result_path, i_o());
- result_mem->init_req(slow_result_path, reset_memory());
- result_val->init_req(slow_result_path, slow_val);
-
- set_all_memory(_gvn.transform(result_mem));
- set_i_o( _gvn.transform(result_io));
- }
-
- C->set_has_split_ifs(true); // Has chance for split-if optimization
- set_result(result_rgn, result_val);
- return true;
-}
-
//---------------------------load_mirror_from_klass----------------------------
// Given a klass oop, load its java mirror (a java.lang.Class oop).
Node* LibraryCallKit::load_mirror_from_klass(Node* klass) {
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/prims/jvm.cpp
--- a/src/hotspot/share/prims/jvm.cpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/prims/jvm.cpp Mon Nov 04 11:25:55 2019 +0000
@@ -3052,50 +3052,6 @@
return JNIHandles::make_local(env, jthread);
JVM_END
-class CountStackFramesTC : public ThreadClosure {
- int _count;
- bool _suspended;
- public:
- CountStackFramesTC() : _count(0), _suspended(false) {}
- virtual void do_thread(Thread* thread) {
- JavaThread* jt = (JavaThread*)thread;
- if (!jt->is_external_suspend()) {
- // To keep same behavior we fail this operation,
- // even if it would work perfectly.
- return;
- }
- _suspended = true;
- // Count all java activation, i.e., number of vframes.
- for (vframeStream vfst(jt); !vfst.at_end(); vfst.next()) {
- // Native frames are not counted.
- if (!vfst.method()->is_native()) _count++;
- }
- }
- int count() { return _count; }
- int suspended() { return _suspended; }
-};
-
-JVM_ENTRY(jint, JVM_CountStackFrames(JNIEnv* env, jobject jthread))
- JVMWrapper("JVM_CountStackFrames");
-
- ThreadsListHandle tlh(thread);
- JavaThread* receiver = NULL;
- bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);
- if (is_alive) {
- // jthread refers to a live JavaThread.
- CountStackFramesTC csf;
- Handshake::execute(&csf, receiver);
- if (!csf.suspended()) {
- THROW_MSG_0(vmSymbols::java_lang_IllegalThreadStateException(),
- "this thread is not suspended");
- }
- return csf.count();
- }
- // Implied else: if JavaThread is not alive simply return a count of 0.
- return 0;
-JVM_END
-
-
JVM_ENTRY(void, JVM_Interrupt(JNIEnv* env, jobject jthread))
JVMWrapper("JVM_Interrupt");
@@ -3109,21 +3065,6 @@
JVM_END
-JVM_ENTRY(jboolean, JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrupted))
- JVMWrapper("JVM_IsInterrupted");
-
- ThreadsListHandle tlh(thread);
- JavaThread* receiver = NULL;
- bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);
- if (is_alive) {
- // jthread refers to a live JavaThread.
- return (jboolean) receiver->is_interrupted(clear_interrupted != 0);
- } else {
- return JNI_FALSE;
- }
-JVM_END
-
-
// Return true iff the current thread has locked the object passed in
JVM_ENTRY(jboolean, JVM_HoldsLock(JNIEnv* env, jclass threadClass, jobject obj))
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/prims/jvmtiEnv.cpp
--- a/src/hotspot/share/prims/jvmtiEnv.cpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/prims/jvmtiEnv.cpp Mon Nov 04 11:25:55 2019 +0000
@@ -879,8 +879,7 @@
if (jts == _thread_in_native) {
state |= JVMTI_THREAD_STATE_IN_NATIVE;
}
- OSThread* osThread = java_thread->osthread();
- if (osThread != NULL && osThread->interrupted()) {
+ if (java_thread->is_interrupted(false)) {
state |= JVMTI_THREAD_STATE_INTERRUPTED;
}
}
@@ -1092,7 +1091,6 @@
// thread - NOT pre-checked
jvmtiError
JvmtiEnv::InterruptThread(jthread thread) {
- // TODO: this is very similar to JVM_Interrupt(); share code in future
JavaThread* current_thread = JavaThread::current();
JavaThread* java_thread = NULL;
ThreadsListHandle tlh(current_thread);
@@ -1100,7 +1098,11 @@
if (err != JVMTI_ERROR_NONE) {
return err;
}
-
+ // Really this should be a Java call to Thread.interrupt to ensure the same
+ // semantics, however historically this has not been done for some reason.
+ // So we continue with that (which means we don't interact with any Java-level
+ // Interruptible object) but we must set the Java-level interrupted state.
+ java_lang_Thread::set_interrupted(JNIHandles::resolve(thread), true);
java_thread->interrupt();
return JVMTI_ERROR_NONE;
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/prims/jvmtiEnvBase.cpp
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp Mon Nov 04 11:25:55 2019 +0000
@@ -1214,8 +1214,7 @@
if (jts == _thread_in_native) {
state |= JVMTI_THREAD_STATE_IN_NATIVE;
}
- OSThread* osThread = thr->osthread();
- if (osThread != NULL && osThread->interrupted()) {
+ if (thr->is_interrupted(false)) {
state |= JVMTI_THREAD_STATE_INTERRUPTED;
}
}
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/runtime/arguments.cpp
--- a/src/hotspot/share/runtime/arguments.cpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/runtime/arguments.cpp Mon Nov 04 11:25:55 2019 +0000
@@ -60,12 +60,6 @@
#include "jfr/jfr.hpp"
#endif
-// Note: This is a special bug reporting site for the JVM
-#ifdef VENDOR_URL_VM_BUG
-# define DEFAULT_VENDOR_URL_BUG VENDOR_URL_VM_BUG
-#else
-# define DEFAULT_VENDOR_URL_BUG "http://bugreport.java.com/bugreport/crash.jsp"
-#endif
#define DEFAULT_JAVA_LAUNCHER "generic"
char* Arguments::_jvm_flags_file = NULL;
@@ -80,7 +74,7 @@
Arguments::Mode Arguments::_mode = _mixed;
bool Arguments::_java_compiler = false;
bool Arguments::_xdebug_mode = false;
-const char* Arguments::_java_vendor_url_bug = DEFAULT_VENDOR_URL_BUG;
+const char* Arguments::_java_vendor_url_bug = NULL;
const char* Arguments::_sun_java_launcher = DEFAULT_JAVA_LAUNCHER;
bool Arguments::_sun_java_launcher_is_altjvm = false;
@@ -1422,12 +1416,16 @@
os::free(old_java_command);
}
} else if (strcmp(key, "java.vendor.url.bug") == 0) {
+ // If this property is set on the command line then its value will be
+ // displayed in VM error logs as the URL at which to submit such logs.
+ // Normally the URL displayed in error logs is different from the value
+ // of this system property, so a different property should have been
+ // used here, but we leave this as-is in case someone depends upon it.
const char* old_java_vendor_url_bug = _java_vendor_url_bug;
// save it in _java_vendor_url_bug, so JVM fatal error handler can access
// its value without going through the property list or making a Java call.
_java_vendor_url_bug = os::strdup_check_oom(value, mtArguments);
- if (old_java_vendor_url_bug != DEFAULT_VENDOR_URL_BUG) {
- assert(old_java_vendor_url_bug != NULL, "_java_vendor_url_bug is NULL");
+ if (old_java_vendor_url_bug != NULL) {
os::free((void *)old_java_vendor_url_bug);
}
}
@@ -2185,7 +2183,8 @@
// Parse JavaVMInitArgs structure
-jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
+jint Arguments::parse_vm_init_args(const JavaVMInitArgs *vm_options_args,
+ const JavaVMInitArgs *java_tool_options_args,
const JavaVMInitArgs *java_options_args,
const JavaVMInitArgs *cmd_line_args) {
bool patch_mod_javabase = false;
@@ -2203,9 +2202,15 @@
// Setup flags for mixed which is the default
set_mode_flags(_mixed);
+ // Parse args structure generated from java.base vm options resource
+ jint result = parse_each_vm_init_arg(vm_options_args, &patch_mod_javabase, JVMFlag::JIMAGE_RESOURCE);
+ if (result != JNI_OK) {
+ return result;
+ }
+
// Parse args structure generated from JAVA_TOOL_OPTIONS environment
// variable (if present).
- jint result = parse_each_vm_init_arg(java_tool_options_args, &patch_mod_javabase, JVMFlag::ENVIRON_VAR);
+ result = parse_each_vm_init_arg(java_tool_options_args, &patch_mod_javabase, JVMFlag::ENVIRON_VAR);
if (result != JNI_OK) {
return result;
}
@@ -2711,7 +2716,6 @@
needs_module_property_warning = true;
continue;
}
-
if (!add_property(tail)) {
return JNI_ENOMEM;
}
@@ -3143,7 +3147,13 @@
NOT_PRODUCT(UNSUPPORTED_OPTION(TraceProfileInterpreter));
#endif
-#ifndef TIERED
+
+#ifdef TIERED
+ // Parse the CompilationMode flag
+ if (!CompilationModeFlag::initialize()) {
+ return JNI_ERR;
+ }
+#else
// Tiered compilation is undefined.
UNSUPPORTED_OPTION(TieredCompilation);
#endif
@@ -3832,16 +3842,19 @@
const char* hotspotrc = ".hotspotrc";
bool settings_file_specified = false;
bool needs_hotspotrc_warning = false;
+ ScopedVMInitArgs initial_vm_options_args("");
ScopedVMInitArgs initial_java_tool_options_args("env_var='JAVA_TOOL_OPTIONS'");
ScopedVMInitArgs initial_java_options_args("env_var='_JAVA_OPTIONS'");
// Pointers to current working set of containers
JavaVMInitArgs* cur_cmd_args;
+ JavaVMInitArgs* cur_vm_options_args;
JavaVMInitArgs* cur_java_options_args;
JavaVMInitArgs* cur_java_tool_options_args;
// Containers for modified/expanded options
ScopedVMInitArgs mod_cmd_args("cmd_line_args");
+ ScopedVMInitArgs mod_vm_options_args("vm_options_args");
ScopedVMInitArgs mod_java_tool_options_args("env_var='JAVA_TOOL_OPTIONS'");
ScopedVMInitArgs mod_java_options_args("env_var='_JAVA_OPTIONS'");
@@ -3857,6 +3870,16 @@
return code;
}
+ // Parse the options in the /java.base/jdk/internal/vm/options resource, if present
+ char *vmoptions = ClassLoader::lookup_vm_options();
+ if (vmoptions != NULL) {
+ code = parse_options_buffer("vm options resource", vmoptions, strlen(vmoptions), &initial_vm_options_args);
+ FREE_C_HEAP_ARRAY(char, vmoptions);
+ if (code != JNI_OK) {
+ return code;
+ }
+ }
+
code = expand_vm_options_as_needed(initial_java_tool_options_args.get(),
&mod_java_tool_options_args,
&cur_java_tool_options_args);
@@ -3878,6 +3901,13 @@
return code;
}
+ code = expand_vm_options_as_needed(initial_vm_options_args.get(),
+ &mod_vm_options_args,
+ &cur_vm_options_args);
+ if (code != JNI_OK) {
+ return code;
+ }
+
const char* flags_file = Arguments::get_jvm_flags_file();
settings_file_specified = (flags_file != NULL);
@@ -3915,7 +3945,8 @@
}
// Parse JavaVMInitArgs structure passed in, as well as JAVA_TOOL_OPTIONS and _JAVA_OPTIONS
- jint result = parse_vm_init_args(cur_java_tool_options_args,
+ jint result = parse_vm_init_args(cur_vm_options_args,
+ cur_java_tool_options_args,
cur_java_options_args,
cur_cmd_args);
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/runtime/arguments.hpp
--- a/src/hotspot/share/runtime/arguments.hpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/runtime/arguments.hpp Mon Nov 04 11:25:55 2019 +0000
@@ -427,7 +427,8 @@
static void handle_extra_cms_flags(const char* msg);
- static jint parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
+ static jint parse_vm_init_args(const JavaVMInitArgs *vm_options_args,
+ const JavaVMInitArgs *java_tool_options_args,
const JavaVMInitArgs *java_options_args,
const JavaVMInitArgs *cmd_line_args);
static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_mod_javabase, JVMFlag::Flags origin);
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/runtime/flags/jvmFlag.cpp
--- a/src/hotspot/share/runtime/flags/jvmFlag.cpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/runtime/flags/jvmFlag.cpp Mon Nov 04 11:25:55 2019 +0000
@@ -709,6 +709,8 @@
st->print("attach"); break;
case INTERNAL:
st->print("internal"); break;
+ case JIMAGE_RESOURCE:
+ st->print("jimage"); break;
}
st->print("}");
}
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/runtime/flags/jvmFlag.hpp
--- a/src/hotspot/share/runtime/flags/jvmFlag.hpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/runtime/flags/jvmFlag.hpp Mon Nov 04 11:25:55 2019 +0000
@@ -44,8 +44,9 @@
ERGONOMIC = 5,
ATTACH_ON_DEMAND = 6,
INTERNAL = 7,
+ JIMAGE_RESOURCE = 8,
- LAST_VALUE_ORIGIN = INTERNAL,
+ LAST_VALUE_ORIGIN = JIMAGE_RESOURCE,
VALUE_ORIGIN_BITS = 4,
VALUE_ORIGIN_MASK = right_n_bits(VALUE_ORIGIN_BITS),
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/runtime/flags/jvmFlagConstraintsCompiler.cpp
--- a/src/hotspot/share/runtime/flags/jvmFlagConstraintsCompiler.cpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/runtime/flags/jvmFlagConstraintsCompiler.cpp Mon Nov 04 11:25:55 2019 +0000
@@ -60,16 +60,29 @@
* 4) The JVM is build using the compilers and tiered compilation is enabled. The option
* 'TieredStopAtLevel = CompLevel_full_optimization' (the default value). As a result,
* the minimum number of compiler threads is 2.
+ * 5) Non-tiered emulation mode is on. CompilationModeFlag::disable_intermediate() == true.
+ * The mininum number of threads is 2. But if CompilationModeFlag::quick_internal() == false, then it's 1.
*/
JVMFlag::Error CICompilerCountConstraintFunc(intx value, bool verbose) {
int min_number_of_compiler_threads = 0;
#if !defined(COMPILER1) && !defined(COMPILER2) && !INCLUDE_JVMCI
// case 1
#else
- if (!TieredCompilation || (TieredStopAtLevel < CompLevel_full_optimization)) {
- min_number_of_compiler_threads = 1; // case 2 or case 3
+ if (TieredCompilation) {
+ if (TieredStopAtLevel < CompLevel_full_optimization || CompilationModeFlag::quick_only()) {
+ min_number_of_compiler_threads = 1; // case 3
+ } else if (CompilationModeFlag::disable_intermediate()) {
+ // case 5
+ if (CompilationModeFlag::quick_internal()) {
+ min_number_of_compiler_threads = 2;
+ } else {
+ min_number_of_compiler_threads = 1;
+ }
+ } else {
+ min_number_of_compiler_threads = 2; // case 4 (tiered)
+ }
} else {
- min_number_of_compiler_threads = 2; // case 4 (tiered)
+ min_number_of_compiler_threads = 1; // case 2
}
#endif
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/runtime/globals.hpp
--- a/src/hotspot/share/runtime/globals.hpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/runtime/globals.hpp Mon Nov 04 11:25:55 2019 +0000
@@ -2059,6 +2059,35 @@
"if coming from AOT") \
range(0, max_jint) \
\
+ diagnostic(intx, Tier0AOTInvocationThreshold, 200, \
+ "Switch to interpreter to profile if the number of method " \
+ "invocations crosses this threshold if coming from AOT " \
+ "(applicable only with " \
+ "CompilationMode=high-only|high-only-quick-internal)") \
+ range(0, max_jint) \
+ \
+ diagnostic(intx, Tier0AOTMinInvocationThreshold, 100, \
+ "Minimum number of invocations to switch to interpreter " \
+ "to profile if coming from AOT " \
+ "(applicable only with " \
+ "CompilationMode=high-only|high-only-quick-internal)") \
+ range(0, max_jint) \
+ \
+ diagnostic(intx, Tier0AOTCompileThreshold, 2000, \
+ "Threshold at which to switch to interpreter to profile " \
+ "if coming from AOT " \
+ "(invocation minimum must be satisfied, " \
+ "applicable only with " \
+ "CompilationMode=high-only|high-only-quick-internal)") \
+ range(0, max_jint) \
+ \
+ diagnostic(intx, Tier0AOTBackEdgeThreshold, 60000, \
+ "Back edge threshold at which to switch to interpreter " \
+ "to profile if coming from AOT " \
+ "(applicable only with " \
+ "CompilationMode=high-only|high-only-quick-internal)") \
+ range(0, max_jint) \
+ \
product(intx, Tier4InvocationThreshold, 5000, \
"Compile if number of method invocations crosses this " \
"threshold") \
@@ -2070,13 +2099,44 @@
\
product(intx, Tier4CompileThreshold, 15000, \
"Threshold at which tier 4 compilation is invoked (invocation " \
- "minimum must be satisfied") \
+ "minimum must be satisfied)") \
range(0, max_jint) \
\
product(intx, Tier4BackEdgeThreshold, 40000, \
"Back edge threshold at which tier 4 OSR compilation is invoked") \
range(0, max_jint) \
\
+ diagnostic(intx, Tier40InvocationThreshold, 5000, \
+ "Compile if number of method invocations crosses this " \
+ "threshold (applicable only with " \
+ "CompilationMode=high-only|high-only-quick-internal)") \
+ range(0, max_jint) \
+ \
+ diagnostic(intx, Tier40MinInvocationThreshold, 600, \
+ "Minimum number of invocations to compile at tier 4 " \
+ "(applicable only with " \
+ "CompilationMode=high-only|high-only-quick-internal)") \
+ range(0, max_jint) \
+ \
+ diagnostic(intx, Tier40CompileThreshold, 10000, \
+ "Threshold at which tier 4 compilation is invoked (invocation " \
+ "minimum must be satisfied, applicable only with " \
+ "CompilationMode=high-only|high-only-quick-internal)") \
+ range(0, max_jint) \
+ \
+ diagnostic(intx, Tier40BackEdgeThreshold, 15000, \
+ "Back edge threshold at which tier 4 OSR compilation is invoked " \
+ "(applicable only with " \
+ "CompilationMode=high-only|high-only-quick-internal)") \
+ range(0, max_jint) \
+ \
+ diagnostic(intx, Tier0Delay, 5, \
+ "If C2 queue size grows over this amount per compiler thread " \
+ "do not start profiling in the interpreter " \
+ "(applicable only with " \
+ "CompilationMode=high-only|high-only-quick-internal)") \
+ range(0, max_jint) \
+ \
product(intx, Tier3DelayOn, 5, \
"If C2 queue size grows over this amount per compiler thread " \
"stop compiling at tier 3 and start compiling at tier 2") \
@@ -2108,7 +2168,9 @@
\
product(intx, Tier0ProfilingStartPercentage, 200, \
"Start profiling in interpreter if the counters exceed tier 3 " \
- "thresholds by the specified percentage") \
+ "thresholds (tier 4 thresholds with " \
+ "CompilationMode=high-only|high-only-quick-internal)" \
+ "by the specified percentage") \
range(0, max_jint) \
\
product(uintx, IncreaseFirstTierCompileThresholdAt, 50, \
@@ -2124,6 +2186,14 @@
"Maximum rate sampling interval (in milliseconds)") \
range(0, max_intx) \
\
+ product(ccstr, CompilationMode, "default", \
+ "Compilation modes: " \
+ "default: normal tiered compilation; " \
+ "quick-only: C1-only mode; " \
+ "high-only: C2/JVMCI-only mode; " \
+ "high-only-quick-internal: C2/JVMCI-only mode, " \
+ "with JVMCI compiler compiled with C1.") \
+ \
product_pd(bool, TieredCompilation, \
"Enable tiered compilation") \
\
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/runtime/java.cpp
--- a/src/hotspot/share/runtime/java.cpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/runtime/java.cpp Mon Nov 04 11:25:55 2019 +0000
@@ -690,6 +690,8 @@
JDK_Version JDK_Version::_current;
const char* JDK_Version::_runtime_name;
const char* JDK_Version::_runtime_version;
+const char* JDK_Version::_runtime_vendor_version;
+const char* JDK_Version::_runtime_vendor_vm_bug_url;
void JDK_Version::initialize() {
jdk_version_info info;
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/runtime/java.hpp
--- a/src/hotspot/share/runtime/java.hpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/runtime/java.hpp Mon Nov 04 11:25:55 2019 +0000
@@ -67,6 +67,8 @@
static JDK_Version _current;
static const char* _runtime_name;
static const char* _runtime_version;
+ static const char* _runtime_vendor_version;
+ static const char* _runtime_vendor_vm_bug_url;
uint8_t _major;
uint8_t _minor;
@@ -142,6 +144,20 @@
_runtime_version = version;
}
+ static const char* runtime_vendor_version() {
+ return _runtime_vendor_version;
+ }
+ static void set_runtime_vendor_version(const char* vendor_version) {
+ _runtime_vendor_version = vendor_version;
+ }
+
+ static const char* runtime_vendor_vm_bug_url() {
+ return _runtime_vendor_vm_bug_url;
+ }
+ static void set_runtime_vendor_vm_bug_url(const char* vendor_vm_bug_url) {
+ _runtime_vendor_vm_bug_url = vendor_vm_bug_url;
+ }
+
};
#endif // SHARE_RUNTIME_JAVA_HPP
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/runtime/mutexLocker.cpp
--- a/src/hotspot/share/runtime/mutexLocker.cpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/runtime/mutexLocker.cpp Mon Nov 04 11:25:55 2019 +0000
@@ -312,7 +312,7 @@
#if INCLUDE_JFR
def(JfrMsg_lock , PaddedMonitor, leaf, true, _safepoint_check_always);
def(JfrBuffer_lock , PaddedMutex , leaf, true, _safepoint_check_never);
- def(JfrStream_lock , PaddedMutex , leaf+1, true, _safepoint_check_never); // ensure to rank lower than 'safepoint'
+ def(JfrStream_lock , PaddedMutex , nonleaf + 1, false, _safepoint_check_always);
def(JfrStacktrace_lock , PaddedMutex , special, true, _safepoint_check_never);
def(JfrThreadSampler_lock , PaddedMonitor, leaf, true, _safepoint_check_never);
#endif
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/runtime/osThread.cpp
--- a/src/hotspot/share/runtime/osThread.cpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/runtime/osThread.cpp Mon Nov 04 11:25:55 2019 +0000
@@ -30,7 +30,6 @@
pd_initialize();
set_start_proc(start_proc);
set_start_parm(start_parm);
- _interrupted = 0;
}
OSThread::~OSThread() {
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/runtime/osThread.hpp
--- a/src/hotspot/share/runtime/osThread.hpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/runtime/osThread.hpp Mon Nov 04 11:25:55 2019 +0000
@@ -62,12 +62,6 @@
OSThreadStartFunc _start_proc; // Thread start routine
void* _start_parm; // Thread start routine parameter
volatile ThreadState _state; // Thread state *hint*
- volatile jint _interrupted; // Thread.isInterrupted state
-
- // Note: _interrupted must be jint, so that Java intrinsics can access it.
- // The value stored there must be either 0 or 1. It must be possible
- // for Java to emulate Thread.currentThread().isInterrupted() by performing
- // the double indirection Thread::current()->_osthread->_interrupted.
// Methods
public:
@@ -82,18 +76,14 @@
void set_start_proc(OSThreadStartFunc start_proc) { _start_proc = start_proc; }
void* start_parm() const { return _start_parm; }
void set_start_parm(void* start_parm) { _start_parm = start_parm; }
- // These are specialized on Windows.
+ // This is specialized on Windows.
#ifndef _WINDOWS
- volatile bool interrupted() const { return _interrupted != 0; }
- void set_interrupted(bool z) { _interrupted = z ? 1 : 0; }
+ void set_interrupted(bool z) { /* nothing to do */ }
#endif
// Printing
void print_on(outputStream* st) const;
void print() const;
- // For java intrinsics:
- static ByteSize interrupted_offset() { return byte_offset_of(OSThread, _interrupted); }
-
// Platform dependent stuff
#include OS_HEADER(osThread)
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/runtime/thread.cpp
--- a/src/hotspot/share/runtime/thread.cpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/runtime/thread.cpp Mon Nov 04 11:25:55 2019 +0000
@@ -1090,6 +1090,8 @@
char java_runtime_name[128] = "";
char java_runtime_version[128] = "";
+char java_runtime_vendor_version[128] = "";
+char java_runtime_vendor_vm_bug_url[128] = "";
// extract the JRE name from java.lang.VersionProps.java_runtime_name
static const char* get_java_runtime_name(TRAPS) {
@@ -1135,6 +1137,50 @@
}
}
+// extract the JRE vendor version from java.lang.VersionProps.VENDOR_VERSION
+static const char* get_java_runtime_vendor_version(TRAPS) {
+ Klass* k = SystemDictionary::find(vmSymbols::java_lang_VersionProps(),
+ Handle(), Handle(), CHECK_AND_CLEAR_NULL);
+ fieldDescriptor fd;
+ bool found = k != NULL &&
+ InstanceKlass::cast(k)->find_local_field(vmSymbols::java_runtime_vendor_version_name(),
+ vmSymbols::string_signature(), &fd);
+ if (found) {
+ oop name_oop = k->java_mirror()->obj_field(fd.offset());
+ if (name_oop == NULL) {
+ return NULL;
+ }
+ const char* name = java_lang_String::as_utf8_string(name_oop,
+ java_runtime_vendor_version,
+ sizeof(java_runtime_vendor_version));
+ return name;
+ } else {
+ return NULL;
+ }
+}
+
+// extract the JRE vendor VM bug URL from java.lang.VersionProps.VENDOR_URL_VM_BUG
+static const char* get_java_runtime_vendor_vm_bug_url(TRAPS) {
+ Klass* k = SystemDictionary::find(vmSymbols::java_lang_VersionProps(),
+ Handle(), Handle(), CHECK_AND_CLEAR_NULL);
+ fieldDescriptor fd;
+ bool found = k != NULL &&
+ InstanceKlass::cast(k)->find_local_field(vmSymbols::java_runtime_vendor_vm_bug_url_name(),
+ vmSymbols::string_signature(), &fd);
+ if (found) {
+ oop name_oop = k->java_mirror()->obj_field(fd.offset());
+ if (name_oop == NULL) {
+ return NULL;
+ }
+ const char* name = java_lang_String::as_utf8_string(name_oop,
+ java_runtime_vendor_vm_bug_url,
+ sizeof(java_runtime_vendor_vm_bug_url));
+ return name;
+ } else {
+ return NULL;
+ }
+}
+
// General purpose hook into Java code, run once when the VM is initialized.
// The Java library method itself may be changed independently from the VM.
static void call_postVMInitHook(TRAPS) {
@@ -1679,19 +1725,13 @@
void JavaThread::interrupt() {
debug_only(check_for_dangling_thread_pointer(this);)
- if (!osthread()->interrupted()) {
- osthread()->set_interrupted(true);
- // More than one thread can get here with the same value of osthread,
- // resulting in multiple notifications. We do, however, want the store
- // to interrupted() to be visible to other threads before we execute unpark().
- OrderAccess::fence();
-
- // For JavaThread::sleep. Historically we only unpark if changing to the interrupted
- // state, in contrast to the other events below. Not clear exactly why.
- _SleepEvent->unpark();
- }
-
- // For JSR166. Unpark even if interrupt status already was set.
+ // For Windows _interrupt_event
+ osthread()->set_interrupted(true);
+
+ // For Thread.sleep
+ _SleepEvent->unpark();
+
+ // For JSR166 LockSupport.park
parker()->unpark();
// For ObjectMonitor and JvmtiRawMonitor
@@ -1701,11 +1741,11 @@
bool JavaThread::is_interrupted(bool clear_interrupted) {
debug_only(check_for_dangling_thread_pointer(this);)
- bool interrupted = osthread()->interrupted();
+ bool interrupted = java_lang_Thread::interrupted(threadObj());
// NOTE that since there is no "lock" around the interrupt and
// is_interrupted operations, there is the possibility that the
- // interrupted flag (in osThread) will be "false" but that the
+ // interrupted flag will be "false" but that the
// low-level events will be in the signaled state. This is
// intentional. The effect of this is that Object.wait() and
// LockSupport.park() will appear to have a spurious wakeup, which
@@ -1715,9 +1755,12 @@
// to JavaThread::sleep, so there is no early return. It has also been
// recommended not to put the interrupted flag into the "event"
// structure because it hides the issue.
+ // Also, because there is no lock, we must only clear the interrupt
+ // state if we are going to report that we were interrupted; otherwise
+ // an interrupt that happens just after we read the field would be lost.
if (interrupted && clear_interrupted) {
+ java_lang_Thread::set_interrupted(threadObj(), false);
osthread()->set_interrupted(false);
- // consider thread->_SleepEvent->reset() ... optional optimization
}
return interrupted;
@@ -2371,6 +2414,7 @@
// Interrupt thread so it will wake up from a potential wait()/sleep()/park()
+ java_lang_Thread::set_interrupted(threadObj(), true);
this->interrupt();
}
@@ -3656,9 +3700,11 @@
// Phase 1 of the system initialization in the library, java.lang.System class initialization
call_initPhase1(CHECK);
- // get the Java runtime name after java.lang.System is initialized
+ // get the Java runtime name, version, and vendor info after java.lang.System is initialized
JDK_Version::set_runtime_name(get_java_runtime_name(THREAD));
JDK_Version::set_runtime_version(get_java_runtime_version(THREAD));
+ JDK_Version::set_runtime_vendor_version(get_java_runtime_vendor_version(THREAD));
+ JDK_Version::set_runtime_vendor_vm_bug_url(get_java_runtime_vendor_vm_bug_url(THREAD));
// an instance of OutOfMemory exception has been allocated earlier
initialize_class(vmSymbols::java_lang_OutOfMemoryError(), CHECK);
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/runtime/vmStructs.cpp
--- a/src/hotspot/share/runtime/vmStructs.cpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/runtime/vmStructs.cpp Mon Nov 04 11:25:55 2019 +0000
@@ -786,7 +786,6 @@
/* OSThread */ \
/************/ \
\
- volatile_nonstatic_field(OSThread, _interrupted, jint) \
volatile_nonstatic_field(OSThread, _state, ThreadState) \
\
/************************/ \
@@ -2612,6 +2611,7 @@
declare_constant(JVMFlag::ERGONOMIC) \
declare_constant(JVMFlag::ATTACH_ON_DEMAND) \
declare_constant(JVMFlag::INTERNAL) \
+ declare_constant(JVMFlag::JIMAGE_RESOURCE) \
declare_constant(JVMFlag::VALUE_ORIGIN_MASK) \
declare_constant(JVMFlag::ORIG_COMMAND_LINE)
diff -r 12b08b510fd0 -r 2c777f25cfff src/hotspot/share/utilities/vmError.cpp
--- a/src/hotspot/share/utilities/vmError.cpp Wed Oct 30 12:25:22 2019 +0000
+++ b/src/hotspot/share/utilities/vmError.cpp Mon Nov 04 11:25:55 2019 +0000
@@ -128,9 +128,14 @@
static void print_bug_submit_message(outputStream *out, Thread *thread) {
if (out == NULL) return;
- out->print_raw_cr("# If you would like to submit a bug report, please visit:");
- out->print_raw ("# ");
- out->print_raw_cr(Arguments::java_vendor_url_bug());
+ const char *url = Arguments::java_vendor_url_bug();
+ if (url == NULL || *url == '\0')
+ url = JDK_Version::runtime_vendor_vm_bug_url();
+ if (url != NULL && *url != '\0') {
+ out->print_raw_cr("# If you would like to submit a bug report, please visit:");
+ out->print_raw ("# ");
+ out->print_raw_cr(url);
+ }
// If the crash is in native code, encourage user to submit a bug to the
// provider of that code.
if (thread && thread->is_Java_thread() &&
@@ -321,15 +326,19 @@
JDK_Version::runtime_name() : "";
const char* runtime_version = JDK_Version::runtime_version() != NULL ?
JDK_Version::runtime_version() : "";
+ const char* vendor_version = JDK_Version::runtime_vendor_version() != NULL ?
+ JDK_Version::runtime_vendor_version() : "";
const char* jdk_debug_level = VM_Version::printable_jdk_debug_level() != NULL ?
VM_Version::printable_jdk_debug_level() : "";
- st->print_cr("# JRE version: %s (%s) (%sbuild %s)", runtime_name, buf,
- jdk_debug_level, runtime_version);
+ st->print_cr("# JRE version: %s%s%s (%s) (%sbuild %s)", runtime_name,
+ (*vendor_version != '\0') ? " " : "", vendor_version,
+ buf, jdk_debug_level, runtime_version);
// This is the long version with some default settings added
- st->print_cr("# Java VM: %s (%s%s, %s%s%s%s%s, %s, %s)",
+ st->print_cr("# Java VM: %s%s%s (%s%s, %s%s%s%s%s, %s, %s)",
VM_Version::vm_name(),
+ (*vendor_version != '\0') ? " " : "", vendor_version,
jdk_debug_level,
VM_Version::vm_release(),
VM_Version::vm_info_string(),
diff -r 12b08b510fd0 -r 2c777f25cfff src/java.base/share/classes/java/lang/Thread.java
--- a/src/java.base/share/classes/java/lang/Thread.java Wed Oct 30 12:25:22 2019 +0000
+++ b/src/java.base/share/classes/java/lang/Thread.java Mon Nov 04 11:25:55 2019 +0000
@@ -154,6 +154,9 @@
/* Whether or not the thread is a daemon thread. */
private boolean daemon = false;
+ /* Interrupt state of the thread - read/written directly by JVM */
+ private volatile boolean interrupted;
+
/* Fields reserved for exclusive use by the JVM */
private boolean stillborn = false;
private long eetop;
@@ -971,10 +974,14 @@
*
* Interrupting a thread that is not alive need not have any effect.
*
+ * @implNote In the JDK Reference Implementation, interruption of a thread
+ * that is not alive still records that the interrupt request was made and
+ * will report it via {@link #interrupted} and {@link #isInterrupted()}.
+ *
* @throws SecurityException
* if the current thread cannot modify this thread
*
- * @revised 6.0
+ * @revised 6.0, 14
* @spec JSR-51
*/
public void interrupt() {
@@ -985,14 +992,15 @@
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
- interrupt0(); // set interrupt status
+ interrupted = true;
+ interrupt0(); // inform VM of interrupt
b.interrupt(this);
return;
}
}
}
-
- // set interrupt status
+ interrupted = true;
+ // inform VM of interrupt
interrupt0();
}
@@ -1004,45 +1012,38 @@
* interrupted again, after the first call had cleared its interrupted
* status and before the second call had examined it).
*
- *
A thread interruption ignored because a thread was not alive
- * at the time of the interrupt will be reflected by this method
- * returning false.
- *
* @return {@code true} if the current thread has been interrupted;
* {@code false} otherwise.
* @see #isInterrupted()
- * @revised 6.0
+ * @revised 6.0, 14
*/
public static boolean interrupted() {
- return currentThread().isInterrupted(true);
+ Thread t = currentThread();
+ boolean interrupted = t.interrupted;
+ // We may have been interrupted the moment after we read the field,
+ // so only clear the field if we saw that it was set and will return
+ // true; otherwise we could lose an interrupt.
+ if (interrupted) {
+ t.interrupted = false;
+ clearInterruptEvent();
+ }
+ return interrupted;
}
/**
* Tests whether this thread has been interrupted. The interrupted
* status of the thread is unaffected by this method.
*
- *
A thread interruption ignored because a thread was not alive
- * at the time of the interrupt will be reflected by this method
- * returning false.
- *
* @return {@code true} if this thread has been interrupted;
* {@code false} otherwise.
* @see #interrupted()
- * @revised 6.0
+ * @revised 6.0, 14
*/
public boolean isInterrupted() {
- return isInterrupted(false);
+ return interrupted;
}
/**
- * Tests if some Thread has been interrupted. The interrupted state
- * is reset or not based on the value of ClearInterrupted that is
- * passed.
- */
- @HotSpotIntrinsicCandidate
- private native boolean isInterrupted(boolean ClearInterrupted);
-
- /**
* Tests if this thread is alive. A thread is alive if it has
* been started and has not yet died.
*
@@ -1251,20 +1252,20 @@
}
/**
- * Counts the number of stack frames in this thread. The thread must
- * be suspended.
+ * Throws {@code UnsupportedOperationException}.
+ *
+ * @return nothing
*
- * @return the number of stack frames in this thread.
- * @throws IllegalThreadStateException if this thread is not
- * suspended.
- * @deprecated The definition of this call depends on {@link #suspend},
- * which is deprecated. Further, the results of this call
- * were never well-defined.
+ * @deprecated This method was originally designed to count the number of
+ * stack frames but the results were never well-defined and it
+ * depended on thread-suspension.
* This method is subject to removal in a future version of Java SE.
* @see StackWalker
*/
@Deprecated(since="1.2", forRemoval=true)
- public native int countStackFrames();
+ public int countStackFrames() {
+ throw new UnsupportedOperationException();
+ }
/**
* Waits at most {@code millis} milliseconds for this thread to
@@ -2080,5 +2081,6 @@
private native void suspend0();
private native void resume0();
private native void interrupt0();
+ private static native void clearInterruptEvent();
private native void setNativeName(String name);
}
diff -r 12b08b510fd0 -r 2c777f25cfff src/java.base/share/classes/java/lang/VersionProps.java.template
--- a/src/java.base/share/classes/java/lang/VersionProps.java.template Wed Oct 30 12:25:22 2019 +0000
+++ b/src/java.base/share/classes/java/lang/VersionProps.java.template Mon Nov 04 11:25:55 2019 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -42,9 +42,11 @@
private static final String java_version_date =
"@@VERSION_DATE@@";
+ // This field is read by HotSpot
private static final String java_runtime_name =
"@@RUNTIME_NAME@@";
+ // This field is read by HotSpot
private static final String java_runtime_version =
"@@VERSION_STRING@@";
@@ -69,22 +71,26 @@
private static final String CLASSFILE_MAJOR_MINOR =
"@@VERSION_CLASSFILE_MAJOR@@.@@VERSION_CLASSFILE_MINOR@@";
- private static final String VENDOR_VERSION_STRING =
- "@@VENDOR_VERSION_STRING@@";
-
- private static final String vendor_version =
- (!VENDOR_VERSION_STRING.isEmpty()
- ? " " + VENDOR_VERSION_STRING : "");
-
private static final String VENDOR =
"@@VENDOR@@";
private static final String VENDOR_URL =
"@@VENDOR_URL@@";
- private static final String VENDOR_URL_BUG =
+ // The remaining VENDOR_* fields must not be final,
+ // so that they can be redefined by jlink plugins
+
+ // This field is read by HotSpot
+ private static String VENDOR_VERSION =
+ "@@VENDOR_VERSION_STRING@@";
+
+ private static String VENDOR_URL_BUG =
"@@VENDOR_URL_BUG@@";
+ // This field is read by HotSpot
+ private static String VENDOR_URL_VM_BUG =
+ "@@VENDOR_URL_VM_BUG@@";
+
/**
* Initialize system properties using build provided values.
*
@@ -95,8 +101,8 @@
props.put("java.version.date", java_version_date);
props.put("java.runtime.version", java_runtime_version);
props.put("java.runtime.name", java_runtime_name);
- if (!VENDOR_VERSION_STRING.isEmpty())
- props.put("java.vendor.version", VENDOR_VERSION_STRING);
+ if (!VENDOR_VERSION.isEmpty())
+ props.put("java.vendor.version", VENDOR_VERSION);
props.put("java.class.version", CLASSFILE_MAJOR_MINOR);
@@ -216,6 +222,9 @@
jdk_debug_level = jdk_debug_level + " ";
}
+ String vendor_version = (VENDOR_VERSION.isEmpty()
+ ? "" : " " + VENDOR_VERSION);
+
ps.println(java_runtime_name + vendor_version
+ " (" + jdk_debug_level + "build " + java_runtime_version + ")");
diff -r 12b08b510fd0 -r 2c777f25cfff src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
--- a/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java Wed Oct 30 12:25:22 2019 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java Mon Nov 04 11:25:55 2019 +0000
@@ -29,6 +29,7 @@
import sun.invoke.util.BytecodeDescriptor;
import jdk.internal.misc.Unsafe;
import sun.security.action.GetPropertyAction;
+import sun.security.action.GetBooleanAction;
import java.io.FilePermission;
import java.io.Serializable;
@@ -87,10 +88,15 @@
// For dumping generated classes to disk, for debugging purposes
private static final ProxyClassesDumper dumper;
+ private static final boolean disableEagerInitialization;
+
static {
- final String key = "jdk.internal.lambda.dumpProxyClasses";
- String path = GetPropertyAction.privilegedGetProperty(key);
- dumper = (null == path) ? null : ProxyClassesDumper.getInstance(path);
+ final String dumpProxyClassesKey = "jdk.internal.lambda.dumpProxyClasses";
+ String dumpPath = GetPropertyAction.privilegedGetProperty(dumpProxyClassesKey);
+ dumper = (null == dumpPath) ? null : ProxyClassesDumper.getInstance(dumpPath);
+
+ final String disableEagerInitializationKey = "jdk.internal.lambda.disableEagerInitialization";
+ disableEagerInitialization = GetBooleanAction.privilegedGetProperty(disableEagerInitializationKey);
}
// See context values in AbstractValidatingLambdaMetafactory
@@ -187,7 +193,9 @@
@Override
CallSite buildCallSite() throws LambdaConversionException {
final Class> innerClass = spinInnerClass();
- if (invokedType.parameterCount() == 0) {
+ if (invokedType.parameterCount() == 0 && !disableEagerInitialization) {
+ // In the case of a non-capturing lambda, we optimize linkage by pre-computing a single instance,
+ // unless we've suppressed eager initialization
final Constructor>[] ctrs = AccessController.doPrivileged(
new PrivilegedAction<>() {
@Override
@@ -215,7 +223,9 @@
}
} else {
try {
- UNSAFE.ensureClassInitialized(innerClass);
+ if (!disableEagerInitialization) {
+ UNSAFE.ensureClassInitialized(innerClass);
+ }
return new ConstantCallSite(
MethodHandles.Lookup.IMPL_LOOKUP
.findStatic(innerClass, NAME_FACTORY, invokedType));
@@ -273,7 +283,7 @@
generateConstructor();
- if (invokedType.parameterCount() != 0) {
+ if (invokedType.parameterCount() != 0 || disableEagerInitialization) {
generateFactory();
}
diff -r 12b08b510fd0 -r 2c777f25cfff src/java.base/share/classes/java/lang/invoke/MethodHandles.java
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Wed Oct 30 12:25:22 2019 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Mon Nov 04 11:25:55 2019 +0000
@@ -203,7 +203,7 @@
* @param targetClass the target class
* @param caller the caller lookup object
* @return a lookup object for the target class, with private access
- * @throws IllegalArgumentException if {@code targetClass} is a primitive type or array class
+ * @throws IllegalArgumentException if {@code targetClass} is a primitive type or void or array class
* @throws NullPointerException if {@code targetClass} or {@code caller} is {@code null}
* @throws SecurityException if denied by the security manager
* @throws IllegalAccessException if any of the other access checks specified above fails
@@ -1385,7 +1385,7 @@
private Lookup(Class> lookupClass, Class> prevLookupClass, int allowedModes) {
assert prevLookupClass == null || ((allowedModes & MODULE) == 0
&& prevLookupClass.getModule() != lookupClass.getModule());
-
+ assert !lookupClass.isArray() && !lookupClass.isPrimitive();
this.lookupClass = lookupClass;
this.prevLookupClass = prevLookupClass;
this.allowedModes = allowedModes;
@@ -1443,6 +1443,7 @@
* @param requestedLookupClass the desired lookup class for the new lookup object
* @return a lookup object which reports the desired lookup class, or the same object
* if there is no change
+ * @throws IllegalArgumentException if {@code requestedLookupClass} is a primitive type or void or array class
* @throws NullPointerException if the argument is null
*
* @revised 9
@@ -1452,6 +1453,11 @@
*/
public Lookup in(Class> requestedLookupClass) {
Objects.requireNonNull(requestedLookupClass);
+ if (requestedLookupClass.isPrimitive())
+ throw new IllegalArgumentException(requestedLookupClass + " is a primitive class");
+ if (requestedLookupClass.isArray())
+ throw new IllegalArgumentException(requestedLookupClass + " is an array class");
+
if (allowedModes == TRUSTED) // IMPL_LOOKUP can make any lookup at all
return new Lookup(requestedLookupClass, null, FULL_POWER_MODES);
if (requestedLookupClass == this.lookupClass)
diff -r 12b08b510fd0 -r 2c777f25cfff src/java.base/share/classes/java/net/DatagramSocket.java
--- a/src/java.base/share/classes/java/net/DatagramSocket.java Wed Oct 30 12:25:22 2019 +0000
+++ b/src/java.base/share/classes/java/net/DatagramSocket.java Mon Nov 04 11:25:55 2019 +0000
@@ -606,7 +606,6 @@
* @see #bind(SocketAddress)
* @since 1.4
*/
-
public SocketAddress getLocalSocketAddress() {
if (isClosed())
return null;
@@ -853,7 +852,7 @@
public InetAddress getLocalAddress() {
if (isClosed())
return null;
- InetAddress in = null;
+ InetAddress in;
try {
in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
if (in.isAnyLocalAddress()) {
@@ -874,8 +873,8 @@
* is bound.
*
* @return the port number on the local host to which this socket is bound,
- {@code -1} if the socket is closed, or
- {@code 0} if it is not bound yet.
+ * {@code -1} if the socket is closed, or
+ * {@code 0} if it is not bound yet.
*/
public int getLocalPort() {
if (isClosed())
@@ -887,15 +886,16 @@
}
}
- /** Enable/disable SO_TIMEOUT with the specified timeout, in
- * milliseconds. With this option set to a positive timeout value,
- * a call to receive() for this DatagramSocket
- * will block for only this amount of time. If the timeout expires,
- * a java.net.SocketTimeoutException is raised, though the
- * DatagramSocket is still valid. A timeout of zero is interpreted
- * as an infinite timeout.
- * The option must be enabled prior to entering the blocking
- * operation to have effect.
+ /**
+ * Enable/disable SO_TIMEOUT with the specified timeout, in
+ * milliseconds. With this option set to a positive timeout value,
+ * a call to receive() for this DatagramSocket
+ * will block for only this amount of time. If the timeout expires,
+ * a java.net.SocketTimeoutException is raised, though the
+ * DatagramSocket is still valid. A timeout of zero is interpreted
+ * as an infinite timeout.
+ * The option must be enabled prior to entering the blocking
+ * operation to have effect.
*
* @param timeout the specified timeout in milliseconds.
* @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
@@ -963,8 +963,7 @@
* negative.
* @see #getSendBufferSize()
*/
- public synchronized void setSendBufferSize(int size)
- throws SocketException{
+ public synchronized void setSendBufferSize(int size) throws SocketException {
if (!(size > 0)) {
throw new IllegalArgumentException("negative send size");
}
@@ -1021,8 +1020,7 @@
* negative.
* @see #getReceiveBufferSize()
*/
- public synchronized void setReceiveBufferSize(int size)
- throws SocketException{
+ public synchronized void setReceiveBufferSize(int size) throws SocketException {
if (size <= 0) {
throw new IllegalArgumentException("invalid receive size");
}
@@ -1039,8 +1037,7 @@
* @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
* @see #setReceiveBufferSize(int)
*/
- public synchronized int getReceiveBufferSize()
- throws SocketException{
+ public synchronized int getReceiveBufferSize() throws SocketException {
if (isClosed())
throw new SocketException("Socket is closed");
int result = 0;
diff -r 12b08b510fd0 -r 2c777f25cfff src/java.base/share/classes/java/net/HttpURLConnection.java
--- a/src/java.base/share/classes/java/net/HttpURLConnection.java Wed Oct 30 12:25:22 2019 +0000
+++ b/src/java.base/share/classes/java/net/HttpURLConnection.java Mon Nov 04 11:25:55 2019 +0000
@@ -618,8 +618,13 @@
/**
* Indicates if the connection is going through a proxy.
- * @return a boolean indicating if the connection is
- * using a proxy.
+ *
+ * This method returns {@code true} if the connection is known
+ * to be going or has gone through proxies, and returns {@code false}
+ * if the connection will never go through a proxy or if
+ * the use of a proxy cannot be determined.
+ *
+ * @return a boolean indicating if the connection is using a proxy.
*/
public abstract boolean usingProxy();
diff -r 12b08b510fd0 -r 2c777f25cfff src/java.base/share/classes/java/nio/file/FileStore.java
--- a/src/java.base/share/classes/java/nio/file/FileStore.java Wed Oct 30 12:25:22 2019 +0000
+++ b/src/java.base/share/classes/java/nio/file/FileStore.java Mon Nov 04 11:25:55 2019 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -84,7 +84,9 @@
public abstract boolean isReadOnly();
/**
- * Returns the size, in bytes, of the file store.
+ * Returns the size, in bytes, of the file store. If the total number of
+ * bytes in the file store is greater than {@link Long#MAX_VALUE}, then
+ * {@code Long.MAX_VALUE} will be returned.
*
* @return the size of the file store, in bytes
*
@@ -95,7 +97,8 @@
/**
* Returns the number of bytes available to this Java virtual machine on the
- * file store.
+ * file store. If the number of bytes available is greater than
+ * {@link Long#MAX_VALUE}, then {@code Long.MAX_VALUE} will be returned.
*
*
The returned number of available bytes is a hint, but not a
* guarantee, that it is possible to use most or any of these bytes. The
@@ -112,14 +115,33 @@
public abstract long getUsableSpace() throws IOException;
/**
+ * Returns the number of unallocated bytes in the file store.
+ * If the number of unallocated bytes is greater than
+ * {@link Long#MAX_VALUE}, then {@code Long.MAX_VALUE} will be returned.
+ *
+ *
The returned number of unallocated bytes is a hint, but not a
+ * guarantee, that it is possible to use most or any of these bytes. The
+ * number of unallocated bytes is most likely to be accurate immediately
+ * after the space attributes are obtained. It is likely to be
+ * made inaccurate by any external I/O operations including those made on
+ * the system outside of this virtual machine.
+ *
+ * @return the number of unallocated bytes
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public abstract long getUnallocatedSpace() throws IOException;
+
+ /**
* Returns the number of bytes per block in this file store.
*
*
File storage is typically organized into discrete sequences of bytes
* called blocks. A block is the smallest storage unit of a file store.
* Every read and write operation is performed on a multiple of blocks.
*
- * @implSpec The implementation in this class throws an
- * {@code UnsupportedOperationException}.
+ * @implSpec The implementation in this class throws
+ * {@code UnsupportedOperationException}.
*
* @return a positive value representing the block size of this file store,
* in bytes
@@ -137,23 +159,6 @@
}
/**
- * Returns the number of unallocated bytes in the file store.
- *
- *
The returned number of unallocated bytes is a hint, but not a
- * guarantee, that it is possible to use most or any of these bytes. The
- * number of unallocated bytes is most likely to be accurate immediately
- * after the space attributes are obtained. It is likely to be
- * made inaccurate by any external I/O operations including those made on
- * the system outside of this virtual machine.
- *
- * @return the number of unallocated bytes
- *
- * @throws IOException
- * if an I/O error occurs
- */
- public abstract long getUnallocatedSpace() throws IOException;
-
- /**
* Tells whether or not this file store supports the file attributes
* identified by the given file attribute view.
*
diff -r 12b08b510fd0 -r 2c777f25cfff src/java.base/share/classes/java/util/concurrent/CompletableFuture.java
--- a/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java Wed Oct 30 12:25:22 2019 +0000
+++ b/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java Mon Nov 04 11:25:55 2019 +0000
@@ -623,8 +623,8 @@
final CompletableFuture tryFire(int mode) {
CompletableFuture d; CompletableFuture a;
Object r; Throwable x; Function super T,? extends V> f;
- if ((d = dep) == null || (f = fn) == null
- || (a = src) == null || (r = a.result) == null)
+ if ((a = src) == null || (r = a.result) == null
+ || (d = dep) == null || (f = fn) == null)
return null;
tryComplete: if (d.result == null) {
if (r instanceof AltResult) {
@@ -645,7 +645,7 @@
d.completeThrowable(ex);
}
}
- dep = null; src = null; fn = null;
+ src = null; dep = null; fn = null;
return d.postFire(a, mode);
}
}
@@ -695,8 +695,8 @@
final CompletableFuture tryFire(int mode) {
CompletableFuture d; CompletableFuture a;
Object r; Throwable x; Consumer super T> f;
- if ((d = dep) == null || (f = fn) == null
- || (a = src) == null || (r = a.result) == null)
+ if ((a = src) == null || (r = a.result) == null
+ || (d = dep) == null || (f = fn) == null)
return null;
tryComplete: if (d.result == null) {
if (r instanceof AltResult) {
@@ -718,7 +718,7 @@
d.completeThrowable(ex);
}
}
- dep = null; src = null; fn = null;
+ src = null; dep = null; fn = null;
return d.postFire(a, mode);
}
}
@@ -769,8 +769,8 @@
final CompletableFuture tryFire(int mode) {
CompletableFuture d; CompletableFuture a;
Object r; Throwable x; Runnable f;
- if ((d = dep) == null || (f = fn) == null
- || (a = src) == null || (r = a.result) == null)
+ if ((a = src) == null || (r = a.result) == null
+ || (d = dep) == null || (f = fn) == null)
return null;
if (d.result == null) {
if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
@@ -787,7 +787,7 @@
d.completeThrowable(ex);
}
}
- dep = null; src = null; fn = null;
+ src = null; dep = null; fn = null;
return d.postFire(a, mode);
}
}
@@ -832,11 +832,11 @@
final CompletableFuture tryFire(int mode) {
CompletableFuture d; CompletableFuture a;
Object r; BiConsumer super T, ? super Throwable> f;
- if ((d = dep) == null || (f = fn) == null
- || (a = src) == null || (r = a.result) == null
+ if ((a = src) == null || (r = a.result) == null
+ || (d = dep) == null || (f = fn) == null
|| !d.uniWhenComplete(r, f, mode > 0 ? null : this))
return null;
- dep = null; src = null; fn = null;
+ src = null; dep = null; fn = null;
return d.postFire(a, mode);
}
}
@@ -902,11 +902,11 @@
final CompletableFuture tryFire(int mode) {
CompletableFuture