Sat, 24 Oct 2020 16:43:47 +0800
Merge
1.1 --- a/.hgtags Sat Oct 24 16:18:50 2020 +0800 1.2 +++ b/.hgtags Sat Oct 24 16:43:47 2020 +0800 1.3 @@ -1338,8 +1338,23 @@ 1.4 545fe7caa2fb4a6dc4b4f9bba9556e30886ca1f1 jdk8u262-b03 1.5 3a3803a0c789c4d09fd53e54760e7bb7d704ca6e jdk8u262-b04 1.6 f7691a80458c365b5dd754b1e117818144ed30f1 jdk8u262-b05 1.7 +f7691a80458c365b5dd754b1e117818144ed30f1 jdk8u272-b00 1.8 de6565b66f9458fb97eb66483e48f159b3f39d36 jdk8u262-b06 1.9 d20a5f399218f58f82f4f4503d24957ce7e48e60 jdk8u262-b07 1.10 d2c2cd90513e48822648ff16016aa76577eb7ab1 jdk8u262-b08 1.11 cf6e3496e19a2957f7d8b28bd0a033cefbf6509f jdk8u262-b09 1.12 +1c6e1f187fdc571e5fb7eaf9ed0180ce6fe0a4a4 jdk8u262-b10 1.13 +1c6e1f187fdc571e5fb7eaf9ed0180ce6fe0a4a4 jdk8u262-ga 1.14 0672fc1cf8113b459db1d6d255c2fb17c2938723 mips-jdk8u262-b10 1.15 +1c6e1f187fdc571e5fb7eaf9ed0180ce6fe0a4a4 jdk8u265-b00 1.16 +3bd5ac4488a39330ad5452b89ed98afac584ce59 jdk8u265-b01 1.17 +3bd5ac4488a39330ad5452b89ed98afac584ce59 jdk8u265-ga 1.18 +85c9d74850ed3a6c99dd97c85d25ffb29afc0a28 jdk8u272-b01 1.19 +414c1dcfc3f3620b73cc7faf23f9a3ffde83b240 jdk8u272-b02 1.20 +e649f213636810823e761473ac871ce55a5235f7 jdk8u272-b03 1.21 +cbabffce5685f9a18bfd05bd1fb18c4c73be98cf jdk8u272-b04 1.22 +1b2d99958c293b7ab324c5786664f82c8e9c4e50 jdk8u272-b05 1.23 +4b0aa85a95653f44cc45f2ec0571153017ebbf03 jdk8u272-b06 1.24 +4689eaf1a5c9c5e284d466631420761f4bd4ecae jdk8u272-b07 1.25 +a0eb08e2db5a40956a9c2d6b7dea76a894559033 jdk8u272-b08 1.26 +176a7e5cc0609cface769e5e8a31b00700d223ba jdk8u272-b09
2.1 --- a/THIRD_PARTY_README Sat Oct 24 16:18:50 2020 +0800 2.2 +++ b/THIRD_PARTY_README Sat Oct 24 16:43:47 2020 +0800 2.3 @@ -2240,7 +2240,7 @@ 2.4 2.5 ------------------------------------------------------------------------------- 2.6 2.7 -%% This notice is provided with respect to PC/SC Lite v1.8.24, 2.8 +%% This notice is provided with respect to PC/SC Lite v1.8.26, 2.9 which may be included with JRE 8, JDK 8, and OpenJDK 8 on Linux and Solaris. 2.10 2.11 --- begin of LICENSE --- 2.12 @@ -3028,8 +3028,7 @@ 2.13 Apache Commons Math 3.2 2.14 Apache Derby 10.11.1.2 2.15 Apache Jakarta BCEL 5.1 2.16 - Apache Jakarta Regexp 1.4 2.17 - Apache Santuario XML Security for Java 1.5.4 2.18 + Apache Santuario XML Security for Java 2.1.1 2.19 Apache Xalan-Java 2.7.2 2.20 Apache Xerces Java 2.10.0 2.21 Apache XML Resolver 1.1 2.22 @@ -3243,3 +3242,41 @@ 2.23 2.24 ------------------------------------------------------------------------------- 2.25 2.26 +%% This notice is provided with respect to OASIS PKCS #11 Cryptographic Token 2.27 +Interface v2.40, which may be included with JRE 8, JDK 8, and OpenJDK 8. 2.28 + 2.29 +--- begin of LICENSE --- 2.30 + 2.31 +Copyright (c) OASIS Open 2016. All Rights Reserved. 2.32 + 2.33 +All capitalized terms in the following text have the meanings assigned to them 2.34 +in the OASIS Intellectual Property Rights Policy (the "OASIS IPR Policy"). The 2.35 +full Policy may be found at the OASIS website: 2.36 +[http://www.oasis-open.org/policies-guidelines/ipr] 2.37 + 2.38 +This document and translations of it may be copied and furnished to others, and 2.39 +derivative works that comment on or otherwise explain it or assist in its 2.40 +implementation may be prepared, copied, published, and distributed, in whole or 2.41 +in part, without restriction of any kind, provided that the above copyright 2.42 +notice and this section are included on all such copies and derivative works. 2.43 +However, this document itself may not be modified in any way, including by 2.44 +removing the copyright notice or references to OASIS, except as needed for the 2.45 +purpose of developing any document or deliverable produced by an OASIS 2.46 +Technical Committee (in which case the rules applicable to copyrights, as set 2.47 +forth in the OASIS IPR Policy, must be followed) or as required to translate it 2.48 +into languages other than English. 2.49 + 2.50 +The limited permissions granted above are perpetual and will not be revoked by 2.51 +OASIS or its successors or assigns. 2.52 + 2.53 +This document and the information contained herein is provided on an "AS IS" 2.54 +basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT 2.55 +LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT 2.56 +INFRINGE ANY OWNERSHIP RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR 2.57 +FITNESS FOR A PARTICULAR PURPOSE. OASIS AND ITS MEMBERS WILL NOT BE LIABLE FOR 2.58 +ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE 2.59 +OF THIS DOCUMENT OR ANY PART THEREOF. 2.60 + 2.61 +--- end of LICENSE --- 2.62 + 2.63 +-------------------------------------------------------------------------------
3.1 --- a/make/aix/makefiles/buildtree.make Sat Oct 24 16:18:50 2020 +0800 3.2 +++ b/make/aix/makefiles/buildtree.make Sat Oct 24 16:43:47 2020 +0800 3.3 @@ -111,7 +111,7 @@ 3.4 endif 3.5 endif 3.6 3.7 -ifeq ($(ENABLE_JFR),false) 3.8 +ifneq ($(ENABLE_JFR),true) 3.9 ALWAYS_EXCLUDE_DIRS += -o -name jfr 3.10 endif 3.11
4.1 --- a/make/aix/makefiles/vm.make Sat Oct 24 16:18:50 2020 +0800 4.2 +++ b/make/aix/makefiles/vm.make Sat Oct 24 16:43:47 2020 +0800 4.3 @@ -147,7 +147,7 @@ 4.4 LIBJVM_DEBUGINFO = lib$(JVM).debuginfo 4.5 LIBJVM_DIZ = lib$(JVM).diz 4.6 4.7 -ifeq ($(ENABLE_JFR),false) 4.8 +ifneq ($(ENABLE_JFR),true) 4.9 EXCLUDE_JFR_PATHS:= -o -name jfr -prune 4.10 endif 4.11
5.1 --- a/make/bsd/makefiles/buildtree.make Sat Oct 24 16:18:50 2020 +0800 5.2 +++ b/make/bsd/makefiles/buildtree.make Sat Oct 24 16:43:47 2020 +0800 5.3 @@ -113,7 +113,7 @@ 5.4 endif 5.5 endif 5.6 5.7 -ifeq ($(ENABLE_JFR),false) 5.8 +ifneq ($(ENABLE_JFR),true) 5.9 ALWAYS_EXCLUDE_DIRS += -o -name jfr 5.10 endif 5.11
6.1 --- a/make/bsd/makefiles/vm.make Sat Oct 24 16:18:50 2020 +0800 6.2 +++ b/make/bsd/makefiles/vm.make Sat Oct 24 16:43:47 2020 +0800 6.3 @@ -165,7 +165,7 @@ 6.4 LIBJVM_DIZ = lib$(JVM).diz 6.5 endif 6.6 6.7 -ifeq ($(ENABLE_JFR),false) 6.8 +ifneq ($(ENABLE_JFR),true) 6.9 EXCLUDE_JFR_PATHS:= -o -name jfr -prune 6.10 endif 6.11 SPECIAL_PATHS:=adlc c1 gc_implementation opto shark libadt
7.1 --- a/make/excludeSrc.make Sat Oct 24 16:18:50 2020 +0800 7.2 +++ b/make/excludeSrc.make Sat Oct 24 16:43:47 2020 +0800 7.3 @@ -95,6 +95,7 @@ 7.4 gc_shared_keep := \ 7.5 adaptiveSizePolicy.cpp \ 7.6 ageTable.cpp \ 7.7 + ageTableTracer.cpp \ 7.8 collectorCounters.cpp \ 7.9 cSpaceCounters.cpp \ 7.10 gcId.cpp \
8.1 --- a/make/linux/makefiles/buildtree.make Sat Oct 24 16:18:50 2020 +0800 8.2 +++ b/make/linux/makefiles/buildtree.make Sat Oct 24 16:43:47 2020 +0800 8.3 @@ -112,7 +112,7 @@ 8.4 endif 8.5 endif 8.6 8.7 -ifeq ($(ENABLE_JFR),false) 8.8 +ifneq ($(ENABLE_JFR),true) 8.9 ALWAYS_EXCLUDE_DIRS += -o -name jfr 8.10 endif 8.11
9.1 --- a/make/linux/makefiles/mapfile-vers-debug Sat Oct 24 16:18:50 2020 +0800 9.2 +++ b/make/linux/makefiles/mapfile-vers-debug Sat Oct 24 16:43:47 2020 +0800 9.3 @@ -190,6 +190,7 @@ 9.4 JVM_IsSilentCompiler; 9.5 JVM_IsSupportedJNIVersion; 9.6 JVM_IsThreadAlive; 9.7 + JVM_IsUseContainerSupport; 9.8 JVM_IsVMGeneratedMethodIx; 9.9 JVM_LatestUserDefinedLoader; 9.10 JVM_Listen;
10.1 --- a/make/linux/makefiles/mapfile-vers-product Sat Oct 24 16:18:50 2020 +0800 10.2 +++ b/make/linux/makefiles/mapfile-vers-product Sat Oct 24 16:43:47 2020 +0800 10.3 @@ -185,6 +185,7 @@ 10.4 JVM_IsInterface; 10.5 JVM_IsInterrupted; 10.6 JVM_IsNaN; 10.7 + JVM_IsUseContainerSupport; 10.8 JVM_IsPrimitiveClass; 10.9 JVM_IsSameClassPackage; 10.10 JVM_IsSilentCompiler;
11.1 --- a/make/linux/makefiles/vm.make Sat Oct 24 16:18:50 2020 +0800 11.2 +++ b/make/linux/makefiles/vm.make Sat Oct 24 16:43:47 2020 +0800 11.3 @@ -169,7 +169,7 @@ 11.4 LIBJVM_DEBUGINFO = lib$(JVM).debuginfo 11.5 LIBJVM_DIZ = lib$(JVM).diz 11.6 11.7 -ifeq ($(ENABLE_JFR),false) 11.8 +ifneq ($(ENABLE_JFR),true) 11.9 EXCLUDE_JFR_PATHS:= -o -name jfr -prune 11.10 endif 11.11 SPECIAL_PATHS:=adlc c1 gc_implementation opto shark libadt
12.1 --- a/make/solaris/makefiles/buildtree.make Sat Oct 24 16:18:50 2020 +0800 12.2 +++ b/make/solaris/makefiles/buildtree.make Sat Oct 24 16:43:47 2020 +0800 12.3 @@ -103,7 +103,7 @@ 12.4 endif 12.5 endif 12.6 12.7 -ifeq ($(ENABLE_JFR),false) 12.8 +ifneq ($(ENABLE_JFR),true) 12.9 ALWAYS_EXCLUDE_DIRS += -o -name jfr 12.10 endif 12.11
13.1 --- a/make/solaris/makefiles/vm.make Sat Oct 24 16:18:50 2020 +0800 13.2 +++ b/make/solaris/makefiles/vm.make Sat Oct 24 16:43:47 2020 +0800 13.3 @@ -164,7 +164,7 @@ 13.4 13.5 LIBJVM_DEBUGINFO = lib$(JVM).debuginfo 13.6 LIBJVM_DIZ = lib$(JVM).diz 13.7 -ifeq ($(ENABLE_JFR),false) 13.8 +ifneq ($(ENABLE_JFR),true) 13.9 EXCLUDE_JFR_PATHS:= -o -name jfr -prune 13.10 endif 13.11 SPECIAL_PATHS:=adlc c1 dist gc_implementation opto shark libadt
14.1 --- a/src/share/vm/c1/c1_GraphBuilder.cpp Sat Oct 24 16:18:50 2020 +0800 14.2 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Sat Oct 24 16:43:47 2020 +0800 14.3 @@ -1705,6 +1705,23 @@ 14.4 Value replacement = !needs_patching ? _memory->load(load) : load; 14.5 if (replacement != load) { 14.6 assert(replacement->is_linked() || !replacement->can_be_linked(), "should already by linked"); 14.7 + // Writing an (integer) value to a boolean, byte, char or short field includes an implicit narrowing 14.8 + // conversion. Emit an explicit conversion here to get the correct field value after the write. 14.9 + BasicType bt = field->type()->basic_type(); 14.10 + switch (bt) { 14.11 + case T_BOOLEAN: 14.12 + case T_BYTE: 14.13 + replacement = append(new Convert(Bytecodes::_i2b, replacement, as_ValueType(bt))); 14.14 + break; 14.15 + case T_CHAR: 14.16 + replacement = append(new Convert(Bytecodes::_i2c, replacement, as_ValueType(bt))); 14.17 + break; 14.18 + case T_SHORT: 14.19 + replacement = append(new Convert(Bytecodes::_i2s, replacement, as_ValueType(bt))); 14.20 + break; 14.21 + default: 14.22 + break; 14.23 + } 14.24 push(type, replacement); 14.25 } else { 14.26 push(type, append(load)); 14.27 @@ -2376,7 +2393,7 @@ 14.28 if (!has_handler() && (!instruction->needs_exception_state() || instruction->exception_state() != NULL)) { 14.29 assert(instruction->exception_state() == NULL 14.30 || instruction->exception_state()->kind() == ValueStack::EmptyExceptionState 14.31 - || (instruction->exception_state()->kind() == ValueStack::ExceptionState && _compilation->env()->jvmti_can_access_local_variables()), 14.32 + || (instruction->exception_state()->kind() == ValueStack::ExceptionState && _compilation->env()->should_retain_local_variables()), 14.33 "exception_state should be of exception kind"); 14.34 return new XHandlers(); 14.35 } 14.36 @@ -2467,7 +2484,7 @@ 14.37 // This scope and all callees do not handle exceptions, so the local 14.38 // variables of this scope are not needed. However, the scope itself is 14.39 // required for a correct exception stack trace -> clear out the locals. 14.40 - if (_compilation->env()->jvmti_can_access_local_variables()) { 14.41 + if (_compilation->env()->should_retain_local_variables()) { 14.42 cur_state = cur_state->copy(ValueStack::ExceptionState, cur_state->bci()); 14.43 } else { 14.44 cur_state = cur_state->copy(ValueStack::EmptyExceptionState, cur_state->bci()); 14.45 @@ -3353,7 +3370,7 @@ 14.46 ValueStack* GraphBuilder::copy_state_for_exception_with_bci(int bci) { 14.47 ValueStack* s = copy_state_exhandling_with_bci(bci); 14.48 if (s == NULL) { 14.49 - if (_compilation->env()->jvmti_can_access_local_variables()) { 14.50 + if (_compilation->env()->should_retain_local_variables()) { 14.51 s = state()->copy(ValueStack::ExceptionState, bci); 14.52 } else { 14.53 s = state()->copy(ValueStack::EmptyExceptionState, bci);
15.1 --- a/src/share/vm/c1/c1_Instruction.cpp Sat Oct 24 16:18:50 2020 +0800 15.2 +++ b/src/share/vm/c1/c1_Instruction.cpp Sat Oct 24 16:43:47 2020 +0800 15.3 @@ -76,7 +76,7 @@ 15.4 15.5 void Instruction::update_exception_state(ValueStack* state) { 15.6 if (state != NULL && (state->kind() == ValueStack::EmptyExceptionState || state->kind() == ValueStack::ExceptionState)) { 15.7 - assert(state->kind() == ValueStack::EmptyExceptionState || Compilation::current()->env()->jvmti_can_access_local_variables(), "unexpected state kind"); 15.8 + assert(state->kind() == ValueStack::EmptyExceptionState || Compilation::current()->env()->should_retain_local_variables(), "unexpected state kind"); 15.9 _exception_state = state; 15.10 } else { 15.11 _exception_state = NULL;
16.1 --- a/src/share/vm/c1/c1_ValueStack.cpp Sat Oct 24 16:18:50 2020 +0800 16.2 +++ b/src/share/vm/c1/c1_ValueStack.cpp Sat Oct 24 16:43:47 2020 +0800 16.3 @@ -52,7 +52,7 @@ 16.4 , _stack() 16.5 , _locks(copy_from->locks_size()) 16.6 { 16.7 - assert(kind != EmptyExceptionState || !Compilation::current()->env()->jvmti_can_access_local_variables(), "need locals"); 16.8 + assert(kind != EmptyExceptionState || !Compilation::current()->env()->should_retain_local_variables(), "need locals"); 16.9 if (kind != EmptyExceptionState) { 16.10 // only allocate space if we need to copy the locals-array 16.11 _locals = Values(copy_from->locals_size());
17.1 --- a/src/share/vm/c1/c1_ValueStack.hpp Sat Oct 24 16:18:50 2020 +0800 17.2 +++ b/src/share/vm/c1/c1_ValueStack.hpp Sat Oct 24 16:43:47 2020 +0800 17.3 @@ -75,7 +75,7 @@ 17.4 17.5 void set_caller_state(ValueStack* s) { 17.6 assert(kind() == EmptyExceptionState || 17.7 - (Compilation::current()->env()->jvmti_can_access_local_variables() && kind() == ExceptionState), 17.8 + (Compilation::current()->env()->should_retain_local_variables() && kind() == ExceptionState), 17.9 "only EmptyExceptionStates can be modified"); 17.10 _caller_state = s; 17.11 }
18.1 --- a/src/share/vm/ci/ciEnv.cpp Sat Oct 24 16:18:50 2020 +0800 18.2 +++ b/src/share/vm/ci/ciEnv.cpp Sat Oct 24 16:43:47 2020 +0800 18.3 @@ -139,6 +139,11 @@ 18.4 _ClassCastException_instance = NULL; 18.5 _the_null_string = NULL; 18.6 _the_min_jint_string = NULL; 18.7 + 18.8 + _jvmti_can_hotswap_or_post_breakpoint = false; 18.9 + _jvmti_can_access_local_variables = false; 18.10 + _jvmti_can_post_on_exceptions = false; 18.11 + _jvmti_can_pop_frame = false; 18.12 } 18.13 18.14 ciEnv::ciEnv(Arena* arena) : _ciEnv_arena(mtCompiler) { 18.15 @@ -189,6 +194,11 @@ 18.16 _ClassCastException_instance = NULL; 18.17 _the_null_string = NULL; 18.18 _the_min_jint_string = NULL; 18.19 + 18.20 + _jvmti_can_hotswap_or_post_breakpoint = false; 18.21 + _jvmti_can_access_local_variables = false; 18.22 + _jvmti_can_post_on_exceptions = false; 18.23 + _jvmti_can_pop_frame = false; 18.24 } 18.25 18.26 ciEnv::~ciEnv() { 18.27 @@ -208,6 +218,31 @@ 18.28 _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint(); 18.29 _jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables(); 18.30 _jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions(); 18.31 + _jvmti_can_pop_frame = JvmtiExport::can_pop_frame(); 18.32 +} 18.33 + 18.34 +bool ciEnv::should_retain_local_variables() const { 18.35 + return _jvmti_can_access_local_variables || _jvmti_can_pop_frame; 18.36 +} 18.37 + 18.38 +bool ciEnv::jvmti_state_changed() const { 18.39 + if (!_jvmti_can_access_local_variables && 18.40 + JvmtiExport::can_access_local_variables()) { 18.41 + return true; 18.42 + } 18.43 + if (!_jvmti_can_hotswap_or_post_breakpoint && 18.44 + JvmtiExport::can_hotswap_or_post_breakpoint()) { 18.45 + return true; 18.46 + } 18.47 + if (!_jvmti_can_post_on_exceptions && 18.48 + JvmtiExport::can_post_on_exceptions()) { 18.49 + return true; 18.50 + } 18.51 + if (!_jvmti_can_pop_frame && 18.52 + JvmtiExport::can_pop_frame()) { 18.53 + return true; 18.54 + } 18.55 + return false; 18.56 } 18.57 18.58 // ------------------------------------------------------------------ 18.59 @@ -953,13 +988,7 @@ 18.60 No_Safepoint_Verifier nsv; 18.61 18.62 // Change in Jvmti state may invalidate compilation. 18.63 - if (!failing() && 18.64 - ( (!jvmti_can_hotswap_or_post_breakpoint() && 18.65 - JvmtiExport::can_hotswap_or_post_breakpoint()) || 18.66 - (!jvmti_can_access_local_variables() && 18.67 - JvmtiExport::can_access_local_variables()) || 18.68 - (!jvmti_can_post_on_exceptions() && 18.69 - JvmtiExport::can_post_on_exceptions()) )) { 18.70 + if (!failing() && jvmti_state_changed()) { 18.71 record_failure("Jvmti state change invalidated dependencies"); 18.72 } 18.73
19.1 --- a/src/share/vm/ci/ciEnv.hpp Sat Oct 24 16:18:50 2020 +0800 19.2 +++ b/src/share/vm/ci/ciEnv.hpp Sat Oct 24 16:43:47 2020 +0800 19.3 @@ -69,6 +69,7 @@ 19.4 bool _jvmti_can_hotswap_or_post_breakpoint; 19.5 bool _jvmti_can_access_local_variables; 19.6 bool _jvmti_can_post_on_exceptions; 19.7 + bool _jvmti_can_pop_frame; 19.8 19.9 // Cache DTrace flags 19.10 bool _dtrace_extended_probes; 19.11 @@ -336,8 +337,9 @@ 19.12 19.13 // Cache Jvmti state 19.14 void cache_jvmti_state(); 19.15 + bool jvmti_state_changed() const; 19.16 + bool should_retain_local_variables() const; 19.17 bool jvmti_can_hotswap_or_post_breakpoint() const { return _jvmti_can_hotswap_or_post_breakpoint; } 19.18 - bool jvmti_can_access_local_variables() const { return _jvmti_can_access_local_variables; } 19.19 bool jvmti_can_post_on_exceptions() const { return _jvmti_can_post_on_exceptions; } 19.20 19.21 // Cache DTrace flags
20.1 --- a/src/share/vm/ci/ciMethod.cpp Sat Oct 24 16:18:50 2020 +0800 20.2 +++ b/src/share/vm/ci/ciMethod.cpp Sat Oct 24 16:43:47 2020 +0800 20.3 @@ -415,7 +415,7 @@ 20.4 // information. 20.5 MethodLivenessResult ciMethod::liveness_at_bci(int bci) { 20.6 MethodLivenessResult result = raw_liveness_at_bci(bci); 20.7 - if (CURRENT_ENV->jvmti_can_access_local_variables() || DeoptimizeALot || CompileTheWorld) { 20.8 + if (CURRENT_ENV->should_retain_local_variables() || DeoptimizeALot || CompileTheWorld) { 20.9 // Keep all locals live for the user's edification and amusement. 20.10 result.at_put_range(0, result.size(), true); 20.11 }
21.1 --- a/src/share/vm/classfile/altHashing.cpp Sat Oct 24 16:18:50 2020 +0800 21.2 +++ b/src/share/vm/classfile/altHashing.cpp Sat Oct 24 16:43:47 2020 +0800 21.3 @@ -1,5 +1,5 @@ 21.4 /* 21.5 - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. 21.6 + * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. 21.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 21.8 * 21.9 * This code is free software; you can redistribute it and/or modify it 21.10 @@ -22,12 +22,29 @@ 21.11 * 21.12 */ 21.13 21.14 +/* 21.15 + * halfsiphash code adapted from reference implementation 21.16 + * (https://github.com/veorq/SipHash/blob/master/halfsiphash.c) 21.17 + * which is distributed with the following copyright: 21.18 + * 21.19 + * SipHash reference C implementation 21.20 + * 21.21 + * Copyright (c) 2016 Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com> 21.22 + * 21.23 + * To the extent possible under law, the author(s) have dedicated all copyright 21.24 + * and related and neighboring rights to this software to the public domain 21.25 + * worldwide. This software is distributed without any warranty. 21.26 + * 21.27 + * You should have received a copy of the CC0 Public Domain Dedication along 21.28 + * with this software. If not, see 21.29 + * <http://creativecommons.org/publicdomain/zero/1.0/>. 21.30 + */ 21.31 + 21.32 #include "precompiled.hpp" 21.33 #include "classfile/altHashing.hpp" 21.34 -#include "classfile/symbolTable.hpp" 21.35 #include "classfile/systemDictionary.hpp" 21.36 #include "oops/markOop.hpp" 21.37 -#include "runtime/thread.hpp" 21.38 +#include "runtime/os.hpp" 21.39 21.40 // Get the hash code of the classes mirror if it exists, otherwise just 21.41 // return a random number, which is one of the possible hash code used for 21.42 @@ -39,266 +56,292 @@ 21.43 } 21.44 21.45 // Seed value used for each alternative hash calculated. 21.46 -juint AltHashing::compute_seed() { 21.47 - jlong nanos = os::javaTimeNanos(); 21.48 - jlong now = os::javaTimeMillis(); 21.49 - int SEED_MATERIAL[8] = { 21.50 - (int) object_hash(SystemDictionary::String_klass()), 21.51 - (int) object_hash(SystemDictionary::System_klass()), 21.52 - (int) os::random(), // current thread isn't a java thread 21.53 - (int) (((julong)nanos) >> 32), 21.54 - (int) nanos, 21.55 - (int) (((julong)now) >> 32), 21.56 - (int) now, 21.57 - (int) (os::javaTimeNanos() >> 2) 21.58 +uint64_t AltHashing::compute_seed() { 21.59 + uint64_t nanos = os::javaTimeNanos(); 21.60 + uint64_t now = os::javaTimeMillis(); 21.61 + uint32_t SEED_MATERIAL[8] = { 21.62 + (uint32_t) object_hash(SystemDictionary::String_klass()), 21.63 + (uint32_t) object_hash(SystemDictionary::System_klass()), 21.64 + (uint32_t) os::random(), // current thread isn't a java thread 21.65 + (uint32_t) (((uint64_t)nanos) >> 32), 21.66 + (uint32_t) nanos, 21.67 + (uint32_t) (((uint64_t)now) >> 32), 21.68 + (uint32_t) now, 21.69 + (uint32_t) (os::javaTimeNanos() >> 2) 21.70 }; 21.71 21.72 - return murmur3_32(SEED_MATERIAL, 8); 21.73 + return halfsiphash_64(SEED_MATERIAL, 8); 21.74 } 21.75 21.76 +// utility function copied from java/lang/Integer 21.77 +static uint32_t Integer_rotateLeft(uint32_t i, int distance) { 21.78 + return (i << distance) | (i >> (32 - distance)); 21.79 +} 21.80 21.81 -// Murmur3 hashing for Symbol 21.82 -juint AltHashing::murmur3_32(juint seed, const jbyte* data, int len) { 21.83 - juint h1 = seed; 21.84 +static void halfsiphash_rounds(uint32_t v[4], int rounds) { 21.85 + while (rounds-- > 0) { 21.86 + v[0] += v[1]; 21.87 + v[1] = Integer_rotateLeft(v[1], 5); 21.88 + v[1] ^= v[0]; 21.89 + v[0] = Integer_rotateLeft(v[0], 16); 21.90 + v[2] += v[3]; 21.91 + v[3] = Integer_rotateLeft(v[3], 8); 21.92 + v[3] ^= v[2]; 21.93 + v[0] += v[3]; 21.94 + v[3] = Integer_rotateLeft(v[3], 7); 21.95 + v[3] ^= v[0]; 21.96 + v[2] += v[1]; 21.97 + v[1] = Integer_rotateLeft(v[1], 13); 21.98 + v[1] ^= v[2]; 21.99 + v[2] = Integer_rotateLeft(v[2], 16); 21.100 + } 21.101 + } 21.102 + 21.103 +static void halfsiphash_adddata(uint32_t v[4], uint32_t newdata, int rounds) { 21.104 + v[3] ^= newdata; 21.105 + halfsiphash_rounds(v, rounds); 21.106 + v[0] ^= newdata; 21.107 +} 21.108 + 21.109 +static void halfsiphash_init32(uint32_t v[4], uint64_t seed) { 21.110 + v[0] = seed & 0xffffffff; 21.111 + v[1] = seed >> 32; 21.112 + v[2] = 0x6c796765 ^ v[0]; 21.113 + v[3] = 0x74656462 ^ v[1]; 21.114 +} 21.115 + 21.116 +static void halfsiphash_init64(uint32_t v[4], uint64_t seed) { 21.117 + halfsiphash_init32(v, seed); 21.118 + v[1] ^= 0xee; 21.119 +} 21.120 + 21.121 +uint32_t halfsiphash_finish32(uint32_t v[4], int rounds) { 21.122 + v[2] ^= 0xff; 21.123 + halfsiphash_rounds(v, rounds); 21.124 + return (v[1] ^ v[3]); 21.125 +} 21.126 + 21.127 +static uint64_t halfsiphash_finish64(uint32_t v[4], int rounds) { 21.128 + uint64_t rv; 21.129 + v[2] ^= 0xee; 21.130 + halfsiphash_rounds(v, rounds); 21.131 + rv = v[1] ^ v[3]; 21.132 + v[1] ^= 0xdd; 21.133 + halfsiphash_rounds(v, rounds); 21.134 + rv |= (uint64_t)(v[1] ^ v[3]) << 32; 21.135 + return rv; 21.136 +} 21.137 + 21.138 +// HalfSipHash-2-4 (32-bit output) for Symbols 21.139 +uint32_t AltHashing::halfsiphash_32(uint64_t seed, const uint8_t* data, int len) { 21.140 + uint32_t v[4]; 21.141 + uint32_t newdata; 21.142 + int off = 0; 21.143 int count = len; 21.144 - int offset = 0; 21.145 21.146 + halfsiphash_init32(v, seed); 21.147 // body 21.148 while (count >= 4) { 21.149 - juint k1 = (data[offset] & 0x0FF) 21.150 - | (data[offset + 1] & 0x0FF) << 8 21.151 - | (data[offset + 2] & 0x0FF) << 16 21.152 - | data[offset + 3] << 24; 21.153 + // Avoid sign extension with 0x0ff 21.154 + newdata = (data[off] & 0x0FF) 21.155 + | (data[off + 1] & 0x0FF) << 8 21.156 + | (data[off + 2] & 0x0FF) << 16 21.157 + | data[off + 3] << 24; 21.158 21.159 count -= 4; 21.160 - offset += 4; 21.161 + off += 4; 21.162 21.163 - k1 *= 0xcc9e2d51; 21.164 - k1 = Integer_rotateLeft(k1, 15); 21.165 - k1 *= 0x1b873593; 21.166 - 21.167 - h1 ^= k1; 21.168 - h1 = Integer_rotateLeft(h1, 13); 21.169 - h1 = h1 * 5 + 0xe6546b64; 21.170 + halfsiphash_adddata(v, newdata, 2); 21.171 } 21.172 21.173 // tail 21.174 + newdata = ((uint32_t)len) << 24; // (Byte.SIZE / Byte.SIZE); 21.175 21.176 if (count > 0) { 21.177 - juint k1 = 0; 21.178 - 21.179 switch (count) { 21.180 case 3: 21.181 - k1 ^= (data[offset + 2] & 0xff) << 16; 21.182 + newdata |= (data[off + 2] & 0x0ff) << 16; 21.183 // fall through 21.184 case 2: 21.185 - k1 ^= (data[offset + 1] & 0xff) << 8; 21.186 + newdata |= (data[off + 1] & 0x0ff) << 8; 21.187 // fall through 21.188 case 1: 21.189 - k1 ^= (data[offset] & 0xff); 21.190 + newdata |= (data[off] & 0x0ff); 21.191 // fall through 21.192 - default: 21.193 - k1 *= 0xcc9e2d51; 21.194 - k1 = Integer_rotateLeft(k1, 15); 21.195 - k1 *= 0x1b873593; 21.196 - h1 ^= k1; 21.197 } 21.198 } 21.199 21.200 + halfsiphash_adddata(v, newdata, 2); 21.201 + 21.202 // finalization 21.203 - h1 ^= len; 21.204 - 21.205 - // finalization mix force all bits of a hash block to avalanche 21.206 - h1 ^= h1 >> 16; 21.207 - h1 *= 0x85ebca6b; 21.208 - h1 ^= h1 >> 13; 21.209 - h1 *= 0xc2b2ae35; 21.210 - h1 ^= h1 >> 16; 21.211 - 21.212 - return h1; 21.213 + return halfsiphash_finish32(v, 4); 21.214 } 21.215 21.216 -// Murmur3 hashing for Strings 21.217 -juint AltHashing::murmur3_32(juint seed, const jchar* data, int len) { 21.218 - juint h1 = seed; 21.219 - 21.220 +// HalfSipHash-2-4 (32-bit output) for Strings 21.221 +uint32_t AltHashing::halfsiphash_32(uint64_t seed, const uint16_t* data, int len) { 21.222 + uint32_t v[4]; 21.223 + uint32_t newdata; 21.224 int off = 0; 21.225 int count = len; 21.226 21.227 + halfsiphash_init32(v, seed); 21.228 + 21.229 // body 21.230 while (count >= 2) { 21.231 - jchar d1 = data[off++] & 0xFFFF; 21.232 - jchar d2 = data[off++]; 21.233 - juint k1 = (d1 | d2 << 16); 21.234 + uint16_t d1 = data[off++] & 0x0FFFF; 21.235 + uint16_t d2 = data[off++]; 21.236 + newdata = (d1 | d2 << 16); 21.237 21.238 count -= 2; 21.239 21.240 - k1 *= 0xcc9e2d51; 21.241 - k1 = Integer_rotateLeft(k1, 15); 21.242 - k1 *= 0x1b873593; 21.243 - 21.244 - h1 ^= k1; 21.245 - h1 = Integer_rotateLeft(h1, 13); 21.246 - h1 = h1 * 5 + 0xe6546b64; 21.247 + halfsiphash_adddata(v, newdata, 2); 21.248 } 21.249 21.250 // tail 21.251 - 21.252 + newdata = ((uint32_t)len * 2) << 24; // (Character.SIZE / Byte.SIZE); 21.253 if (count > 0) { 21.254 - juint k1 = (juint)data[off]; 21.255 - 21.256 - k1 *= 0xcc9e2d51; 21.257 - k1 = Integer_rotateLeft(k1, 15); 21.258 - k1 *= 0x1b873593; 21.259 - h1 ^= k1; 21.260 + newdata |= (uint32_t)data[off]; 21.261 } 21.262 + halfsiphash_adddata(v, newdata, 2); 21.263 21.264 // finalization 21.265 - h1 ^= len * 2; // (Character.SIZE / Byte.SIZE); 21.266 - 21.267 - // finalization mix force all bits of a hash block to avalanche 21.268 - h1 ^= h1 >> 16; 21.269 - h1 *= 0x85ebca6b; 21.270 - h1 ^= h1 >> 13; 21.271 - h1 *= 0xc2b2ae35; 21.272 - h1 ^= h1 >> 16; 21.273 - 21.274 - return h1; 21.275 + return halfsiphash_finish32(v, 4); 21.276 } 21.277 21.278 -// Hash used for the seed. 21.279 -juint AltHashing::murmur3_32(juint seed, const int* data, int len) { 21.280 - juint h1 = seed; 21.281 +// HalfSipHash-2-4 (64-bit output) for integers (used to create seed) 21.282 +uint64_t AltHashing::halfsiphash_64(uint64_t seed, const uint32_t* data, int len) { 21.283 + uint32_t v[4]; 21.284 21.285 int off = 0; 21.286 int end = len; 21.287 21.288 + halfsiphash_init64(v, seed); 21.289 + 21.290 // body 21.291 while (off < end) { 21.292 - juint k1 = (juint)data[off++]; 21.293 - 21.294 - k1 *= 0xcc9e2d51; 21.295 - k1 = Integer_rotateLeft(k1, 15); 21.296 - k1 *= 0x1b873593; 21.297 - 21.298 - h1 ^= k1; 21.299 - h1 = Integer_rotateLeft(h1, 13); 21.300 - h1 = h1 * 5 + 0xe6546b64; 21.301 + halfsiphash_adddata(v, (uint32_t)data[off++], 2); 21.302 } 21.303 21.304 // tail (always empty, as body is always 32-bit chunks) 21.305 21.306 // finalization 21.307 - 21.308 - h1 ^= len * 4; // (Integer.SIZE / Byte.SIZE); 21.309 - 21.310 - // finalization mix force all bits of a hash block to avalanche 21.311 - h1 ^= h1 >> 16; 21.312 - h1 *= 0x85ebca6b; 21.313 - h1 ^= h1 >> 13; 21.314 - h1 *= 0xc2b2ae35; 21.315 - h1 ^= h1 >> 16; 21.316 - 21.317 - return h1; 21.318 + halfsiphash_adddata(v, ((uint32_t)len * 4) << 24, 2); // (Integer.SIZE / Byte.SIZE); 21.319 + return halfsiphash_finish64(v, 4); 21.320 } 21.321 21.322 -juint AltHashing::murmur3_32(const int* data, int len) { 21.323 - return murmur3_32(0, data, len); 21.324 +// HalfSipHash-2-4 (64-bit output) for integers (used to create seed) 21.325 +uint64_t AltHashing::halfsiphash_64(const uint32_t* data, int len) { 21.326 + return halfsiphash_64((uint64_t)0, data, len); 21.327 } 21.328 21.329 #ifndef PRODUCT 21.330 -// Overloaded versions for internal test. 21.331 -juint AltHashing::murmur3_32(const jbyte* data, int len) { 21.332 - return murmur3_32(0, data, len); 21.333 -} 21.334 + void AltHashing::testHalfsiphash_32_ByteArray() { 21.335 + const int factor = 4; 21.336 21.337 -juint AltHashing::murmur3_32(const jchar* data, int len) { 21.338 - return murmur3_32(0, data, len); 21.339 -} 21.340 + uint8_t vector[256]; 21.341 + uint8_t hashes[factor * 256]; 21.342 21.343 -// Internal test for alternate hashing. Translated from JDK version 21.344 -// test/sun/misc/Hashing.java 21.345 -static const jbyte ONE_BYTE[] = { (jbyte) 0x80}; 21.346 -static const jbyte TWO_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81}; 21.347 -static const jchar ONE_CHAR[] = { (jchar) 0x8180}; 21.348 -static const jbyte THREE_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82}; 21.349 -static const jbyte FOUR_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, (jbyte) 0x83}; 21.350 -static const jchar TWO_CHAR[] = { (jchar) 0x8180, (jchar) 0x8382}; 21.351 -static const jint ONE_INT[] = { (jint) 0x83828180}; 21.352 -static const jbyte SIX_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, (jbyte) 0x83, (jbyte) 0x84, (jbyte) 0x85}; 21.353 -static const jchar THREE_CHAR[] = { (jchar) 0x8180, (jchar) 0x8382, (jchar) 0x8584}; 21.354 -static const jbyte EIGHT_BYTE[] = { 21.355 - (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, 21.356 - (jbyte) 0x83, (jbyte) 0x84, (jbyte) 0x85, 21.357 - (jbyte) 0x86, (jbyte) 0x87}; 21.358 -static const jchar FOUR_CHAR[] = { 21.359 - (jchar) 0x8180, (jchar) 0x8382, 21.360 - (jchar) 0x8584, (jchar) 0x8786}; 21.361 + for (int i = 0; i < 256; i++) { 21.362 + vector[i] = (uint8_t) i; 21.363 + } 21.364 21.365 -static const jint TWO_INT[] = { (jint) 0x83828180, (jint) 0x87868584}; 21.366 + // Hash subranges {}, {0}, {0,1}, {0,1,2}, ..., {0,...,255} 21.367 + for (int i = 0; i < 256; i++) { 21.368 + uint32_t hash = AltHashing::halfsiphash_32(256 - i, vector, i); 21.369 + hashes[i * factor] = (uint8_t) hash; 21.370 + hashes[i * factor + 1] = (uint8_t)(hash >> 8); 21.371 + hashes[i * factor + 2] = (uint8_t)(hash >> 16); 21.372 + hashes[i * factor + 3] = (uint8_t)(hash >> 24); 21.373 + } 21.374 21.375 -static const juint MURMUR3_32_X86_CHECK_VALUE = 0xB0F57EE3; 21.376 + // hash to get const result. 21.377 + uint32_t final_hash = AltHashing::halfsiphash_32(0, hashes, factor*256); 21.378 21.379 -void AltHashing::testMurmur3_32_ByteArray() { 21.380 - // printf("testMurmur3_32_ByteArray\n"); 21.381 + // Value found using reference implementation for the hashes array. 21.382 + //uint64_t k = 0; // seed 21.383 + //uint32_t reference; 21.384 + //halfsiphash((const uint8_t*)hashes, factor*256, (const uint8_t *)&k, (uint8_t*)&reference, 4); 21.385 + //printf("0x%x", reference); 21.386 21.387 - jbyte vector[256]; 21.388 - jbyte hashes[4 * 256]; 21.389 + static const uint32_t HALFSIPHASH_32_BYTE_CHECK_VALUE = 0xd2be7fd8; 21.390 21.391 - for (int i = 0; i < 256; i++) { 21.392 - vector[i] = (jbyte) i; 21.393 + assert (HALFSIPHASH_32_BYTE_CHECK_VALUE == final_hash, 21.394 + err_msg( 21.395 + "Calculated hash result not as expected. Expected " UINT32_FORMAT " got " UINT32_FORMAT, 21.396 + HALFSIPHASH_32_BYTE_CHECK_VALUE, 21.397 + final_hash)); 21.398 } 21.399 21.400 - // Hash subranges {}, {0}, {0,1}, {0,1,2}, ..., {0,...,255} 21.401 - for (int i = 0; i < 256; i++) { 21.402 - juint hash = murmur3_32(256 - i, vector, i); 21.403 - hashes[i * 4] = (jbyte) hash; 21.404 - hashes[i * 4 + 1] = (jbyte)(hash >> 8); 21.405 - hashes[i * 4 + 2] = (jbyte)(hash >> 16); 21.406 - hashes[i * 4 + 3] = (jbyte)(hash >> 24); 21.407 + void AltHashing::testHalfsiphash_32_CharArray() { 21.408 + const int factor = 2; 21.409 + 21.410 + uint16_t vector[256]; 21.411 + uint16_t hashes[factor * 256]; 21.412 + 21.413 + for (int i = 0; i < 256; i++) { 21.414 + vector[i] = (uint16_t) i; 21.415 + } 21.416 + 21.417 + // Hash subranges {}, {0}, {0,1}, {0,1,2}, ..., {0,...,255} 21.418 + for (int i = 0; i < 256; i++) { 21.419 + uint32_t hash = AltHashing::halfsiphash_32(256 - i, vector, i); 21.420 + hashes[i * factor] = (uint16_t) hash; 21.421 + hashes[i * factor + 1] = (uint16_t)(hash >> 16); 21.422 + } 21.423 + 21.424 + // hash to get const result. 21.425 + uint32_t final_hash = AltHashing::halfsiphash_32(0, hashes, factor*256); 21.426 + 21.427 + // Value found using reference implementation for the hashes array. 21.428 + //uint64_t k = 0; // seed 21.429 + //uint32_t reference; 21.430 + //halfsiphash((const uint8_t*)hashes, 2*factor*256, (const uint8_t *)&k, (uint8_t*)&reference, 4); 21.431 + //printf("0x%x", reference); 21.432 + 21.433 + static const uint32_t HALFSIPHASH_32_CHAR_CHECK_VALUE = 0x428bf8a5; 21.434 + 21.435 + assert(HALFSIPHASH_32_CHAR_CHECK_VALUE == final_hash, 21.436 + err_msg( 21.437 + "Calculated hash result not as expected. Expected " UINT32_FORMAT " got " UINT32_FORMAT, 21.438 + HALFSIPHASH_32_CHAR_CHECK_VALUE, 21.439 + final_hash)); 21.440 } 21.441 21.442 - // hash to get const result. 21.443 - juint final_hash = murmur3_32(hashes, 4*256); 21.444 + // Test against sample hashes published with the reference implementation: 21.445 + // https://github.com/veorq/SipHash 21.446 + void AltHashing::testHalfsiphash_64_FromReference() { 21.447 21.448 - assert (MURMUR3_32_X86_CHECK_VALUE == final_hash, 21.449 - err_msg( 21.450 - "Calculated hash result not as expected. Expected %08X got %08X\n", 21.451 - MURMUR3_32_X86_CHECK_VALUE, 21.452 - final_hash)); 21.453 -} 21.454 + const uint64_t seed = 0x0706050403020100; 21.455 + const uint64_t results[16] = { 21.456 + 0xc83cb8b9591f8d21, 0xa12ee55b178ae7d5, 21.457 + 0x8c85e4bc20e8feed, 0x99c7f5ae9f1fc77b, 21.458 + 0xb5f37b5fd2aa3673, 0xdba7ee6f0a2bf51b, 21.459 + 0xf1a63fae45107470, 0xb516001efb5f922d, 21.460 + 0x6c6211d8469d7028, 0xdc7642ec407ad686, 21.461 + 0x4caec8671cc8385b, 0x5ab1dc27adf3301e, 21.462 + 0x3e3ea94bc0a8eaa9, 0xe150f598795a4402, 21.463 + 0x1d5ff142f992a4a1, 0x60e426bf902876d6 21.464 + }; 21.465 + uint32_t vector[16]; 21.466 21.467 -void AltHashing::testEquivalentHashes() { 21.468 - juint jbytes, jchars, ints; 21.469 + for (int i = 0; i < 16; i++) 21.470 + vector[i] = 0x03020100 + i * 0x04040404; 21.471 21.472 - // printf("testEquivalentHashes\n"); 21.473 + for (int i = 0; i < 16; i++) { 21.474 + uint64_t hash = AltHashing::halfsiphash_64(seed, vector, i); 21.475 + assert(results[i] == hash, 21.476 + err_msg( 21.477 + "Calculated hash result not as expected. Round %d: " 21.478 + "Expected " UINT64_FORMAT_X " got " UINT64_FORMAT_X "\n", 21.479 + i, 21.480 + results[i], 21.481 + hash)); 21.482 + } 21.483 + } 21.484 21.485 - jbytes = murmur3_32(TWO_BYTE, 2); 21.486 - jchars = murmur3_32(ONE_CHAR, 1); 21.487 - assert (jbytes == jchars, 21.488 - err_msg("Hashes did not match. b:%08x != c:%08x\n", jbytes, jchars)); 21.489 - 21.490 - jbytes = murmur3_32(FOUR_BYTE, 4); 21.491 - jchars = murmur3_32(TWO_CHAR, 2); 21.492 - ints = murmur3_32(ONE_INT, 1); 21.493 - assert ((jbytes == jchars) && (jbytes == ints), 21.494 - err_msg("Hashes did not match. b:%08x != c:%08x != i:%08x\n", jbytes, jchars, ints)); 21.495 - 21.496 - jbytes = murmur3_32(SIX_BYTE, 6); 21.497 - jchars = murmur3_32(THREE_CHAR, 3); 21.498 - assert (jbytes == jchars, 21.499 - err_msg("Hashes did not match. b:%08x != c:%08x\n", jbytes, jchars)); 21.500 - 21.501 - jbytes = murmur3_32(EIGHT_BYTE, 8); 21.502 - jchars = murmur3_32(FOUR_CHAR, 4); 21.503 - ints = murmur3_32(TWO_INT, 2); 21.504 - assert ((jbytes == jchars) && (jbytes == ints), 21.505 - err_msg("Hashes did not match. b:%08x != c:%08x != i:%08x\n", jbytes, jchars, ints)); 21.506 -} 21.507 - 21.508 -// Returns true if the alternate hashcode is correct 21.509 void AltHashing::test_alt_hash() { 21.510 - testMurmur3_32_ByteArray(); 21.511 - testEquivalentHashes(); 21.512 + testHalfsiphash_32_ByteArray(); 21.513 + testHalfsiphash_32_CharArray(); 21.514 + testHalfsiphash_64_FromReference(); 21.515 } 21.516 #endif // PRODUCT
22.1 --- a/src/share/vm/classfile/altHashing.hpp Sat Oct 24 16:18:50 2020 +0800 22.2 +++ b/src/share/vm/classfile/altHashing.hpp Sat Oct 24 16:43:47 2020 +0800 22.3 @@ -26,37 +26,30 @@ 22.4 #define SHARE_VM_CLASSFILE_ALTHASHING_HPP 22.5 22.6 #include "prims/jni.h" 22.7 -#include "classfile/symbolTable.hpp" 22.8 +#include "memory/allocation.hpp" 22.9 22.10 /** 22.11 - * Hashing utilities. 22.12 - * 22.13 - * Implementation of Murmur3 hashing. 22.14 - * This code was translated from src/share/classes/sun/misc/Hashing.java 22.15 - * code in the JDK. 22.16 + * Implementation of alternate more secure hashing. 22.17 */ 22.18 22.19 class AltHashing : AllStatic { 22.20 22.21 - // utility function copied from java/lang/Integer 22.22 - static juint Integer_rotateLeft(juint i, int distance) { 22.23 - return (i << distance) | (i >> (32-distance)); 22.24 - } 22.25 - static juint murmur3_32(const int* data, int len); 22.26 - static juint murmur3_32(juint seed, const int* data, int len); 22.27 + // For the seed computation 22.28 + static uint64_t halfsiphash_64(const uint32_t* data, int len); 22.29 + static uint64_t halfsiphash_64(uint64_t seed, const uint32_t* data, int len); 22.30 + #ifndef PRODUCT 22.31 + // Hashing functions used for internal testing 22.32 + static void testHalfsiphash_32_ByteArray(); 22.33 + static void testHalfsiphash_32_CharArray(); 22.34 + static void testHalfsiphash_64_FromReference(); 22.35 + #endif // PRODUCT 22.36 + public: 22.37 + static uint64_t compute_seed(); 22.38 22.39 -#ifndef PRODUCT 22.40 - // Hashing functions used for internal testing 22.41 - static juint murmur3_32(const jbyte* data, int len); 22.42 - static juint murmur3_32(const jchar* data, int len); 22.43 - static void testMurmur3_32_ByteArray(); 22.44 - static void testEquivalentHashes(); 22.45 -#endif // PRODUCT 22.46 - 22.47 - public: 22.48 - static juint compute_seed(); 22.49 - static juint murmur3_32(juint seed, const jbyte* data, int len); 22.50 - static juint murmur3_32(juint seed, const jchar* data, int len); 22.51 + // For Symbols 22.52 + static uint32_t halfsiphash_32(uint64_t seed, const uint8_t* data, int len); 22.53 + // For Strings 22.54 + static uint32_t halfsiphash_32(uint64_t seed, const uint16_t* data, int len); 22.55 NOT_PRODUCT(static void test_alt_hash();) 22.56 }; 22.57 #endif // SHARE_VM_CLASSFILE_ALTHASHING_HPP
23.1 --- a/src/share/vm/classfile/classFileParser.cpp Sat Oct 24 16:18:50 2020 +0800 23.2 +++ b/src/share/vm/classfile/classFileParser.cpp Sat Oct 24 16:43:47 2020 +0800 23.3 @@ -2691,8 +2691,83 @@ 23.4 // Inner classes can be static, private or protected (classic VM does this) 23.5 #define RECOGNIZED_INNER_CLASS_MODIFIERS (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED | JVM_ACC_STATIC) 23.6 23.7 +// Find index of the InnerClasses entry for the specified inner_class_info_index. 23.8 +// Return -1 if none is found. 23.9 +static int inner_classes_find_index(const Array<u2>* inner_classes, int inner, const ConstantPool* cp, int length) { 23.10 + Symbol* cp_klass_name = cp->klass_name_at(inner); 23.11 + for (int idx = 0; idx < length; idx += InstanceKlass::inner_class_next_offset) { 23.12 + int idx_inner = inner_classes->at(idx + InstanceKlass::inner_class_inner_class_info_offset); 23.13 + if (cp->klass_name_at(idx_inner) == cp_klass_name) { 23.14 + return idx; 23.15 + } 23.16 + } 23.17 + return -1; 23.18 +} 23.19 + 23.20 +// Return the outer_class_info_index for the InnerClasses entry containing the 23.21 +// specified inner_class_info_index. Return -1 if no InnerClasses entry is found. 23.22 +static int inner_classes_jump_to_outer(const Array<u2>* inner_classes, int inner, const ConstantPool* cp, int length) { 23.23 + if (inner == 0) return -1; 23.24 + int idx = inner_classes_find_index(inner_classes, inner, cp, length); 23.25 + if (idx == -1) return -1; 23.26 + int result = inner_classes->at(idx + InstanceKlass::inner_class_outer_class_info_offset); 23.27 + return result; 23.28 +} 23.29 + 23.30 +// Return true if circularity is found, false if no circularity is found. 23.31 +// Use Floyd's cycle finding algorithm. 23.32 +static bool inner_classes_check_loop_through_outer(const Array<u2>* inner_classes, int idx, const ConstantPool* cp, int length) { 23.33 + int slow = inner_classes->at(idx + InstanceKlass::inner_class_inner_class_info_offset); 23.34 + int fast = inner_classes->at(idx + InstanceKlass::inner_class_outer_class_info_offset); 23.35 + while (fast != -1 && fast != 0) { 23.36 + if (slow != 0 && (cp->klass_name_at(slow) == cp->klass_name_at(fast))) { 23.37 + return true; // found a circularity 23.38 + } 23.39 + fast = inner_classes_jump_to_outer(inner_classes, fast, cp, length); 23.40 + if (fast == -1) return false; 23.41 + fast = inner_classes_jump_to_outer(inner_classes, fast, cp, length); 23.42 + if (fast == -1) return false; 23.43 + slow = inner_classes_jump_to_outer(inner_classes, slow, cp, length); 23.44 + assert(slow != -1, "sanity check"); 23.45 + } 23.46 + return false; 23.47 +} 23.48 + 23.49 +// Loop through each InnerClasses entry checking for circularities and duplications 23.50 +// with other entries. If duplicate entries are found then throw CFE. Otherwise, 23.51 +// return true if a circularity or entries with duplicate inner_class_info_indexes 23.52 +// are found. 23.53 +bool ClassFileParser::check_inner_classes_circularity(const ConstantPool* cp, int length, TRAPS) { 23.54 + // Loop through each InnerClasses entry. 23.55 + for (int idx = 0; idx < length; idx += InstanceKlass::inner_class_next_offset) { 23.56 + // Return true if there are circular entries. 23.57 + if (inner_classes_check_loop_through_outer(_inner_classes, idx, cp, length)) { 23.58 + return true; 23.59 + } 23.60 + // Check if there are duplicate entries or entries with the same inner_class_info_index. 23.61 + for (int y = idx + InstanceKlass::inner_class_next_offset; y < length; 23.62 + y += InstanceKlass::inner_class_next_offset) { 23.63 + 23.64 + // To maintain compatibility, throw an exception if duplicate inner classes 23.65 + // entries are found. 23.66 + guarantee_property((_inner_classes->at(idx) != _inner_classes->at(y) || 23.67 + _inner_classes->at(idx+1) != _inner_classes->at(y+1) || 23.68 + _inner_classes->at(idx+2) != _inner_classes->at(y+2) || 23.69 + _inner_classes->at(idx+3) != _inner_classes->at(y+3)), 23.70 + "Duplicate entry in InnerClasses attribute in class file %s", 23.71 + CHECK_(true)); 23.72 + // Return true if there are two entries with the same inner_class_info_index. 23.73 + if (_inner_classes->at(y) == _inner_classes->at(idx)) { 23.74 + return true; 23.75 + } 23.76 + } 23.77 + } 23.78 + return false; 23.79 +} 23.80 + 23.81 // Return number of classes in the inner classes attribute table 23.82 -u2 ClassFileParser::parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start, 23.83 +u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ConstantPool* cp, 23.84 + u1* inner_classes_attribute_start, 23.85 bool parsed_enclosingmethod_attribute, 23.86 u2 enclosing_method_class_index, 23.87 u2 enclosing_method_method_index, 23.88 @@ -2764,25 +2839,28 @@ 23.89 } 23.90 23.91 // 4347400: make sure there's no duplicate entry in the classes array 23.92 + // Also, check for circular entries. 23.93 + bool has_circularity = false; 23.94 if (_need_verify && _major_version >= JAVA_1_5_VERSION) { 23.95 - for(int i = 0; i < length * 4; i += 4) { 23.96 - for(int j = i + 4; j < length * 4; j += 4) { 23.97 - guarantee_property((inner_classes->at(i) != inner_classes->at(j) || 23.98 - inner_classes->at(i+1) != inner_classes->at(j+1) || 23.99 - inner_classes->at(i+2) != inner_classes->at(j+2) || 23.100 - inner_classes->at(i+3) != inner_classes->at(j+3)), 23.101 - "Duplicate entry in InnerClasses in class file %s", 23.102 - CHECK_0); 23.103 + has_circularity = check_inner_classes_circularity(cp, length * 4, CHECK_0); 23.104 + if (has_circularity) { 23.105 + // If circularity check failed then ignore InnerClasses attribute. 23.106 + MetadataFactory::free_array<u2>(_loader_data, _inner_classes); 23.107 + index = 0; 23.108 + if (parsed_enclosingmethod_attribute) { 23.109 + inner_classes = MetadataFactory::new_array<u2>(_loader_data, 2, CHECK_0); 23.110 + _inner_classes = inner_classes; 23.111 + } else { 23.112 + _inner_classes = Universe::the_empty_short_array(); 23.113 } 23.114 } 23.115 } 23.116 - 23.117 // Set EnclosingMethod class and method indexes. 23.118 if (parsed_enclosingmethod_attribute) { 23.119 inner_classes->at_put(index++, enclosing_method_class_index); 23.120 inner_classes->at_put(index++, enclosing_method_method_index); 23.121 } 23.122 - assert(index == size, "wrong size"); 23.123 + assert(index == size || has_circularity, "wrong size"); 23.124 23.125 // Restore buffer's current position. 23.126 cfs->set_current(current_mark); 23.127 @@ -3051,6 +3129,7 @@ 23.128 23.129 if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) { 23.130 u2 num_of_classes = parse_classfile_inner_classes_attribute( 23.131 + _cp, 23.132 inner_classes_attribute_start, 23.133 parsed_innerclasses_attribute, 23.134 enclosing_method_class_index,
24.1 --- a/src/share/vm/classfile/classFileParser.hpp Sat Oct 24 16:18:50 2020 +0800 24.2 +++ b/src/share/vm/classfile/classFileParser.hpp Sat Oct 24 16:43:47 2020 +0800 24.3 @@ -275,7 +275,12 @@ 24.4 u2 parse_generic_signature_attribute(TRAPS); 24.5 void parse_classfile_sourcefile_attribute(TRAPS); 24.6 void parse_classfile_source_debug_extension_attribute(int length, TRAPS); 24.7 - u2 parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start, 24.8 + 24.9 + // Check for circularity in InnerClasses attribute. 24.10 + bool check_inner_classes_circularity(const ConstantPool* cp, int length, TRAPS); 24.11 + 24.12 + u2 parse_classfile_inner_classes_attribute(const ConstantPool* cp, 24.13 + u1* inner_classes_attribute_start, 24.14 bool parsed_enclosingmethod_attribute, 24.15 u2 enclosing_method_class_index, 24.16 u2 enclosing_method_method_index,
25.1 --- a/src/share/vm/classfile/javaClasses.cpp Sat Oct 24 16:18:50 2020 +0800 25.2 +++ b/src/share/vm/classfile/javaClasses.cpp Sat Oct 24 16:43:47 2020 +0800 25.3 @@ -1235,6 +1235,16 @@ 25.4 } 25.5 25.6 25.7 +// Return Symbol for detailed_message or NULL 25.8 +Symbol* java_lang_Throwable::detail_message(oop throwable) { 25.9 + PRESERVE_EXCEPTION_MARK; // Keep original exception 25.10 + oop detailed_message = java_lang_Throwable::message(throwable); 25.11 + if (detailed_message != NULL) { 25.12 + return java_lang_String::as_symbol(detailed_message, THREAD); 25.13 + } 25.14 + return NULL; 25.15 +} 25.16 + 25.17 void java_lang_Throwable::set_message(oop throwable, oop value) { 25.18 throwable->obj_field_put(detailMessage_offset, value); 25.19 }
26.1 --- a/src/share/vm/classfile/javaClasses.hpp Sat Oct 24 16:18:50 2020 +0800 26.2 +++ b/src/share/vm/classfile/javaClasses.hpp Sat Oct 24 16:43:47 2020 +0800 26.3 @@ -518,6 +518,7 @@ 26.4 static oop message(oop throwable); 26.5 static oop message(Handle throwable); 26.6 static void set_message(oop throwable, oop value); 26.7 + static Symbol* detail_message(oop throwable); 26.8 static void print_stack_element(outputStream *st, Handle mirror, int method, 26.9 int version, int bci, int cpref); 26.10 static void print_stack_element(outputStream *st, methodHandle method, int bci);
27.1 --- a/src/share/vm/classfile/resolutionErrors.cpp Sat Oct 24 16:18:50 2020 +0800 27.2 +++ b/src/share/vm/classfile/resolutionErrors.cpp Sat Oct 24 16:43:47 2020 +0800 27.3 @@ -1,5 +1,5 @@ 27.4 /* 27.5 - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. 27.6 + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. 27.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 27.8 * 27.9 * This code is free software; you can redistribute it and/or modify it 27.10 @@ -32,12 +32,13 @@ 27.11 27.12 // add new entry to the table 27.13 void ResolutionErrorTable::add_entry(int index, unsigned int hash, 27.14 - constantPoolHandle pool, int cp_index, Symbol* error) 27.15 + constantPoolHandle pool, int cp_index, 27.16 + Symbol* error, Symbol* message) 27.17 { 27.18 assert_locked_or_safepoint(SystemDictionary_lock); 27.19 assert(!pool.is_null() && error != NULL, "adding NULL obj"); 27.20 27.21 - ResolutionErrorEntry* entry = new_entry(hash, pool(), cp_index, error); 27.22 + ResolutionErrorEntry* entry = new_entry(hash, pool(), cp_index, error, message); 27.23 add_entry(index, entry); 27.24 } 27.25 27.26 @@ -58,19 +59,26 @@ 27.27 } 27.28 27.29 void ResolutionErrorEntry::set_error(Symbol* e) { 27.30 - assert(e == NULL || _error == NULL, "cannot reset error"); 27.31 + assert(e != NULL, "must set a value"); 27.32 _error = e; 27.33 - if (_error != NULL) _error->increment_refcount(); 27.34 + _error->increment_refcount(); 27.35 +} 27.36 + 27.37 +void ResolutionErrorEntry::set_message(Symbol* c) { 27.38 + assert(c != NULL, "must set a value"); 27.39 + _message = c; 27.40 + _message->increment_refcount(); 27.41 } 27.42 27.43 // create new error entry 27.44 ResolutionErrorEntry* ResolutionErrorTable::new_entry(int hash, ConstantPool* pool, 27.45 - int cp_index, Symbol* error) 27.46 + int cp_index, Symbol* error, 27.47 + Symbol* message) 27.48 { 27.49 ResolutionErrorEntry* entry = (ResolutionErrorEntry*)Hashtable<ConstantPool*, mtClass>::new_entry(hash, pool); 27.50 entry->set_cp_index(cp_index); 27.51 - NOT_PRODUCT(entry->set_error(NULL);) 27.52 entry->set_error(error); 27.53 + entry->set_message(message); 27.54 27.55 return entry; 27.56 } 27.57 @@ -79,6 +87,7 @@ 27.58 // decrement error refcount 27.59 assert(entry->error() != NULL, "error should be set"); 27.60 entry->error()->decrement_refcount(); 27.61 + entry->message()->decrement_refcount(); 27.62 Hashtable<ConstantPool*, mtClass>::free_entry(entry); 27.63 } 27.64
28.1 --- a/src/share/vm/classfile/resolutionErrors.hpp Sat Oct 24 16:18:50 2020 +0800 28.2 +++ b/src/share/vm/classfile/resolutionErrors.hpp Sat Oct 24 16:43:47 2020 +0800 28.3 @@ -1,5 +1,5 @@ 28.4 /* 28.5 - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. 28.6 + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. 28.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 28.8 * 28.9 * This code is free software; you can redistribute it and/or modify it 28.10 @@ -38,7 +38,8 @@ 28.11 public: 28.12 ResolutionErrorTable(int table_size); 28.13 28.14 - ResolutionErrorEntry* new_entry(int hash, ConstantPool* pool, int cp_index, Symbol* error); 28.15 + ResolutionErrorEntry* new_entry(int hash, ConstantPool* pool, int cp_index, 28.16 + Symbol* error, Symbol* message); 28.17 void free_entry(ResolutionErrorEntry *entry); 28.18 28.19 ResolutionErrorEntry* bucket(int i) { 28.20 @@ -55,7 +56,7 @@ 28.21 } 28.22 28.23 void add_entry(int index, unsigned int hash, 28.24 - constantPoolHandle pool, int which, Symbol* error); 28.25 + constantPoolHandle pool, int which, Symbol* error, Symbol* message); 28.26 28.27 28.28 // find error given the constant pool and constant pool index 28.29 @@ -79,10 +80,10 @@ 28.30 private: 28.31 int _cp_index; 28.32 Symbol* _error; 28.33 + Symbol* _message; 28.34 28.35 public: 28.36 - ConstantPool* pool() const { return (ConstantPool*)literal(); } 28.37 - ConstantPool** pool_addr() { return (ConstantPool**)literal_addr(); } 28.38 + ConstantPool* pool() const { return literal(); } 28.39 28.40 int cp_index() const { return _cp_index; } 28.41 void set_cp_index(int cp_index) { _cp_index = cp_index; } 28.42 @@ -90,6 +91,9 @@ 28.43 Symbol* error() const { return _error; } 28.44 void set_error(Symbol* e); 28.45 28.46 + Symbol* message() const { return _message; } 28.47 + void set_message(Symbol* c); 28.48 + 28.49 ResolutionErrorEntry* next() const { 28.50 return (ResolutionErrorEntry*)HashtableEntry<ConstantPool*, mtClass>::next(); 28.51 }
29.1 --- a/src/share/vm/classfile/symbolTable.cpp Sat Oct 24 16:18:50 2020 +0800 29.2 +++ b/src/share/vm/classfile/symbolTable.cpp Sat Oct 24 16:43:47 2020 +0800 29.3 @@ -1,5 +1,5 @@ 29.4 /* 29.5 - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 29.6 + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. 29.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 29.8 * 29.9 * This code is free software; you can redistribute it and/or modify it 29.10 @@ -224,7 +224,7 @@ 29.11 // Pick hashing algorithm. 29.12 unsigned int SymbolTable::hash_symbol(const char* s, int len) { 29.13 return use_alternate_hashcode() ? 29.14 - AltHashing::murmur3_32(seed(), (const jbyte*)s, len) : 29.15 + AltHashing::halfsiphash_32(seed(), (const uint8_t*)s, len) : 29.16 java_lang_String::hash_code(s, len); 29.17 } 29.18 29.19 @@ -650,7 +650,7 @@ 29.20 29.21 // Pick hashing algorithm 29.22 unsigned int StringTable::hash_string(const jchar* s, int len) { 29.23 - return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) : 29.24 + return use_alternate_hashcode() ? AltHashing::halfsiphash_32(seed(), s, len) : 29.25 java_lang_String::hash_code(s, len); 29.26 } 29.27
30.1 --- a/src/share/vm/classfile/systemDictionary.cpp Sat Oct 24 16:18:50 2020 +0800 30.2 +++ b/src/share/vm/classfile/systemDictionary.cpp Sat Oct 24 16:43:47 2020 +0800 30.3 @@ -1,5 +1,5 @@ 30.4 /* 30.5 - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. 30.6 + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. 30.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 30.8 * 30.9 * This code is free software; you can redistribute it and/or modify it 30.10 @@ -185,12 +185,14 @@ 30.11 if (HAS_PENDING_EXCEPTION || klass == NULL) { 30.12 KlassHandle k_h(THREAD, klass); 30.13 // can return a null klass 30.14 - klass = handle_resolution_exception(class_name, class_loader, protection_domain, throw_error, k_h, THREAD); 30.15 + klass = handle_resolution_exception(class_name, throw_error, k_h, THREAD); 30.16 } 30.17 return klass; 30.18 } 30.19 30.20 -Klass* SystemDictionary::handle_resolution_exception(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, KlassHandle klass_h, TRAPS) { 30.21 +Klass* SystemDictionary::handle_resolution_exception(Symbol* class_name, 30.22 + bool throw_error, 30.23 + KlassHandle klass_h, TRAPS) { 30.24 if (HAS_PENDING_EXCEPTION) { 30.25 // If we have a pending exception we forward it to the caller, unless throw_error is true, 30.26 // in which case we have to check whether the pending exception is a ClassNotFoundException, 30.27 @@ -398,7 +400,7 @@ 30.28 } 30.29 if (HAS_PENDING_EXCEPTION || superk_h() == NULL) { 30.30 // can null superk 30.31 - superk_h = KlassHandle(THREAD, handle_resolution_exception(class_name, class_loader, protection_domain, true, superk_h, THREAD)); 30.32 + superk_h = KlassHandle(THREAD, handle_resolution_exception(class_name, true, superk_h, THREAD)); 30.33 } 30.34 30.35 return superk_h(); 30.36 @@ -1072,6 +1074,18 @@ 30.37 return k(); 30.38 } 30.39 30.40 +static bool is_prohibited_package_slow(Symbol* class_name) { 30.41 + // Caller has ResourceMark 30.42 + int length; 30.43 + jchar* unicode = class_name->as_unicode(length); 30.44 + return (length >= 5 && 30.45 + unicode[0] == 'j' && 30.46 + unicode[1] == 'a' && 30.47 + unicode[2] == 'v' && 30.48 + unicode[3] == 'a' && 30.49 + unicode[4] == '/'); 30.50 +} 30.51 + 30.52 // Add a klass to the system from a stream (called by jni_DefineClass and 30.53 // JVM_DefineClass). 30.54 // Note: class_name can be NULL. In that case we do not know the name of 30.55 @@ -1119,24 +1133,33 @@ 30.56 if (!HAS_PENDING_EXCEPTION && 30.57 !class_loader.is_null() && 30.58 parsed_name != NULL && 30.59 - parsed_name->utf8_length() >= (int)pkglen && 30.60 - !strncmp((const char*)parsed_name->bytes(), pkg, pkglen)) { 30.61 - // It is illegal to define classes in the "java." package from 30.62 - // JVM_DefineClass or jni_DefineClass unless you're the bootclassloader 30.63 + parsed_name->utf8_length() >= (int)pkglen) { 30.64 ResourceMark rm(THREAD); 30.65 - char* name = parsed_name->as_C_string(); 30.66 - char* index = strrchr(name, '/'); 30.67 - assert(index != NULL, "must be"); 30.68 - *index = '\0'; // chop to just the package name 30.69 - while ((index = strchr(name, '/')) != NULL) { 30.70 - *index = '.'; // replace '/' with '.' in package name 30.71 + bool prohibited; 30.72 + const jbyte* base = parsed_name->base(); 30.73 + if ((base[0] | base[1] | base[2] | base[3] | base[4]) & 0x80) { 30.74 + prohibited = is_prohibited_package_slow(parsed_name); 30.75 + } else { 30.76 + char* name = parsed_name->as_C_string(); 30.77 + prohibited = (strncmp(name, pkg, pkglen) == 0); 30.78 } 30.79 - const char* fmt = "Prohibited package name: %s"; 30.80 - size_t len = strlen(fmt) + strlen(name); 30.81 - char* message = NEW_RESOURCE_ARRAY(char, len); 30.82 - jio_snprintf(message, len, fmt, name); 30.83 - Exceptions::_throw_msg(THREAD_AND_LOCATION, 30.84 - vmSymbols::java_lang_SecurityException(), message); 30.85 + if (prohibited) { 30.86 + // It is illegal to define classes in the "java." package from 30.87 + // JVM_DefineClass or jni_DefineClass unless you're the bootclassloader 30.88 + char* name = parsed_name->as_C_string(); 30.89 + char* index = strrchr(name, '/'); 30.90 + assert(index != NULL, "must be"); 30.91 + *index = '\0'; // chop to just the package name 30.92 + while ((index = strchr(name, '/')) != NULL) { 30.93 + *index = '.'; // replace '/' with '.' in package name 30.94 + } 30.95 + const char* fmt = "Prohibited package name: %s"; 30.96 + size_t len = strlen(fmt) + strlen(name); 30.97 + char* message = NEW_RESOURCE_ARRAY(char, len); 30.98 + jio_snprintf(message, len, fmt, name); 30.99 + Exceptions::_throw_msg(THREAD_AND_LOCATION, 30.100 + vmSymbols::java_lang_SecurityException(), message); 30.101 + } 30.102 } 30.103 30.104 if (!HAS_PENDING_EXCEPTION) { 30.105 @@ -2246,12 +2269,13 @@ 30.106 30.107 // Add entry to resolution error table to record the error when the first 30.108 // attempt to resolve a reference to a class has failed. 30.109 -void SystemDictionary::add_resolution_error(constantPoolHandle pool, int which, Symbol* error) { 30.110 +void SystemDictionary::add_resolution_error(constantPoolHandle pool, int which, 30.111 + Symbol* error, Symbol* message) { 30.112 unsigned int hash = resolution_errors()->compute_hash(pool, which); 30.113 int index = resolution_errors()->hash_to_index(hash); 30.114 { 30.115 MutexLocker ml(SystemDictionary_lock, Thread::current()); 30.116 - resolution_errors()->add_entry(index, hash, pool, which, error); 30.117 + resolution_errors()->add_entry(index, hash, pool, which, error, message); 30.118 } 30.119 } 30.120 30.121 @@ -2261,13 +2285,19 @@ 30.122 } 30.123 30.124 // Lookup resolution error table. Returns error if found, otherwise NULL. 30.125 -Symbol* SystemDictionary::find_resolution_error(constantPoolHandle pool, int which) { 30.126 +Symbol* SystemDictionary::find_resolution_error(constantPoolHandle pool, int which, 30.127 + Symbol** message) { 30.128 unsigned int hash = resolution_errors()->compute_hash(pool, which); 30.129 int index = resolution_errors()->hash_to_index(hash); 30.130 { 30.131 MutexLocker ml(SystemDictionary_lock, Thread::current()); 30.132 ResolutionErrorEntry* entry = resolution_errors()->find_entry(index, hash, pool, which); 30.133 - return (entry != NULL) ? entry->error() : (Symbol*)NULL; 30.134 + if (entry != NULL) { 30.135 + *message = entry->message(); 30.136 + return entry->error(); 30.137 + } else { 30.138 + return NULL; 30.139 + } 30.140 } 30.141 } 30.142
31.1 --- a/src/share/vm/classfile/systemDictionary.hpp Sat Oct 24 16:18:50 2020 +0800 31.2 +++ b/src/share/vm/classfile/systemDictionary.hpp Sat Oct 24 16:43:47 2020 +0800 31.3 @@ -241,7 +241,7 @@ 31.4 static Klass* resolve_or_fail(Symbol* class_name, bool throw_error, TRAPS); 31.5 protected: 31.6 // handle error translation for resolve_or_null results 31.7 - static Klass* handle_resolution_exception(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, KlassHandle klass_h, TRAPS); 31.8 + static Klass* handle_resolution_exception(Symbol* class_name, bool throw_error, KlassHandle klass_h, TRAPS); 31.9 31.10 public: 31.11 31.12 @@ -549,9 +549,11 @@ 31.13 31.14 // Record the error when the first attempt to resolve a reference from a constant 31.15 // pool entry to a class fails. 31.16 - static void add_resolution_error(constantPoolHandle pool, int which, Symbol* error); 31.17 + static void add_resolution_error(constantPoolHandle pool, int which, Symbol* error, 31.18 + Symbol* message); 31.19 static void delete_resolution_error(ConstantPool* pool); 31.20 - static Symbol* find_resolution_error(constantPoolHandle pool, int which); 31.21 + static Symbol* find_resolution_error(constantPoolHandle pool, int which, 31.22 + Symbol** message); 31.23 31.24 protected: 31.25
32.1 --- a/src/share/vm/compiler/disassembler.cpp Sat Oct 24 16:18:50 2020 +0800 32.2 +++ b/src/share/vm/compiler/disassembler.cpp Sat Oct 24 16:43:47 2020 +0800 32.3 @@ -253,19 +253,24 @@ 32.4 const char* options() { return _option_buf; } 32.5 }; 32.6 32.7 -decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c) { 32.8 - memset(this, 0, sizeof(*this)); // Beware, this zeroes bits of fields. 32.9 - _output = output ? output : tty; 32.10 - _code = code; 32.11 - if (code != NULL && code->is_nmethod()) 32.12 - _nm = (nmethod*) code; 32.13 +decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c) : 32.14 + _nm((code != NULL && code->is_nmethod()) ? (nmethod*)code : NULL), 32.15 + _code(code), 32.16 + _strings(), 32.17 + _output(output ? output : tty), 32.18 + _start(NULL), 32.19 + _end(NULL), 32.20 + _print_raw(0), 32.21 + // by default, output pc but not bytes: 32.22 + _print_pc(true), 32.23 + _print_bytes(false), 32.24 + _cur_insn(NULL), 32.25 + _total_ticks(0), 32.26 + _bytes_per_line(Disassembler::pd_instruction_alignment()) 32.27 +{ 32.28 + memset(_option_buf, 0, sizeof(_option_buf)); 32.29 _strings.copy(c); 32.30 32.31 - // by default, output pc but not bytes: 32.32 - _print_pc = true; 32.33 - _print_bytes = false; 32.34 - _bytes_per_line = Disassembler::pd_instruction_alignment(); 32.35 - 32.36 // parse the global option string: 32.37 collect_options(Disassembler::pd_cpu_opts()); 32.38 collect_options(PrintAssemblyOptions);
33.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Sat Oct 24 16:18:50 2020 +0800 33.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Sat Oct 24 16:43:47 2020 +0800 33.3 @@ -1,5 +1,5 @@ 33.4 /* 33.5 - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. 33.6 + * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. 33.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 33.8 * 33.9 * This code is free software; you can redistribute it and/or modify it 33.10 @@ -994,6 +994,10 @@ 33.11 return res; 33.12 } 33.13 } else { 33.14 + // The barrier is required to prevent reordering of the free chunk check 33.15 + // and the klass read. 33.16 + OrderAccess::loadload(); 33.17 + 33.18 // must read from what 'p' points to in each loop. 33.19 Klass* k = ((volatile oopDesc*)p)->klass_or_null(); 33.20 if (k != NULL) { 33.21 @@ -1049,6 +1053,10 @@ 33.22 return res; 33.23 } 33.24 } else { 33.25 + // The barrier is required to prevent reordering of the free chunk check 33.26 + // and the klass read. 33.27 + OrderAccess::loadload(); 33.28 + 33.29 // must read from what 'p' points to in each loop. 33.30 Klass* k = ((volatile oopDesc*)p)->klass_or_null(); 33.31 // We trust the size of any object that has a non-NULL 33.32 @@ -1111,6 +1119,11 @@ 33.33 // assert(CollectedHeap::use_parallel_gc_threads() || _bt.block_start(p) == p, 33.34 // "Should be a block boundary"); 33.35 if (FreeChunk::indicatesFreeChunk(p)) return false; 33.36 + 33.37 + // The barrier is required to prevent reordering of the free chunk check 33.38 + // and the klass read. 33.39 + OrderAccess::loadload(); 33.40 + 33.41 Klass* k = oop(p)->klass_or_null(); 33.42 if (k != NULL) { 33.43 // Ignore mark word because it may have been used to
34.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp Sat Oct 24 16:18:50 2020 +0800 34.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp Sat Oct 24 16:43:47 2020 +0800 34.3 @@ -3096,7 +3096,10 @@ 34.4 } 34.5 34.6 void do_object_work(oop obj) { 34.7 - guarantee(!_g1h->obj_in_cs(obj), 34.8 + guarantee(G1CMObjArrayProcessor::is_array_slice(obj) || obj->is_oop(), 34.9 + err_msg("Non-oop " PTR_FORMAT ", phase: %s, info: %d", 34.10 + p2i((void*) obj), phase_str(), _info)); 34.11 + guarantee(G1CMObjArrayProcessor::is_array_slice(obj) || !_g1h->obj_in_cs(obj), 34.12 err_msg("obj: " PTR_FORMAT " in CSet, phase: %s, info: %d", 34.13 p2i((void*) obj), phase_str(), _info)); 34.14 } 34.15 @@ -3506,18 +3509,25 @@ 34.16 template<bool scan> 34.17 inline void CMTask::process_grey_object(oop obj) { 34.18 assert(scan || obj->is_typeArray(), "Skipping scan of grey non-typeArray"); 34.19 - assert(_nextMarkBitMap->isMarked((HeapWord*) obj), "invariant"); 34.20 34.21 if (_cm->verbose_high()) { 34.22 gclog_or_tty->print_cr("[%u] processing grey object " PTR_FORMAT, 34.23 _worker_id, p2i((void*) obj)); 34.24 } 34.25 34.26 - size_t obj_size = obj->size(); 34.27 - _words_scanned += obj_size; 34.28 + assert(G1CMObjArrayProcessor::is_array_slice(obj) || _nextMarkBitMap->isMarked((HeapWord*) obj), 34.29 + "Any stolen object should be a slice or marked"); 34.30 34.31 if (scan) { 34.32 - obj->oop_iterate(_cm_oop_closure); 34.33 + if (G1CMObjArrayProcessor::is_array_slice(obj)) { 34.34 + _words_scanned += _objArray_processor.process_slice(obj); 34.35 + } else if (G1CMObjArrayProcessor::should_be_sliced(obj)) { 34.36 + _words_scanned += _objArray_processor.process_obj(obj); 34.37 + } else { 34.38 + size_t obj_size = obj->size(); 34.39 + _words_scanned += obj_size; 34.40 + obj->oop_iterate(_cm_oop_closure);; 34.41 + } 34.42 } 34.43 statsOnly( ++_objs_scanned ); 34.44 check_limits(); 34.45 @@ -3877,6 +3887,8 @@ 34.46 _worker_id, n); 34.47 } 34.48 for (int i = 0; i < n; ++i) { 34.49 + assert(G1CMObjArrayProcessor::is_array_slice(buffer[i]) || buffer[i]->is_oop(), 34.50 + err_msg("Element " PTR_FORMAT " must be an array slice or oop", p2i(buffer[i]))); 34.51 bool success = _task_queue->push(buffer[i]); 34.52 // We only call this when the local queue is empty or under a 34.53 // given target limit. So, we do not expect this push to fail. 34.54 @@ -3895,7 +3907,9 @@ 34.55 } 34.56 34.57 void CMTask::drain_local_queue(bool partially) { 34.58 - if (has_aborted()) return; 34.59 + if (has_aborted()) { 34.60 + return; 34.61 + } 34.62 34.63 // Decide what the target size is, depending whether we're going to 34.64 // drain it partially (so that other tasks can steal if they run out 34.65 @@ -3923,10 +3937,6 @@ 34.66 p2i((void*) obj)); 34.67 } 34.68 34.69 - assert(_g1h->is_in_g1_reserved((HeapWord*) obj), "invariant" ); 34.70 - assert(!_g1h->is_on_master_free_list( 34.71 - _g1h->heap_region_containing((HeapWord*) obj)), "invariant"); 34.72 - 34.73 scan_object(obj); 34.74 34.75 if (_task_queue->size() <= target_size || has_aborted()) { 34.76 @@ -4427,8 +4437,6 @@ 34.77 34.78 statsOnly( ++_steals ); 34.79 34.80 - assert(_nextMarkBitMap->isMarked((HeapWord*) obj), 34.81 - "any stolen object should be marked"); 34.82 scan_object(obj); 34.83 34.84 // And since we're towards the end, let's totally drain the 34.85 @@ -4602,6 +4610,7 @@ 34.86 CMTaskQueueSet* task_queues) 34.87 : _g1h(G1CollectedHeap::heap()), 34.88 _worker_id(worker_id), _cm(cm), 34.89 + _objArray_processor(this), 34.90 _claimed(false), 34.91 _nextMarkBitMap(NULL), _hash_seed(17), 34.92 _task_queue(task_queue),
35.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp Sat Oct 24 16:18:50 2020 +0800 35.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp Sat Oct 24 16:43:47 2020 +0800 35.3 @@ -26,6 +26,7 @@ 35.4 #define SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_HPP 35.5 35.6 #include "classfile/javaClasses.hpp" 35.7 +#include "gc_implementation/g1/g1ConcurrentMarkObjArrayProcessor.hpp" 35.8 #include "gc_implementation/g1/heapRegionSet.hpp" 35.9 #include "gc_implementation/g1/g1RegionToSpaceMapper.hpp" 35.10 #include "gc_implementation/shared/gcId.hpp" 35.11 @@ -942,7 +943,7 @@ 35.12 words_scanned_period = 12*1024, 35.13 // the regular clock call is called once the number of visited 35.14 // references reaches this limit 35.15 - refs_reached_period = 384, 35.16 + refs_reached_period = 1024, 35.17 // initial value for the hash seed, used in the work stealing code 35.18 init_hash_seed = 17, 35.19 // how many entries will be transferred between global stack and 35.20 @@ -950,6 +951,8 @@ 35.21 global_stack_transfer_size = 16 35.22 }; 35.23 35.24 + G1CMObjArrayProcessor _objArray_processor; 35.25 + 35.26 uint _worker_id; 35.27 G1CollectedHeap* _g1h; 35.28 ConcurrentMark* _cm; 35.29 @@ -1110,6 +1113,9 @@ 35.30 template<bool scan> void process_grey_object(oop obj); 35.31 35.32 public: 35.33 + // Apply the closure on the given area of the objArray. Return the number of words 35.34 + // scanned. 35.35 + inline size_t scan_objArray(objArrayOop obj, MemRegion mr); 35.36 // It resets the task; it should be called right at the beginning of 35.37 // a marking phase. 35.38 void reset(CMBitMap* _nextMarkBitMap);
36.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp Sat Oct 24 16:18:50 2020 +0800 36.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp Sat Oct 24 16:43:47 2020 +0800 36.3 @@ -27,6 +27,7 @@ 36.4 36.5 #include "gc_implementation/g1/concurrentMark.hpp" 36.6 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" 36.7 +#include "gc_implementation/g1/g1ConcurrentMarkObjArrayProcessor.inline.hpp" 36.8 36.9 // Utility routine to set an exclusive range of cards on the given 36.10 // card liveness bitmap 36.11 @@ -224,11 +225,11 @@ 36.12 36.13 inline void CMTask::push(oop obj) { 36.14 HeapWord* objAddr = (HeapWord*) obj; 36.15 - assert(_g1h->is_in_g1_reserved(objAddr), "invariant"); 36.16 - assert(!_g1h->is_on_master_free_list( 36.17 + assert(G1CMObjArrayProcessor::is_array_slice(obj) || _g1h->is_in_g1_reserved(objAddr), "invariant"); 36.18 + assert(G1CMObjArrayProcessor::is_array_slice(obj) || !_g1h->is_on_master_free_list( 36.19 _g1h->heap_region_containing((HeapWord*) objAddr)), "invariant"); 36.20 - assert(!_g1h->is_obj_ill(obj), "invariant"); 36.21 - assert(_nextMarkBitMap->isMarked(objAddr), "invariant"); 36.22 + assert(G1CMObjArrayProcessor::is_array_slice(obj) || !_g1h->is_obj_ill(obj), "invariant"); 36.23 + assert(G1CMObjArrayProcessor::is_array_slice(obj) || _nextMarkBitMap->isMarked(objAddr), "invariant"); 36.24 36.25 if (_cm->verbose_high()) { 36.26 gclog_or_tty->print_cr("[%u] pushing " PTR_FORMAT, _worker_id, p2i((void*) obj)); 36.27 @@ -365,6 +366,11 @@ 36.28 } 36.29 } 36.30 36.31 +inline size_t CMTask::scan_objArray(objArrayOop obj, MemRegion mr) { 36.32 + obj->oop_iterate(_cm_oop_closure, mr); 36.33 + return mr.word_size(); 36.34 +} 36.35 + 36.36 inline void ConcurrentMark::markPrev(oop p) { 36.37 assert(!_prevMarkBitMap->isMarked((HeapWord*) p), "sanity"); 36.38 // Note we are overriding the read-only view of the prev map here, via
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/src/share/vm/gc_implementation/g1/g1ConcurrentMarkObjArrayProcessor.cpp Sat Oct 24 16:43:47 2020 +0800 37.3 @@ -0,0 +1,87 @@ 37.4 +/* 37.5 + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 37.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 37.7 + * 37.8 + * This code is free software; you can redistribute it and/or modify it 37.9 + * under the terms of the GNU General Public License version 2 only, as 37.10 + * published by the Free Software Foundation. 37.11 + * 37.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 37.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 37.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 37.15 + * version 2 for more details (a copy is included in the LICENSE file that 37.16 + * accompanied this code). 37.17 + * 37.18 + * You should have received a copy of the GNU General Public License version 37.19 + * 2 along with this work; if not, write to the Free Software Foundation, 37.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 37.21 + * 37.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 37.23 + * or visit www.oracle.com if you need additional information or have any 37.24 + * questions. 37.25 + * 37.26 + */ 37.27 + 37.28 +#include "precompiled.hpp" 37.29 +#include "gc_implementation/g1/concurrentMark.inline.hpp" 37.30 +#include "gc_implementation/g1/g1ConcurrentMarkObjArrayProcessor.inline.hpp" 37.31 + 37.32 +oop G1CMObjArrayProcessor::encode_array_slice(HeapWord* addr) { 37.33 + return oop((void*)((uintptr_t)addr | ArraySliceBit)); 37.34 +} 37.35 + 37.36 +HeapWord* G1CMObjArrayProcessor::decode_array_slice(oop value) { 37.37 + assert(is_array_slice(value), err_msg("Given value " PTR_FORMAT " is not an array slice", p2i(value))); 37.38 + return (HeapWord*)((uintptr_t)(void*)value & ~ArraySliceBit); 37.39 +} 37.40 + 37.41 +void G1CMObjArrayProcessor::push_array_slice(HeapWord* what) { 37.42 + oop obj = encode_array_slice(what); 37.43 + _task->push(obj); 37.44 +} 37.45 + 37.46 +size_t G1CMObjArrayProcessor::process_array_slice(objArrayOop obj, HeapWord* start_from, size_t remaining) { 37.47 + size_t words_to_scan = MIN2(remaining, ObjArrayMarkingStride); 37.48 + 37.49 + if (remaining > ObjArrayMarkingStride) { 37.50 + push_array_slice(start_from + ObjArrayMarkingStride); 37.51 + } 37.52 + 37.53 + // Then process current area. 37.54 + MemRegion mr(start_from, words_to_scan); 37.55 + return _task->scan_objArray(obj, mr); 37.56 +} 37.57 + 37.58 +size_t G1CMObjArrayProcessor::process_obj(oop obj) { 37.59 + assert(should_be_sliced(obj), err_msg("Must be an array object %d and large " SIZE_FORMAT, obj->is_objArray(), (size_t)obj->size())); 37.60 + 37.61 + return process_array_slice(objArrayOop(obj), (HeapWord*)obj, (size_t)objArrayOop(obj)->size()); 37.62 +} 37.63 + 37.64 +size_t G1CMObjArrayProcessor::process_slice(oop obj) { 37.65 + HeapWord* const decoded_address = decode_array_slice(obj); 37.66 + 37.67 + // Find the start address of the objArrayOop. 37.68 + // Shortcut the BOT access if the given address is from a humongous object. The BOT 37.69 + // slide is fast enough for "smaller" objects in non-humongous regions, but is slower 37.70 + // than directly using heap region table. 37.71 + G1CollectedHeap* g1h = G1CollectedHeap::heap(); 37.72 + HeapRegion* r = g1h->heap_region_containing(decoded_address); 37.73 + 37.74 + HeapWord* const start_address = r->isHumongous() ? 37.75 + r->humongous_start_region()->bottom() : 37.76 + g1h->block_start(decoded_address); 37.77 + 37.78 + assert(oop(start_address)->is_objArray(), err_msg("Address " PTR_FORMAT " does not refer to an object array ", p2i(start_address))); 37.79 + assert(start_address < decoded_address, 37.80 + err_msg("Object start address " PTR_FORMAT " must be smaller than decoded address " PTR_FORMAT, 37.81 + p2i(start_address), 37.82 + p2i(decoded_address))); 37.83 + 37.84 + objArrayOop objArray = objArrayOop(start_address); 37.85 + 37.86 + size_t already_scanned = decoded_address - start_address; 37.87 + size_t remaining = objArray->size() - already_scanned; 37.88 + 37.89 + return process_array_slice(objArray, decoded_address, remaining); 37.90 +}
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/src/share/vm/gc_implementation/g1/g1ConcurrentMarkObjArrayProcessor.hpp Sat Oct 24 16:43:47 2020 +0800 38.3 @@ -0,0 +1,70 @@ 38.4 +/* 38.5 + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 38.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 38.7 + * 38.8 + * This code is free software; you can redistribute it and/or modify it 38.9 + * under the terms of the GNU General Public License version 2 only, as 38.10 + * published by the Free Software Foundation. 38.11 + * 38.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 38.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 38.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 38.15 + * version 2 for more details (a copy is included in the LICENSE file that 38.16 + * accompanied this code). 38.17 + * 38.18 + * You should have received a copy of the GNU General Public License version 38.19 + * 2 along with this work; if not, write to the Free Software Foundation, 38.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 38.21 + * 38.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 38.23 + * or visit www.oracle.com if you need additional information or have any 38.24 + * questions. 38.25 + * 38.26 + */ 38.27 + 38.28 +#ifndef SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_HPP 38.29 +#define SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_HPP 38.30 + 38.31 +#include "oops/oopsHierarchy.hpp" 38.32 +#include "memory/allocation.hpp" 38.33 + 38.34 +class CMTask; 38.35 + 38.36 +// Helper class to mark through large objArrays during marking in an efficient way. 38.37 +// Instead of pushing large object arrays, we push continuations onto the 38.38 +// mark stack. These continuations are identified by having their LSB set. 38.39 +// This allows incremental processing of large objects. 38.40 +class G1CMObjArrayProcessor VALUE_OBJ_CLASS_SPEC { 38.41 +private: 38.42 + // The bit mask for the continuation indicator of elements on the mark stack. 38.43 + static const size_t ArraySliceBit = 1; 38.44 + 38.45 + // Reference to the task for doing the actual work. 38.46 + CMTask* _task; 38.47 + 38.48 + // Encodes the given address as a continuation "oop". 38.49 + oop encode_array_slice(HeapWord* addr); 38.50 + // Remove the continuation marker from the given oop from the mark stack. 38.51 + HeapWord* decode_array_slice(oop value); 38.52 + 38.53 + // Push the continuation at the given address onto the mark stack. 38.54 + void push_array_slice(HeapWord* addr); 38.55 + 38.56 + // Process (apply the closure) on the given continuation of the given objArray. 38.57 + size_t process_array_slice(objArrayOop const obj, HeapWord* start_from, size_t remaining); 38.58 +public: 38.59 + static bool is_array_slice(void* obj) { return ((uintptr_t)obj & ArraySliceBit) != 0; } 38.60 + 38.61 + static bool should_be_sliced(oop obj); 38.62 + 38.63 + G1CMObjArrayProcessor(CMTask* task) : _task(task) { 38.64 + } 38.65 + 38.66 + // Process the given continuation "oop". Returns the number of words scanned. 38.67 + size_t process_slice(oop obj); 38.68 + // Start processing the given objArrayOop by scanning the header and pushing its 38.69 + // continuation. 38.70 + size_t process_obj(oop obj); 38.71 +}; 38.72 + 38.73 +#endif /* SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_HPP */
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/src/share/vm/gc_implementation/g1/g1ConcurrentMarkObjArrayProcessor.inline.hpp Sat Oct 24 16:43:47 2020 +0800 39.3 @@ -0,0 +1,36 @@ 39.4 +/* 39.5 + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 39.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 39.7 + * 39.8 + * This code is free software; you can redistribute it and/or modify it 39.9 + * under the terms of the GNU General Public License version 2 only, as 39.10 + * published by the Free Software Foundation. 39.11 + * 39.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 39.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 39.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 39.15 + * version 2 for more details (a copy is included in the LICENSE file that 39.16 + * accompanied this code). 39.17 + * 39.18 + * You should have received a copy of the GNU General Public License version 39.19 + * 2 along with this work; if not, write to the Free Software Foundation, 39.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 39.21 + * 39.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 39.23 + * or visit www.oracle.com if you need additional information or have any 39.24 + * questions. 39.25 + * 39.26 + */ 39.27 + 39.28 +#ifndef SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_INLINE_HPP 39.29 +#define SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_INLINE_HPP 39.30 + 39.31 +#include "oops/oop.inline.hpp" 39.32 +#include "oops/oopsHierarchy.hpp" 39.33 +#include "runtime/globals.hpp" 39.34 + 39.35 +inline bool G1CMObjArrayProcessor::should_be_sliced(oop obj) { 39.36 + return obj->is_objArray() && ((size_t)((objArrayOop)obj)->size()) >= 2 * ObjArrayMarkingStride; 39.37 +} 39.38 + 39.39 +#endif /* SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_INLINE_HPP */
40.1 --- a/src/share/vm/gc_implementation/g1/g1StringDedupTable.cpp Sat Oct 24 16:18:50 2020 +0800 40.2 +++ b/src/share/vm/gc_implementation/g1/g1StringDedupTable.cpp Sat Oct 24 16:43:47 2020 +0800 40.3 @@ -215,7 +215,7 @@ 40.4 uintx G1StringDedupTable::_resize_count = 0; 40.5 uintx G1StringDedupTable::_rehash_count = 0; 40.6 40.7 -G1StringDedupTable::G1StringDedupTable(size_t size, jint hash_seed) : 40.8 +G1StringDedupTable::G1StringDedupTable(size_t size, uint64_t hash_seed) : 40.9 _size(size), 40.10 _entries(0), 40.11 _grow_threshold((uintx)(size * _grow_load_factor)), 40.12 @@ -319,9 +319,8 @@ 40.13 if (use_java_hash()) { 40.14 hash = java_lang_String::hash_code(data, length); 40.15 } else { 40.16 - hash = AltHashing::murmur3_32(_table->_hash_seed, data, length); 40.17 + hash = AltHashing::halfsiphash_32(_table->_hash_seed, (const uint16_t*)data, length); 40.18 } 40.19 - 40.20 return hash; 40.21 } 40.22 40.23 @@ -600,7 +599,7 @@ 40.24 " [Size: " SIZE_FORMAT ", Min: " SIZE_FORMAT ", Max: " SIZE_FORMAT "]\n" 40.25 " [Entries: " UINTX_FORMAT ", Load: " G1_STRDEDUP_PERCENT_FORMAT_NS ", Cached: " UINTX_FORMAT ", Added: " UINTX_FORMAT ", Removed: " UINTX_FORMAT "]\n" 40.26 " [Resize Count: " UINTX_FORMAT ", Shrink Threshold: " UINTX_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT_NS "), Grow Threshold: " UINTX_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT_NS ")]\n" 40.27 - " [Rehash Count: " UINTX_FORMAT ", Rehash Threshold: " UINTX_FORMAT ", Hash Seed: 0x%x]\n" 40.28 + " [Rehash Count: " UINTX_FORMAT ", Rehash Threshold: " UINTX_FORMAT ", Hash Seed: " UINT64_FORMAT "]\n" 40.29 " [Age Threshold: " UINTX_FORMAT "]", 40.30 G1_STRDEDUP_BYTES_PARAM(_table->_size * sizeof(G1StringDedupEntry*) + (_table->_entries + _entry_cache->size()) * sizeof(G1StringDedupEntry)), 40.31 _table->_size, _min_size, _max_size,
41.1 --- a/src/share/vm/gc_implementation/g1/g1StringDedupTable.hpp Sat Oct 24 16:18:50 2020 +0800 41.2 +++ b/src/share/vm/gc_implementation/g1/g1StringDedupTable.hpp Sat Oct 24 16:43:47 2020 +0800 41.3 @@ -38,8 +38,8 @@ 41.4 class G1StringDedupEntry : public CHeapObj<mtGC> { 41.5 private: 41.6 G1StringDedupEntry* _next; 41.7 - unsigned int _hash; 41.8 - typeArrayOop _obj; 41.9 + unsigned int _hash; 41.10 + typeArrayOop _obj; 41.11 41.12 public: 41.13 G1StringDedupEntry() : 41.14 @@ -119,8 +119,8 @@ 41.15 // The hash seed also dictates which hash function to use. A 41.16 // zero hash seed means we will use the Java compatible hash 41.17 // function (which doesn't use a seed), and a non-zero hash 41.18 - // seed means we use the murmur3 hash function. 41.19 - jint _hash_seed; 41.20 + // seed means we use the murmur3 and better hash function. 41.21 + uint64_t _hash_seed; 41.22 41.23 // Constants governing table resize/rehash/cache. 41.24 static const size_t _min_size; 41.25 @@ -137,7 +137,7 @@ 41.26 static uintx _resize_count; 41.27 static uintx _rehash_count; 41.28 41.29 - G1StringDedupTable(size_t size, jint hash_seed = 0); 41.30 + G1StringDedupTable(size_t size, uint64_t hash_seed = 0); 41.31 ~G1StringDedupTable(); 41.32 41.33 // Returns the hash bucket at the given index.
42.1 --- a/src/share/vm/interpreter/interpreterRuntime.cpp Sat Oct 24 16:18:50 2020 +0800 42.2 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Sat Oct 24 16:43:47 2020 +0800 42.3 @@ -456,9 +456,18 @@ 42.4 42.5 // tracing 42.6 if (TraceExceptions) { 42.7 - ttyLocker ttyl; 42.8 ResourceMark rm(thread); 42.9 - tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", h_exception->print_value_string(), (address)h_exception()); 42.10 + Symbol* message = java_lang_Throwable::detail_message(h_exception()); 42.11 + ttyLocker ttyl; // Lock after getting the detail message 42.12 + if (message != NULL) { 42.13 + tty->print_cr("Exception <%s: %s> (" INTPTR_FORMAT ")", 42.14 + h_exception->print_value_string(), message->as_C_string(), 42.15 + (address)h_exception()); 42.16 + } else { 42.17 + tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", 42.18 + h_exception->print_value_string(), 42.19 + (address)h_exception()); 42.20 + } 42.21 tty->print_cr(" thrown in interpreter method <%s>", h_method->print_value_string()); 42.22 tty->print_cr(" at bci %d for thread " INTPTR_FORMAT, current_bci, thread); 42.23 }
43.1 --- a/src/share/vm/jfr/instrumentation/jfrJvmtiAgent.cpp Sat Oct 24 16:18:50 2020 +0800 43.2 +++ b/src/share/vm/jfr/instrumentation/jfrJvmtiAgent.cpp Sat Oct 24 16:43:47 2020 +0800 43.3 @@ -1,5 +1,5 @@ 43.4 /* 43.5 - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. 43.6 + * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. 43.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 43.8 * 43.9 * This code is free software; you can redistribute it and/or modify it 43.10 @@ -31,9 +31,7 @@ 43.11 #include "jfr/recorder/service/jfrOptionSet.hpp" 43.12 #include "jfr/support/jfrEventClass.hpp" 43.13 #include "memory/resourceArea.hpp" 43.14 -#include "prims/jvmtiEnvBase.hpp" 43.15 #include "prims/jvmtiExport.hpp" 43.16 -#include "prims/jvmtiUtil.hpp" 43.17 #include "runtime/interfaceSupport.hpp" 43.18 #include "runtime/thread.inline.hpp" 43.19 #include "utilities/exceptions.hpp" 43.20 @@ -53,17 +51,19 @@ 43.21 } 43.22 } 43.23 43.24 -static bool set_event_notification_mode(jvmtiEventMode mode, 43.25 - jvmtiEvent event, 43.26 - jthread event_thread, 43.27 - ...) { 43.28 - assert(jfr_jvmti_env != NULL, "invariant"); 43.29 +static jvmtiError set_event_notification_mode(jvmtiEventMode mode, 43.30 + jvmtiEvent event, 43.31 + jthread event_thread, 43.32 + ...) { 43.33 + if (jfr_jvmti_env == NULL) { 43.34 + return JVMTI_ERROR_NONE; 43.35 + } 43.36 const jvmtiError jvmti_ret_code = jfr_jvmti_env->SetEventNotificationMode(mode, event, event_thread); 43.37 check_jvmti_error(jfr_jvmti_env, jvmti_ret_code, "SetEventNotificationMode"); 43.38 - return jvmti_ret_code == JVMTI_ERROR_NONE; 43.39 + return jvmti_ret_code; 43.40 } 43.41 43.42 -static bool update_class_file_load_hook_event(jvmtiEventMode mode) { 43.43 +static jvmtiError update_class_file_load_hook_event(jvmtiEventMode mode) { 43.44 return set_event_notification_mode(mode, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL); 43.45 } 43.46 43.47 @@ -116,23 +116,12 @@ 43.48 return classes; 43.49 } 43.50 43.51 -// caller needs ResourceMark 43.52 -static void log_and_throw(jvmtiError error, TRAPS) { 43.53 +static void log_and_throw(TRAPS) { 43.54 if (!HAS_PENDING_EXCEPTION) { 43.55 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(THREAD)); 43.56 ThreadInVMfromNative tvmfn((JavaThread*)THREAD); 43.57 - const char base_error_msg[] = "JfrJvmtiAgent::retransformClasses failed: "; 43.58 - size_t length = sizeof base_error_msg; // includes terminating null 43.59 - const char* const jvmti_error_name = JvmtiUtil::error_name(error); 43.60 - assert(jvmti_error_name != NULL, "invariant"); 43.61 - length += strlen(jvmti_error_name); 43.62 - char* error_msg = NEW_RESOURCE_ARRAY(char, length); 43.63 - jio_snprintf(error_msg, length, "%s%s", base_error_msg, jvmti_error_name); 43.64 - if (JVMTI_ERROR_INVALID_CLASS_FORMAT == error) { 43.65 - JfrJavaSupport::throw_class_format_error(error_msg, THREAD); 43.66 - } else { 43.67 - JfrJavaSupport::throw_runtime_exception(error_msg, THREAD); 43.68 - } 43.69 + if (true) tty->print_cr("JfrJvmtiAgent::retransformClasses failed"); 43.70 + JfrJavaSupport::throw_class_format_error("JfrJvmtiAgent::retransformClasses failed", THREAD); 43.71 } 43.72 } 43.73 43.74 @@ -147,15 +136,12 @@ 43.75 } 43.76 } 43.77 43.78 -static bool is_valid_jvmti_phase() { 43.79 - return JvmtiEnvBase::get_phase() == JVMTI_PHASE_LIVE; 43.80 -} 43.81 - 43.82 void JfrJvmtiAgent::retransform_classes(JNIEnv* env, jobjectArray classes_array, TRAPS) { 43.83 assert(env != NULL, "invariant"); 43.84 - assert(classes_array != NULL, "invariant"); 43.85 - assert(is_valid_jvmti_phase(), "invariant"); 43.86 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(THREAD)); 43.87 + if (classes_array == NULL) { 43.88 + return; 43.89 + } 43.90 const jint classes_count = env->GetArrayLength(classes_array); 43.91 if (classes_count <= 0) { 43.92 return; 43.93 @@ -166,27 +152,27 @@ 43.94 for (jint i = 0; i < classes_count; i++) { 43.95 jclass clz = (jclass)env->GetObjectArrayElement(classes_array, i); 43.96 check_exception_and_log(env, THREAD); 43.97 - classes[i] = clz; 43.98 - } 43.99 - { 43.100 + 43.101 // inspecting the oop/klass requires a thread transition 43.102 - ThreadInVMfromNative transition((JavaThread*)THREAD); 43.103 - for (jint i = 0; i < classes_count; ++i) { 43.104 - jclass clz = classes[i]; 43.105 - if (!JdkJfrEvent::is_a(clz)) { 43.106 + { 43.107 + ThreadInVMfromNative transition((JavaThread*)THREAD); 43.108 + if (JdkJfrEvent::is_a(clz)) { 43.109 + // should have been tagged already 43.110 + assert(JdkJfrEvent::is_subklass(clz), "invariant"); 43.111 + } else { 43.112 // outside the event hierarchy 43.113 JdkJfrEvent::tag_as_host(clz); 43.114 } 43.115 } 43.116 + 43.117 + classes[i] = clz; 43.118 } 43.119 - DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(THREAD)); 43.120 - const jvmtiError result = jfr_jvmti_env->RetransformClasses(classes_count, classes); 43.121 - if (result != JVMTI_ERROR_NONE) { 43.122 - log_and_throw(result, THREAD); 43.123 + if (jfr_jvmti_env->RetransformClasses(classes_count, classes) != JVMTI_ERROR_NONE) { 43.124 + log_and_throw(THREAD); 43.125 } 43.126 } 43.127 43.128 -static bool register_callbacks(JavaThread* jt) { 43.129 +static jvmtiError register_callbacks(JavaThread* jt) { 43.130 assert(jfr_jvmti_env != NULL, "invariant"); 43.131 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(jt)); 43.132 jvmtiEventCallbacks callbacks; 43.133 @@ -195,10 +181,10 @@ 43.134 callbacks.ClassFileLoadHook = jfr_on_class_file_load_hook; 43.135 const jvmtiError jvmti_ret_code = jfr_jvmti_env->SetEventCallbacks(&callbacks, sizeof(callbacks)); 43.136 check_jvmti_error(jfr_jvmti_env, jvmti_ret_code, "SetEventCallbacks"); 43.137 - return jvmti_ret_code == JVMTI_ERROR_NONE; 43.138 + return jvmti_ret_code; 43.139 } 43.140 43.141 -static bool register_capabilities(JavaThread* jt) { 43.142 +static jvmtiError register_capabilities(JavaThread* jt) { 43.143 assert(jfr_jvmti_env != NULL, "invariant"); 43.144 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(jt)); 43.145 jvmtiCapabilities capabilities; 43.146 @@ -208,7 +194,7 @@ 43.147 capabilities.can_retransform_any_class = 1; 43.148 const jvmtiError jvmti_ret_code = jfr_jvmti_env->AddCapabilities(&capabilities); 43.149 check_jvmti_error(jfr_jvmti_env, jvmti_ret_code, "Add Capabilities"); 43.150 - return jvmti_ret_code == JVMTI_ERROR_NONE; 43.151 + return jvmti_ret_code; 43.152 } 43.153 43.154 static jint create_jvmti_env(JavaThread* jt) { 43.155 @@ -219,14 +205,16 @@ 43.156 return vm->GetEnv((void **)&jfr_jvmti_env, JVMTI_VERSION); 43.157 } 43.158 43.159 -static bool unregister_callbacks(JavaThread* jt) { 43.160 - assert(jfr_jvmti_env != NULL, "invariant"); 43.161 +static jvmtiError unregister_callbacks(JavaThread* jt) { 43.162 + if (jfr_jvmti_env == NULL) { 43.163 + return JVMTI_ERROR_NONE; 43.164 + } 43.165 jvmtiEventCallbacks callbacks; 43.166 /* Set empty callbacks */ 43.167 memset(&callbacks, 0, sizeof(callbacks)); 43.168 const jvmtiError jvmti_ret_code = jfr_jvmti_env->SetEventCallbacks(&callbacks, sizeof(callbacks)); 43.169 check_jvmti_error(jfr_jvmti_env, jvmti_ret_code, "SetEventCallbacks"); 43.170 - return jvmti_ret_code == JVMTI_ERROR_NONE; 43.171 + return jvmti_ret_code; 43.172 } 43.173 43.174 JfrJvmtiAgent::JfrJvmtiAgent() {} 43.175 @@ -234,17 +222,20 @@ 43.176 JfrJvmtiAgent::~JfrJvmtiAgent() { 43.177 JavaThread* jt = current_java_thread(); 43.178 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(jt)); 43.179 + ThreadToNativeFromVM transition(jt); 43.180 + update_class_file_load_hook_event(JVMTI_DISABLE); 43.181 + unregister_callbacks(jt); 43.182 if (jfr_jvmti_env != NULL) { 43.183 - ThreadToNativeFromVM transition(jt); 43.184 - update_class_file_load_hook_event(JVMTI_DISABLE); 43.185 - unregister_callbacks(jt); 43.186 jfr_jvmti_env->DisposeEnvironment(); 43.187 jfr_jvmti_env = NULL; 43.188 } 43.189 + agent = NULL; 43.190 } 43.191 43.192 -static bool initialize(JavaThread* jt) { 43.193 +static bool initialize() { 43.194 + JavaThread* const jt = current_java_thread(); 43.195 assert(jt != NULL, "invariant"); 43.196 + assert(jt->thread_state() == _thread_in_vm, "invariant"); 43.197 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(jt)); 43.198 ThreadToNativeFromVM transition(jt); 43.199 if (create_jvmti_env(jt) != JNI_OK) { 43.200 @@ -252,38 +243,25 @@ 43.201 return false; 43.202 } 43.203 assert(jfr_jvmti_env != NULL, "invariant"); 43.204 - if (!register_capabilities(jt)) { 43.205 + if (register_capabilities(jt) != JVMTI_ERROR_NONE) { 43.206 return false; 43.207 } 43.208 - if (!register_callbacks(jt)) { 43.209 + if (register_callbacks(jt) != JVMTI_ERROR_NONE) { 43.210 return false; 43.211 } 43.212 - return update_class_file_load_hook_event(JVMTI_ENABLE); 43.213 -} 43.214 - 43.215 -static void log_and_throw_illegal_state_exception(TRAPS) { 43.216 - DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD)); 43.217 - const char* const illegal_state_msg = "An attempt was made to start JFR too early in the VM initialization sequence."; 43.218 - if (true) { 43.219 - tty->print_cr("%s\n", illegal_state_msg); 43.220 - tty->print_cr("JFR uses JVMTI RetransformClasses and requires the JVMTI state to have entered JVMTI_PHASE_LIVE.\n"); 43.221 - tty->print_cr("Please initialize JFR in response to event JVMTI_EVENT_VM_INIT instead of JVMTI_EVENT_VM_START.\n"); 43.222 + if (update_class_file_load_hook_event(JVMTI_ENABLE) != JVMTI_ERROR_NONE) { 43.223 + return false; 43.224 } 43.225 - JfrJavaSupport::throw_illegal_state_exception(illegal_state_msg, THREAD); 43.226 + return true; 43.227 } 43.228 43.229 bool JfrJvmtiAgent::create() { 43.230 - assert(agent == NULL, "invariant"); 43.231 - JavaThread* const jt = current_java_thread(); 43.232 - if (!is_valid_jvmti_phase()) { 43.233 - log_and_throw_illegal_state_exception(jt); 43.234 - return false; 43.235 - } 43.236 + assert(jfr_jvmti_env == NULL, "invariant"); 43.237 agent = new JfrJvmtiAgent(); 43.238 if (agent == NULL) { 43.239 return false; 43.240 } 43.241 - if (!initialize(jt)) { 43.242 + if (!initialize()) { 43.243 delete agent; 43.244 agent = NULL; 43.245 return false; 43.246 @@ -297,3 +275,4 @@ 43.247 agent = NULL; 43.248 } 43.249 } 43.250 +
44.1 --- a/src/share/vm/jfr/jfr.cpp Sat Oct 24 16:18:50 2020 +0800 44.2 +++ b/src/share/vm/jfr/jfr.cpp Sat Oct 24 16:43:47 2020 +0800 44.3 @@ -32,7 +32,6 @@ 44.4 #include "jfr/recorder/service/jfrOptionSet.hpp" 44.5 #include "jfr/support/jfrThreadLocal.hpp" 44.6 #include "runtime/java.hpp" 44.7 -#include "utilities/defaultStream.hpp" 44.8 44.9 bool Jfr::is_enabled() { 44.10 return JfrRecorder::is_enabled(); 44.11 @@ -46,21 +45,15 @@ 44.12 return JfrRecorder::is_recording(); 44.13 } 44.14 44.15 -void Jfr::on_create_vm_1() { 44.16 - if (!JfrRecorder::on_create_vm_1()) { 44.17 - vm_exit_during_initialization("Failure when starting JFR on_create_vm_1"); 44.18 +void Jfr::on_vm_init() { 44.19 + if (!JfrRecorder::on_vm_init()) { 44.20 + vm_exit_during_initialization("Failure when starting JFR on_vm_init"); 44.21 } 44.22 } 44.23 44.24 -void Jfr::on_create_vm_2() { 44.25 - if (!JfrRecorder::on_create_vm_2()) { 44.26 - vm_exit_during_initialization("Failure when starting JFR on_create_vm_2"); 44.27 - } 44.28 -} 44.29 - 44.30 -void Jfr::on_create_vm_3() { 44.31 - if (!JfrRecorder::on_create_vm_3()) { 44.32 - vm_exit_during_initialization("Failure when starting JFR on_create_vm_3"); 44.33 +void Jfr::on_vm_start() { 44.34 + if (!JfrRecorder::on_vm_start()) { 44.35 + vm_exit_during_initialization("Failure when starting JFR on_vm_start"); 44.36 } 44.37 } 44.38
45.1 --- a/src/share/vm/jfr/jfr.hpp Sat Oct 24 16:18:50 2020 +0800 45.2 +++ b/src/share/vm/jfr/jfr.hpp Sat Oct 24 16:43:47 2020 +0800 45.3 @@ -43,9 +43,8 @@ 45.4 static bool is_enabled(); 45.5 static bool is_disabled(); 45.6 static bool is_recording(); 45.7 - static void on_create_vm_1(); 45.8 - static void on_create_vm_2(); 45.9 - static void on_create_vm_3(); 45.10 + static void on_vm_init(); 45.11 + static void on_vm_start(); 45.12 static void on_unloading_classes(); 45.13 static void on_thread_start(Thread* thread); 45.14 static void on_thread_exit(Thread* thread);
46.1 --- a/src/share/vm/jfr/jni/jfrJavaSupport.cpp Sat Oct 24 16:18:50 2020 +0800 46.2 +++ b/src/share/vm/jfr/jni/jfrJavaSupport.cpp Sat Oct 24 16:43:47 2020 +0800 46.3 @@ -515,10 +515,6 @@ 46.4 create_and_throw(vmSymbols::java_lang_ClassFormatError(), message, THREAD); 46.5 } 46.6 46.7 -void JfrJavaSupport::throw_runtime_exception(const char* message, TRAPS) { 46.8 - create_and_throw(vmSymbols::java_lang_RuntimeException(), message, THREAD); 46.9 -} 46.10 - 46.11 void JfrJavaSupport::abort(jstring errorMsg, Thread* t) { 46.12 DEBUG_ONLY(check_java_thread_in_vm(t)); 46.13 46.14 @@ -574,10 +570,6 @@ 46.15 return _cause; 46.16 } 46.17 46.18 -// XXX 46.19 -//const char* const JDK_JFR_MODULE_NAME = "jdk.jfr"; 46.20 -//const char* const JDK_JFR_PACKAGE_NAME = "jdk/jfr"; 46.21 - 46.22 jlong JfrJavaSupport::jfr_thread_id(jobject target_thread) { 46.23 // ThreadsListHandle tlh; 46.24 // XXX is it correct and safe?
47.1 --- a/src/share/vm/jfr/jni/jfrJavaSupport.hpp Sat Oct 24 16:18:50 2020 +0800 47.2 +++ b/src/share/vm/jfr/jni/jfrJavaSupport.hpp Sat Oct 24 16:43:47 2020 +0800 47.3 @@ -81,7 +81,6 @@ 47.4 static void throw_internal_error(const char* message, TRAPS); 47.5 static void throw_out_of_memory_error(const char* message, TRAPS); 47.6 static void throw_class_format_error(const char* message, TRAPS); 47.7 - static void throw_runtime_exception(const char* message, TRAPS); 47.8 47.9 static jlong jfr_thread_id(jobject target_thread); 47.10
48.1 --- a/src/share/vm/jfr/jni/jfrJniMethod.cpp Sat Oct 24 16:18:50 2020 +0800 48.2 +++ b/src/share/vm/jfr/jni/jfrJniMethod.cpp Sat Oct 24 16:43:47 2020 +0800 48.3 @@ -191,9 +191,7 @@ 48.4 return JNI_TRUE; 48.5 } 48.6 if (!JfrRecorder::create(simulate_failure == JNI_TRUE)) { 48.7 - if (!thread->has_pending_exception()) { 48.8 - JfrJavaSupport::throw_illegal_state_exception("Unable to start Jfr", thread); 48.9 - } 48.10 + JfrJavaSupport::throw_illegal_state_exception("Unable to start Jfr", thread); 48.11 return JNI_FALSE; 48.12 } 48.13 return JNI_TRUE;
49.1 --- a/src/share/vm/jfr/metadata/metadata.xml Sat Oct 24 16:18:50 2020 +0800 49.2 +++ b/src/share/vm/jfr/metadata/metadata.xml Sat Oct 24 16:43:47 2020 +0800 49.3 @@ -725,19 +725,6 @@ 49.4 <Field type="ulong" contentType="address" name="topAddress" label="Top Address" description="Ending address of the module" /> 49.5 </Event> 49.6 49.7 - <!-- XXX 49.8 - <Event name="ModuleRequire" category="Java Virtual Machine, Runtime, Modules" label="Module Require" thread="false" period="everyChunk" 49.9 - description="A directed edge representing a dependency"> 49.10 - <Field type="Module" name="source" label="Source Module" /> 49.11 - <Field type="Module" name="requiredModule" label="Required Module" /> 49.12 - </Event> 49.13 - 49.14 - <Event name="ModuleExport" category="Java Virtual Machine, Runtime, Modules" label="Module Export" thread="false" period="everyChunk"> 49.15 - <Field type="Package" name="exportedPackage" label="Exported Package" /> 49.16 - <Field type="Module" name="targetModule" label="Target Module" 49.17 - description="Module to which the package is qualifiedly exported. If null or N/A, the package is unqualifiedly exported" /> 49.18 - </Event> 49.19 - --> 49.20 <Event name="CompilerStatistics" category="Java Virtual Machine, Compiler" label="Compiler Statistics" thread="false" period="everyChunk" startTime="false"> 49.21 <Field type="int" name="compileCount" label="Compiled Methods" /> 49.22 <Field type="int" name="bailoutCount" label="Bailouts" /> 49.23 @@ -1032,18 +1019,8 @@ 49.24 <Field type="string" name="cause" label="Cause" /> 49.25 </Type> 49.26 49.27 - <!-- 49.28 - <Type name="Module" label="Module"> 49.29 - <Field type="Symbol" name="name" label="Name" /> 49.30 - <Field type="Symbol" name="version" label="Version" /> 49.31 - <Field type="Symbol" name="location" label="Location" /> 49.32 - <Field type="ClassLoader" name="classLoader" label="Class Loader" /> 49.33 - </Type> 49.34 - --> 49.35 - 49.36 <Type name="Package" label="Package"> 49.37 <Field type="Symbol" name="name" label="Name" /> 49.38 - <!-- <Field type="Module" name="module" label="Module" /> --> 49.39 <Field type="boolean" name="exported" label="Exported" /> 49.40 </Type> 49.41 49.42 @@ -1107,7 +1084,6 @@ 49.43 <Relation name="CompileId" /> 49.44 <Relation name="SweepId"/> 49.45 49.46 - <XmlType name="Package" parameterType="const PackageEntry*" fieldType="const PackageEntry*"/> 49.47 <XmlType name="Class" javaType="java.lang.Class" parameterType="const Klass*" fieldType="const Klass*"/> 49.48 <XmlType name="ClassLoader" parameterType="const ClassLoaderData*" fieldType="const ClassLoaderData*"/> 49.49 <XmlType name="Method" parameterType="const Method*" fieldType="const Method*"/>
50.1 --- a/src/share/vm/jfr/periodic/jfrThreadCPULoadEvent.cpp Sat Oct 24 16:18:50 2020 +0800 50.2 +++ b/src/share/vm/jfr/periodic/jfrThreadCPULoadEvent.cpp Sat Oct 24 16:43:47 2020 +0800 50.3 @@ -86,15 +86,14 @@ 50.4 // Avoid reporting percentages above the theoretical max 50.5 if (user_time + system_time > wallclock_time) { 50.6 jlong excess = user_time + system_time - wallclock_time; 50.7 + cur_cpu_time -= excess; 50.8 if (user_time > excess) { 50.9 user_time -= excess; 50.10 cur_user_time -= excess; 50.11 - cur_cpu_time -= excess; 50.12 } else { 50.13 - cur_cpu_time -= excess; 50.14 excess -= user_time; 50.15 + cur_user_time -= user_time; 50.16 user_time = 0; 50.17 - cur_user_time = 0; 50.18 system_time -= excess; 50.19 } 50.20 }
51.1 --- a/src/share/vm/jfr/periodic/sampling/jfrCallTrace.cpp Sat Oct 24 16:18:50 2020 +0800 51.2 +++ b/src/share/vm/jfr/periodic/sampling/jfrCallTrace.cpp Sat Oct 24 16:43:47 2020 +0800 51.3 @@ -1,5 +1,5 @@ 51.4 /* 51.5 - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. 51.6 + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. 51.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 51.8 * 51.9 * This code is free software; you can redistribute it and/or modify it 51.10 @@ -27,6 +27,7 @@ 51.11 #include "code/nmethod.hpp" 51.12 #include "code/pcDesc.hpp" 51.13 #include "jfr/periodic/sampling/jfrCallTrace.hpp" 51.14 +#include "jfr/utilities/jfrTypes.hpp" 51.15 #include "oops/method.hpp" 51.16 #include "runtime/javaCalls.hpp" 51.17 #include "runtime/frame.inline.hpp" 51.18 @@ -37,7 +38,7 @@ 51.19 assert(top_frame.cb() != NULL, "invariant"); 51.20 RegisterMap map(_thread, false); 51.21 frame candidate = top_frame; 51.22 - for (int i = 0; i < MaxJavaStackTraceDepth * 2; ++i) { 51.23 + for (u4 i = 0; i < MAX_STACK_DEPTH * 2; ++i) { 51.24 if (candidate.is_entry_frame()) { 51.25 JavaCallWrapper *jcw = candidate.entry_frame_call_wrapper_if_safe(_thread); 51.26 if (jcw == NULL || jcw->is_first_frame()) {
52.1 --- a/src/share/vm/jfr/periodic/sampling/jfrThreadSampler.cpp Sat Oct 24 16:18:50 2020 +0800 52.2 +++ b/src/share/vm/jfr/periodic/sampling/jfrThreadSampler.cpp Sat Oct 24 16:43:47 2020 +0800 52.3 @@ -494,8 +494,8 @@ 52.4 last_native_ms = last_java_ms; 52.5 } 52.6 _sample.signal(); 52.7 - jlong java_interval = _interval_java == 0 ? max_jlong : MAX2<jlong>(_interval_java, 10); 52.8 - jlong native_interval = _interval_native == 0 ? max_jlong : MAX2<jlong>(_interval_native, 10); 52.9 + jlong java_interval = _interval_java == 0 ? max_jlong : MAX2<jlong>(_interval_java, 1); 52.10 + jlong native_interval = _interval_native == 0 ? max_jlong : MAX2<jlong>(_interval_native, 1); 52.11 52.12 jlong now_ms = get_monotonic_ms(); 52.13
53.1 --- a/src/share/vm/jfr/recorder/checkpoint/jfrCheckpointWriter.cpp Sat Oct 24 16:18:50 2020 +0800 53.2 +++ b/src/share/vm/jfr/recorder/checkpoint/jfrCheckpointWriter.cpp Sat Oct 24 16:43:47 2020 +0800 53.3 @@ -44,13 +44,13 @@ 53.4 } 53.5 } 53.6 53.7 -static void write_checkpoint_header(u1* pos, jlong size, jlong time, bool flushpoint, juint type_count) { 53.8 +static void write_checkpoint_header(u1* pos, int64_t size, jlong time, bool flushpoint, u4 type_count) { 53.9 assert(pos != NULL, "invariant"); 53.10 JfrBigEndianWriter be_writer(pos, sizeof(JfrCheckpointEntry)); 53.11 be_writer.write(size); 53.12 be_writer.write(time); 53.13 be_writer.write(JfrTicks::now().value() - time); 53.14 - be_writer.write(flushpoint ? (juint)1 : (juint)0); 53.15 + be_writer.write(flushpoint ? (u4)1 : (u4)0); 53.16 be_writer.write(type_count); 53.17 assert(be_writer.is_valid(), "invariant"); 53.18 } 53.19 @@ -71,7 +71,7 @@ 53.20 assert(this->is_valid(), "invariant"); 53.21 assert(count() > 0, "invariant"); 53.22 assert(this->used_size() > sizeof(JfrCheckpointEntry), "invariant"); 53.23 - const jlong size = this->current_offset(); 53.24 + const int64_t size = this->current_offset(); 53.25 assert(size + this->start_pos() == this->current_pos(), "invariant"); 53.26 write_checkpoint_header(const_cast<u1*>(this->start_pos()), size, _time, is_flushpoint(), count()); 53.27 release(); 53.28 @@ -85,11 +85,11 @@ 53.29 return _flushpoint; 53.30 } 53.31 53.32 -juint JfrCheckpointWriter::count() const { 53.33 +u4 JfrCheckpointWriter::count() const { 53.34 return _count; 53.35 } 53.36 53.37 -void JfrCheckpointWriter::set_count(juint count) { 53.38 +void JfrCheckpointWriter::set_count(u4 count) { 53.39 _count = count; 53.40 } 53.41 53.42 @@ -111,7 +111,7 @@ 53.43 } 53.44 53.45 void JfrCheckpointWriter::write_key(u8 key) { 53.46 - write<u8>(key); 53.47 + write(key); 53.48 } 53.49 53.50 void JfrCheckpointWriter::increment() { 53.51 @@ -119,10 +119,10 @@ 53.52 } 53.53 53.54 void JfrCheckpointWriter::write_count(u4 nof_entries) { 53.55 - write<u4>((u4)nof_entries); 53.56 + write(nof_entries); 53.57 } 53.58 53.59 -void JfrCheckpointWriter::write_count(u4 nof_entries, jlong offset) { 53.60 +void JfrCheckpointWriter::write_count(u4 nof_entries, int64_t offset) { 53.61 write_padded_at_offset(nof_entries, offset); 53.62 } 53.63
54.1 --- a/src/share/vm/jfr/recorder/checkpoint/jfrCheckpointWriter.hpp Sat Oct 24 16:18:50 2020 +0800 54.2 +++ b/src/share/vm/jfr/recorder/checkpoint/jfrCheckpointWriter.hpp Sat Oct 24 16:43:47 2020 +0800 54.3 @@ -49,21 +49,21 @@ 54.4 typedef EventWriterHost<BigEndianEncoder, CompressedIntegerEncoder, JfrTransactionalCheckpointWriter> JfrCheckpointWriterBase; 54.5 54.6 struct JfrCheckpointContext { 54.7 - jlong offset; 54.8 - juint count; 54.9 + int64_t offset; 54.10 + u4 count; 54.11 }; 54.12 54.13 class JfrCheckpointWriter : public JfrCheckpointWriterBase { 54.14 friend class JfrSerializerRegistration; 54.15 private: 54.16 JfrTicks _time; 54.17 - jlong _offset; 54.18 - juint _count; 54.19 + int64_t _offset; 54.20 + u4 _count; 54.21 bool _flushpoint; 54.22 bool _header; 54.23 54.24 - juint count() const; 54.25 - void set_count(juint count); 54.26 + u4 count() const; 54.27 + void set_count(u4 count); 54.28 void increment(); 54.29 void set_flushpoint(bool flushpoint); 54.30 bool is_flushpoint() const; 54.31 @@ -75,7 +75,7 @@ 54.32 ~JfrCheckpointWriter(); 54.33 void write_type(JfrTypeId type_id); 54.34 void write_count(u4 nof_entries); 54.35 - void write_count(u4 nof_entries, jlong offset); 54.36 + void write_count(u4 nof_entries, int64_t offset); 54.37 void write_key(u8 key); 54.38 const JfrCheckpointContext context() const; 54.39 void set_context(const JfrCheckpointContext ctx);
55.1 --- a/src/share/vm/jfr/recorder/checkpoint/types/jfrType.cpp Sat Oct 24 16:18:50 2020 +0800 55.2 +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrType.cpp Sat Oct 24 16:43:47 2020 +0800 55.3 @@ -64,7 +64,7 @@ 55.4 private: 55.5 JfrCheckpointWriter& _writer; 55.6 JfrCheckpointContext _ctx; 55.7 - const intptr_t _count_position; 55.8 + const int64_t _count_position; 55.9 Thread* const _curthread; 55.10 u4 _count; 55.11
56.1 --- a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.cpp Sat Oct 24 16:18:50 2020 +0800 56.2 +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.cpp Sat Oct 24 16:43:47 2020 +0800 56.3 @@ -25,7 +25,6 @@ 56.4 #include "precompiled.hpp" 56.5 #include "classfile/classLoaderData.inline.hpp" 56.6 #include "classfile/javaClasses.hpp" 56.7 -// XXX #include "classfile/packageEntry.hpp" 56.8 #include "classfile/symbolTable.hpp" 56.9 #include "classfile/systemDictionary.hpp" 56.10 #include "jfr/jfr.hpp" 56.11 @@ -55,7 +54,6 @@ 56.12 #define CREATE_PACKAGE_ID(pkg_id) (((u8)((checkpoint_id << 24) | pkg_id))) 56.13 56.14 typedef const Klass* KlassPtr; 56.15 -// XXX typedef const PackageEntry* PkgPtr; 56.16 typedef const ClassLoaderData* CldPtr; 56.17 typedef const Method* MethodPtr; 56.18 typedef const Symbol* SymbolPtr; 56.19 @@ -87,11 +85,6 @@ 56.20 56.21 static void tag_leakp_klass_artifacts(KlassPtr k, bool class_unload) { 56.22 assert(k != NULL, "invariant"); 56.23 - // XXX 56.24 - // PkgPtr pkg = k->package(); 56.25 - // if (pkg != NULL) { 56.26 - // tag_leakp_artifact(pkg, class_unload); 56.27 - // } 56.28 CldPtr cld = k->class_loader_data(); 56.29 assert(cld != NULL, "invariant"); 56.30 if (!cld->is_anonymous()) { 56.31 @@ -295,7 +288,6 @@ 56.32 UniquePredicate<traceid, _compare_traceid_> _unique_predicate; 56.33 56.34 int klass_symbols(KlassPtr klass); 56.35 -// XXX int package_symbols(PkgPtr pkg); 56.36 int class_loader_symbols(CldPtr cld); 56.37 int method_symbols(KlassPtr klass); 56.38 56.39 @@ -315,11 +307,6 @@ 56.40 int count = 0; 56.41 if (_predicate(klass)) { 56.42 count += klass_symbols(klass); 56.43 - // XXX 56.44 - // PkgPtr pkg = klass->package(); 56.45 - // if (pkg != NULL) { 56.46 - // count += package_symbols(pkg); 56.47 - // } 56.48 CldPtr cld = klass->class_loader_data(); 56.49 assert(cld != NULL, "invariant"); 56.50 if (!cld->is_anonymous()) { 56.51 @@ -349,52 +336,6 @@ 56.52 return _unique_predicate(entry->id()) ? write__artifact__symbol__entry__(this->_writer, entry) : 0; 56.53 } 56.54 56.55 -// XXX 56.56 -// template <template <typename> class Predicate> 56.57 -// int KlassSymbolWriterImpl<Predicate>::package_symbols(PkgPtr pkg) { 56.58 -// assert(pkg != NULL, "invariant"); 56.59 -// SymbolPtr pkg_name = pkg->name(); 56.60 -// assert(pkg_name != NULL, "invariant"); 56.61 -// SymbolEntryPtr package_symbol = this->_artifacts->map_symbol(pkg_name); 56.62 -// assert(package_symbol != NULL, "invariant"); 56.63 -// return _unique_predicate(package_symbol->id()) ? 56.64 -// write__artifact__symbol__entry__(this->_writer, package_symbol) : 0; 56.65 -// } 56.66 - 56.67 -// XXX 56.68 -// template <template <typename> class Predicate> 56.69 -// int KlassSymbolWriterImpl<Predicate>::module_symbols(ModPtr module) { 56.70 -// assert(module != NULL, "invariant"); 56.71 -// assert(module->is_named(), "invariant"); 56.72 -// int count = 0; 56.73 -// SymbolPtr sym = module->name(); 56.74 -// SymbolEntryPtr entry = NULL; 56.75 -// if (sym != NULL) { 56.76 -// entry = this->_artifacts->map_symbol(sym); 56.77 -// assert(entry != NULL, "invariant"); 56.78 -// if (_unique_predicate(entry->id())) { 56.79 -// count += write__artifact__symbol__entry__(this->_writer, entry); 56.80 -// } 56.81 -// } 56.82 -// sym = module->version(); 56.83 -// if (sym != NULL) { 56.84 -// entry = this->_artifacts->map_symbol(sym); 56.85 -// assert(entry != NULL, "invariant"); 56.86 -// if (_unique_predicate(entry->id())) { 56.87 -// count += write__artifact__symbol__entry__(this->_writer, entry); 56.88 -// } 56.89 -// } 56.90 -// sym = module->location(); 56.91 -// if (sym != NULL) { 56.92 -// entry = this->_artifacts->map_symbol(sym); 56.93 -// assert(entry != NULL, "invariant"); 56.94 -// if (_unique_predicate(entry->id())) { 56.95 -// count += write__artifact__symbol__entry__(this->_writer, entry); 56.96 -// } 56.97 -// } 56.98 -// return count; 56.99 -// } 56.100 - 56.101 template <template <typename> class Predicate> 56.102 int KlassSymbolWriterImpl<Predicate>::class_loader_symbols(CldPtr cld) { 56.103 assert(cld != NULL, "invariant"); 56.104 @@ -712,30 +653,6 @@ 56.105 ClassLoaderDataGraph::classes_do(&do_klass); 56.106 } 56.107 56.108 -// XXX 56.109 -// void JfrTypeSet::do_unloaded_package(PackageEntry* entry) { 56.110 -// assert(entry != NULL, "invariant"); 56.111 -// assert(_subsystem_callback != NULL, "invariant"); 56.112 -// if (ANY_USED_THIS_EPOCH(entry)) { // includes leakp subset 56.113 -// _subsystem_callback->do_artifact(entry); 56.114 -// } 56.115 -// } 56.116 - 56.117 -// void JfrTypeSet::do_package(PackageEntry* entry) { 56.118 -// assert(_subsystem_callback != NULL, "invariant"); 56.119 -// if (ANY_USED_PREV_EPOCH(entry)) { // includes leakp subset 56.120 -// _subsystem_callback->do_artifact(entry); 56.121 -// } 56.122 -// } 56.123 - 56.124 -// void JfrTypeSet::do_packages() { 56.125 -// if (_class_unload) { 56.126 -// ClassLoaderDataGraph::packages_unloading_do(&do_unloaded_package); 56.127 -// return; 56.128 -// } 56.129 -// ClassLoaderDataGraph::packages_do(&do_package); 56.130 -// } 56.131 - 56.132 void JfrTypeSet::do_unloaded_class_loader_data(ClassLoaderData* cld) { 56.133 assert(_subsystem_callback != NULL, "invariant"); 56.134 if (ANY_USED_THIS_EPOCH(cld)) { // includes leakp subset
57.1 --- a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.hpp Sat Oct 24 16:18:50 2020 +0800 57.2 +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.hpp Sat Oct 24 16:43:47 2020 +0800 57.3 @@ -33,8 +33,6 @@ 57.4 class JfrCheckpointWriter; 57.5 class Klass; 57.6 57.7 -// XXX class PackageEntry; 57.8 - 57.9 class JfrTypeSet : AllStatic { 57.10 friend class CLDCallback; 57.11 friend class JfrTypeManager; 57.12 @@ -48,11 +46,6 @@ 57.13 static void do_unloaded_klass(Klass* k); 57.14 static void do_klasses(); 57.15 57.16 - // XXX 57.17 - // static void do_package(PackageEntry* entry); 57.18 - // static void do_unloaded_package(PackageEntry* entry); 57.19 - // static void do_packages(); 57.20 - 57.21 static void do_class_loader_data(ClassLoaderData* cld); 57.22 static void do_unloaded_class_loader_data(ClassLoaderData* cld); 57.23 static void do_class_loaders();
58.1 --- a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSetWriter.hpp Sat Oct 24 16:18:50 2020 +0800 58.2 +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSetWriter.hpp Sat Oct 24 16:43:47 2020 +0800 58.3 @@ -35,7 +35,7 @@ 58.4 WriterImpl _impl; 58.5 JfrCheckpointWriter* _writer; 58.6 JfrCheckpointContext _ctx; 58.7 - jlong _count_offset; 58.8 + int64_t _count_offset; 58.9 int _count; 58.10 bool _skip_header; 58.11 public:
59.1 --- a/src/share/vm/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp Sat Oct 24 16:18:50 2020 +0800 59.2 +++ b/src/share/vm/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp Sat Oct 24 16:43:47 2020 +0800 59.3 @@ -61,12 +61,6 @@ 59.4 #endif 59.5 } 59.6 59.7 -// XXX 59.8 -// static traceid next_package_id() { 59.9 -// static volatile traceid package_id_counter = 1; 59.10 -// return atomic_inc(&package_id_counter) << TRACE_ID_SHIFT; 59.11 -// } 59.12 - 59.13 static traceid next_class_loader_data_id() { 59.14 static volatile traceid cld_id_counter = 1; 59.15 return atomic_inc(&cld_id_counter) << TRACE_ID_SHIFT; 59.16 @@ -104,12 +98,6 @@ 59.17 } 59.18 } 59.19 59.20 -// XXX 59.21 -// void JfrTraceId::assign(const PackageEntry* package) { 59.22 -// assert(package != NULL, "invariant"); 59.23 -// package->set_trace_id(next_package_id()); 59.24 -// } 59.25 - 59.26 void JfrTraceId::assign(const ClassLoaderData* cld) { 59.27 assert(cld != NULL, "invariant"); 59.28 if (cld->is_anonymous()) {
60.1 --- a/src/share/vm/jfr/recorder/checkpoint/types/traceid/jfrTraceId.hpp Sat Oct 24 16:18:50 2020 +0800 60.2 +++ b/src/share/vm/jfr/recorder/checkpoint/types/traceid/jfrTraceId.hpp Sat Oct 24 16:43:47 2020 +0800 60.3 @@ -32,7 +32,6 @@ 60.4 class ClassLoaderData; 60.5 class Klass; 60.6 class Method; 60.7 -// XXX class PackageEntry; 60.8 class Thread; 60.9 60.10 /* 60.11 @@ -54,7 +53,6 @@ 60.12 * 60.13 * Klass (includes Method) 60.14 * ClassLoaderData 60.15 - * XXX PackageEntry 60.16 * 60.17 * These classes have been extended to include a _traceid field (64-bits). 60.18 * 60.19 @@ -78,7 +76,6 @@ 60.20 class JfrTraceId : public AllStatic { 60.21 public: 60.22 static void assign(const Klass* klass); 60.23 - // XXX static void assign(const PackageEntry* package); 60.24 static void assign(const ClassLoaderData* cld); 60.25 static traceid assign_thread_id(); 60.26 60.27 @@ -90,7 +87,6 @@ 60.28 static traceid use(const Klass* klass, bool leakp = false); 60.29 static traceid use(jclass jc, bool leakp = false); 60.30 static traceid use(const Method* method, bool leakp = false); 60.31 - // XXX static traceid use(const PackageEntry* package, bool leakp = false); 60.32 static traceid use(const ClassLoaderData* cld, bool leakp = false); 60.33 60.34 static void remove(const Klass* klass);
61.1 --- a/src/share/vm/jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp Sat Oct 24 16:18:50 2020 +0800 61.2 +++ b/src/share/vm/jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp Sat Oct 24 16:43:47 2020 +0800 61.3 @@ -82,12 +82,6 @@ 61.4 return (METHOD_ID(klass, method)); 61.5 } 61.6 61.7 -// XXX 61.8 -//inline traceid JfrTraceId::use(const PackageEntry* package, bool leakp /* false */) { 61.9 -// assert(package != NULL, "invariant"); 61.10 -// return set_used_and_get_shifted(package, leakp); 61.11 -//} 61.12 - 61.13 inline traceid JfrTraceId::use(const ClassLoaderData* cld, bool leakp /* false */) { 61.14 assert(cld != NULL, "invariant"); 61.15 return cld->is_anonymous() ? 0 : set_used_and_get_shifted(cld, leakp);
62.1 --- a/src/share/vm/jfr/recorder/jfrRecorder.cpp Sat Oct 24 16:18:50 2020 +0800 62.2 +++ b/src/share/vm/jfr/recorder/jfrRecorder.cpp Sat Oct 24 16:43:47 2020 +0800 62.3 @@ -44,9 +44,6 @@ 62.4 #include "runtime/handles.inline.hpp" 62.5 #include "runtime/globals_extension.hpp" 62.6 #include "utilities/growableArray.hpp" 62.7 -#ifdef ASSERT 62.8 -#include "prims/jvmtiEnvBase.hpp" 62.9 -#endif 62.10 62.11 bool JfrRecorder::_shutting_down = false; 62.12 62.13 @@ -60,9 +57,7 @@ 62.14 62.15 static bool enable() { 62.16 assert(!_enabled, "invariant"); 62.17 - if (!FlightRecorder) { 62.18 - FLAG_SET_MGMT(bool, FlightRecorder, true); 62.19 - } 62.20 + FLAG_SET_MGMT(bool, FlightRecorder, true); 62.21 _enabled = FlightRecorder; 62.22 assert(_enabled, "invariant"); 62.23 return _enabled; 62.24 @@ -72,7 +67,7 @@ 62.25 return _enabled; 62.26 } 62.27 62.28 -bool JfrRecorder::on_create_vm_1() { 62.29 +bool JfrRecorder::on_vm_init() { 62.30 if (!is_disabled()) { 62.31 if (FlightRecorder || StartFlightRecording != NULL) { 62.32 enable(); 62.33 @@ -97,7 +92,7 @@ 62.34 62.35 static void teardown_startup_support() { 62.36 release_recordings(); 62.37 - JfrOptionSet::release_start_flight_recording_options(); 62.38 + JfrOptionSet::release_startup_recording_options(); 62.39 } 62.40 62.41 // Parsing options here to detect errors as soon as possible 62.42 @@ -115,7 +110,7 @@ 62.43 } 62.44 62.45 static bool validate_recording_options(TRAPS) { 62.46 - const GrowableArray<const char*>* options = JfrOptionSet::start_flight_recording_options(); 62.47 + const GrowableArray<const char*>* options = JfrOptionSet::startup_recording_options(); 62.48 if (options == NULL) { 62.49 return true; 62.50 } 62.51 @@ -148,7 +143,7 @@ 62.52 return true; 62.53 } 62.54 62.55 -static bool launch_command_line_recordings(TRAPS) { 62.56 +static bool launch_recordings(TRAPS) { 62.57 bool result = true; 62.58 if (dcmd_recordings_array != NULL) { 62.59 const int length = dcmd_recordings_array->length(); 62.60 @@ -166,7 +161,7 @@ 62.61 62.62 static bool is_cds_dump_requested() { 62.63 // we will not be able to launch recordings if a cds dump is being requested 62.64 - if (DumpSharedSpaces && (JfrOptionSet::start_flight_recording_options() != NULL)) { 62.65 + if (DumpSharedSpaces && (JfrOptionSet::startup_recording_options() != NULL)) { 62.66 warning("JFR will be disabled during CDS dumping"); 62.67 teardown_startup_support(); 62.68 return true; 62.69 @@ -174,7 +169,7 @@ 62.70 return false; 62.71 } 62.72 62.73 -bool JfrRecorder::on_create_vm_2() { 62.74 +bool JfrRecorder::on_vm_start() { 62.75 if (is_cds_dump_requested()) { 62.76 return true; 62.77 } 62.78 @@ -201,14 +196,10 @@ 62.79 if (!is_enabled()) { 62.80 return true; 62.81 } 62.82 - return true; 62.83 + 62.84 + return launch_recordings(thread); 62.85 } 62.86 62.87 -bool JfrRecorder::on_create_vm_3() { 62.88 - assert(JvmtiEnvBase::get_phase() == JVMTI_PHASE_LIVE, "invalid init sequence"); 62.89 - return launch_command_line_recordings(Thread::current()); 62.90 - } 62.91 - 62.92 static bool _created = false; 62.93 62.94 // 62.95 @@ -275,6 +266,7 @@ 62.96 } 62.97 62.98 // subsystems 62.99 +static JfrJvmtiAgent* _jvmti_agent = NULL; 62.100 static JfrPostBox* _post_box = NULL; 62.101 static JfrStorage* _storage = NULL; 62.102 static JfrCheckpointManager* _checkpoint_manager = NULL;
63.1 --- a/src/share/vm/jfr/recorder/jfrRecorder.hpp Sat Oct 24 16:18:50 2020 +0800 63.2 +++ b/src/share/vm/jfr/recorder/jfrRecorder.hpp Sat Oct 24 16:43:47 2020 +0800 63.3 @@ -40,9 +40,6 @@ 63.4 private: 63.5 static bool _shutting_down; 63.6 63.7 - static bool on_create_vm_1(); 63.8 - static bool on_create_vm_2(); 63.9 - static bool on_create_vm_3(); 63.10 static bool create_checkpoint_manager(); 63.11 static bool create_chunk_repository(); 63.12 static bool create_java_event_writer(); 63.13 @@ -57,6 +54,8 @@ 63.14 static bool create_components(); 63.15 static void destroy_components(); 63.16 static void on_recorder_thread_exit(); 63.17 + static bool on_vm_start(); 63.18 + static bool on_vm_init(); 63.19 63.20 public: 63.21 static bool is_enabled();
64.1 --- a/src/share/vm/jfr/recorder/repository/jfrChunkState.cpp Sat Oct 24 16:18:50 2020 +0800 64.2 +++ b/src/share/vm/jfr/recorder/repository/jfrChunkState.cpp Sat Oct 24 16:43:47 2020 +0800 64.3 @@ -52,19 +52,19 @@ 64.4 set_previous_checkpoint_offset(0); 64.5 } 64.6 64.7 -void JfrChunkState::set_previous_checkpoint_offset(jlong offset) { 64.8 +void JfrChunkState::set_previous_checkpoint_offset(int64_t offset) { 64.9 _previous_checkpoint_offset = offset; 64.10 } 64.11 64.12 -jlong JfrChunkState::previous_checkpoint_offset() const { 64.13 +int64_t JfrChunkState::previous_checkpoint_offset() const { 64.14 return _previous_checkpoint_offset; 64.15 } 64.16 64.17 -jlong JfrChunkState::previous_start_ticks() const { 64.18 +int64_t JfrChunkState::previous_start_ticks() const { 64.19 return _previous_start_ticks; 64.20 } 64.21 64.22 -jlong JfrChunkState::previous_start_nanos() const { 64.23 +int64_t JfrChunkState::previous_start_nanos() const { 64.24 return _previous_start_nanos; 64.25 } 64.26 64.27 @@ -91,7 +91,7 @@ 64.28 save_current_and_update_start_ticks(); 64.29 } 64.30 64.31 -jlong JfrChunkState::last_chunk_duration() const { 64.32 +int64_t JfrChunkState::last_chunk_duration() const { 64.33 return _start_nanos - _previous_start_nanos; 64.34 } 64.35
65.1 --- a/src/share/vm/jfr/recorder/repository/jfrChunkState.hpp Sat Oct 24 16:18:50 2020 +0800 65.2 +++ b/src/share/vm/jfr/recorder/repository/jfrChunkState.hpp Sat Oct 24 16:43:47 2020 +0800 65.3 @@ -25,7 +25,6 @@ 65.4 #ifndef SHARE_VM_JFR_RECORDER_REPOSITORY_JFRRCHUNKSTATE_HPP 65.5 #define SHARE_VM_JFR_RECORDER_REPOSITORY_JFRRCHUNKSTATE_HPP 65.6 65.7 -#include "jni.h" 65.8 #include "jfr/utilities/jfrAllocation.hpp" 65.9 #include "jfr/utilities/jfrTypes.hpp" 65.10 65.11 @@ -33,11 +32,11 @@ 65.12 friend class JfrChunkWriter; 65.13 private: 65.14 char* _path; 65.15 - jlong _start_ticks; 65.16 - jlong _start_nanos; 65.17 - jlong _previous_start_ticks; 65.18 - jlong _previous_start_nanos; 65.19 - jlong _previous_checkpoint_offset; 65.20 + int64_t _start_ticks; 65.21 + int64_t _start_nanos; 65.22 + int64_t _previous_start_ticks; 65.23 + int64_t _previous_start_nanos; 65.24 + int64_t _previous_checkpoint_offset; 65.25 65.26 void update_start_ticks(); 65.27 void update_start_nanos(); 65.28 @@ -47,11 +46,11 @@ 65.29 JfrChunkState(); 65.30 ~JfrChunkState(); 65.31 void reset(); 65.32 - jlong previous_checkpoint_offset() const; 65.33 - void set_previous_checkpoint_offset(jlong offset); 65.34 - jlong previous_start_ticks() const; 65.35 - jlong previous_start_nanos() const; 65.36 - jlong last_chunk_duration() const; 65.37 + int64_t previous_checkpoint_offset() const; 65.38 + void set_previous_checkpoint_offset(int64_t offset); 65.39 + int64_t previous_start_ticks() const; 65.40 + int64_t previous_start_nanos() const; 65.41 + int64_t last_chunk_duration() const; 65.42 void update_time_to_now(); 65.43 void set_path(const char* path); 65.44 const char* path() const;
66.1 --- a/src/share/vm/jfr/recorder/repository/jfrChunkWriter.cpp Sat Oct 24 16:18:50 2020 +0800 66.2 +++ b/src/share/vm/jfr/recorder/repository/jfrChunkWriter.cpp Sat Oct 24 16:43:47 2020 +0800 66.3 @@ -32,9 +32,8 @@ 66.4 #include "runtime/os.hpp" 66.5 #include "runtime/os.hpp" 66.6 66.7 -const u2 JFR_VERSION_MAJOR = 2; 66.8 -const u2 JFR_VERSION_MINOR = 0; 66.9 - 66.10 +static const u2 JFR_VERSION_MAJOR = 2; 66.11 +static const u2 JFR_VERSION_MINOR = 0; 66.12 static const size_t MAGIC_LEN = 4; 66.13 static const size_t FILEHEADER_SLOT_SIZE = 8; 66.14 static const size_t CHUNK_SIZE_OFFSET = 8; 66.15 @@ -79,14 +78,14 @@ 66.16 return is_open; 66.17 } 66.18 66.19 -size_t JfrChunkWriter::close(intptr_t metadata_offset) { 66.20 +size_t JfrChunkWriter::close(int64_t metadata_offset) { 66.21 write_header(metadata_offset); 66.22 this->flush(); 66.23 this->close_fd(); 66.24 - return size_written(); 66.25 + return (size_t)size_written(); 66.26 } 66.27 66.28 -void JfrChunkWriter::write_header(intptr_t metadata_offset) { 66.29 +void JfrChunkWriter::write_header(int64_t metadata_offset) { 66.30 assert(this->is_valid(), "invariant"); 66.31 // Chunk size 66.32 this->write_be_at_offset((jlong)size_written(), CHUNK_SIZE_OFFSET); 66.33 @@ -106,15 +105,15 @@ 66.34 _chunkstate->set_path(chunk_path); 66.35 } 66.36 66.37 -intptr_t JfrChunkWriter::size_written() const { 66.38 +int64_t JfrChunkWriter::size_written() const { 66.39 return this->is_valid() ? this->current_offset() : 0; 66.40 } 66.41 66.42 -intptr_t JfrChunkWriter::previous_checkpoint_offset() const { 66.43 +int64_t JfrChunkWriter::previous_checkpoint_offset() const { 66.44 return _chunkstate->previous_checkpoint_offset(); 66.45 } 66.46 66.47 -void JfrChunkWriter::set_previous_checkpoint_offset(intptr_t offset) { 66.48 +void JfrChunkWriter::set_previous_checkpoint_offset(int64_t offset) { 66.49 _chunkstate->set_previous_checkpoint_offset(offset); 66.50 } 66.51
67.1 --- a/src/share/vm/jfr/recorder/repository/jfrChunkWriter.hpp Sat Oct 24 16:18:50 2020 +0800 67.2 +++ b/src/share/vm/jfr/recorder/repository/jfrChunkWriter.hpp Sat Oct 24 16:43:47 2020 +0800 67.3 @@ -41,16 +41,16 @@ 67.4 JfrChunkState* _chunkstate; 67.5 67.6 bool open(); 67.7 - size_t close(intptr_t metadata_offset); 67.8 - void write_header(intptr_t metadata_offset); 67.9 + size_t close(int64_t metadata_offset); 67.10 + void write_header(int64_t metadata_offset); 67.11 void set_chunk_path(const char* chunk_path); 67.12 67.13 public: 67.14 JfrChunkWriter(); 67.15 bool initialize(); 67.16 - intptr_t size_written() const; 67.17 - intptr_t previous_checkpoint_offset() const; 67.18 - void set_previous_checkpoint_offset(intptr_t offset); 67.19 + int64_t size_written() const; 67.20 + int64_t previous_checkpoint_offset() const; 67.21 + void set_previous_checkpoint_offset(int64_t offset); 67.22 void time_stamp_chunk_now(); 67.23 }; 67.24
68.1 --- a/src/share/vm/jfr/recorder/repository/jfrEmergencyDump.cpp Sat Oct 24 16:18:50 2020 +0800 68.2 +++ b/src/share/vm/jfr/recorder/repository/jfrEmergencyDump.cpp Sat Oct 24 16:43:47 2020 +0800 68.3 @@ -70,10 +70,9 @@ 68.4 Threads_lock->unlock(); 68.5 } 68.6 68.7 - // XXX (Module_lock -> PackageTable_lock) 68.8 - if (PackageTable_lock->owned_by_self()) { 68.9 - PackageTable_lock->unlock(); 68.10 - } 68.11 + if (PackageTable_lock->owned_by_self()) { 68.12 + PackageTable_lock->unlock(); 68.13 + } 68.14 68.15 if (Heap_lock->owned_by_self()) { 68.16 Heap_lock->unlock();
69.1 --- a/src/share/vm/jfr/recorder/repository/jfrRepository.cpp Sat Oct 24 16:18:50 2020 +0800 69.2 +++ b/src/share/vm/jfr/recorder/repository/jfrRepository.cpp Sat Oct 24 16:43:47 2020 +0800 69.3 @@ -147,10 +147,10 @@ 69.4 iso8601_to_date_time(buffer); 69.5 } 69.6 69.7 -static jlong file_size(fio_fd fd) { 69.8 +static int64_t file_size(fio_fd fd) { 69.9 assert(fd != invalid_fd, "invariant"); 69.10 - const jlong current_offset = os::current_file_offset(fd); 69.11 - const jlong size = os::lseek(fd, 0, SEEK_END); 69.12 + const int64_t current_offset = os::current_file_offset(fd); 69.13 + const int64_t size = os::lseek(fd, 0, SEEK_END); 69.14 os::seek_to_file_offset(fd, current_offset); 69.15 return size; 69.16 } 69.17 @@ -218,7 +218,7 @@ 69.18 if (invalid_fd == entry_fd) { 69.19 return NULL; 69.20 } 69.21 - const jlong entry_size = file_size(entry_fd); 69.22 + const int64_t entry_size = file_size(entry_fd); 69.23 os::close(entry_fd); 69.24 if (0 == entry_size) { 69.25 return NULL; 69.26 @@ -260,6 +260,7 @@ 69.27 } 69.28 } 69.29 #endif 69.30 + 69.31 bool RepositoryIterator::has_next() const { 69.32 return (_files != NULL && _iterator < _files->length()); 69.33 } 69.34 @@ -275,21 +276,26 @@ 69.35 if (file_copy_block == NULL) { 69.36 return; 69.37 } 69.38 - jlong bytes_written_total = 0; 69.39 + int64_t bytes_written_total = 0; 69.40 while (iterator.has_next()) { 69.41 fio_fd current_fd = invalid_fd; 69.42 const char* const fqn = iterator.next(); 69.43 if (fqn != NULL) { 69.44 current_fd = open_existing(fqn); 69.45 if (current_fd != invalid_fd) { 69.46 - const jlong current_filesize = file_size(current_fd); 69.47 + const int64_t current_filesize = file_size(current_fd); 69.48 assert(current_filesize > 0, "invariant"); 69.49 - jlong bytes_read = 0; 69.50 - jlong bytes_written = 0; 69.51 + int64_t bytes_read = 0; 69.52 + int64_t bytes_written = 0; 69.53 while (bytes_read < current_filesize) { 69.54 - bytes_read += (jlong)os::read_at(current_fd, file_copy_block, size_of_file_copy_block, bytes_read); 69.55 - assert(bytes_read - bytes_written <= (jlong)size_of_file_copy_block, "invariant"); 69.56 - bytes_written += (jlong)os::write(emergency_fd, file_copy_block, bytes_read - bytes_written); 69.57 + const ssize_t read_result = os::read_at(current_fd, file_copy_block, size_of_file_copy_block, bytes_read); 69.58 + if (-1 == read_result) { 69.59 + if (LogJFR) tty->print_cr("Unable to recover JFR data"); 69.60 + break; 69.61 + } 69.62 + bytes_read += (int64_t)read_result; 69.63 + assert(bytes_read - bytes_written <= (int64_t)size_of_file_copy_block, "invariant"); 69.64 + bytes_written += (int64_t)os::write(emergency_fd, file_copy_block, bytes_read - bytes_written); 69.65 assert(bytes_read == bytes_written, "invariant"); 69.66 } 69.67 os::close(current_fd); 69.68 @@ -468,6 +474,6 @@ 69.69 return _chunkwriter->open(); 69.70 } 69.71 69.72 -size_t JfrRepository::close_chunk(jlong metadata_offset) { 69.73 +size_t JfrRepository::close_chunk(int64_t metadata_offset) { 69.74 return _chunkwriter->close(metadata_offset); 69.75 }
70.1 --- a/src/share/vm/jfr/recorder/repository/jfrRepository.hpp Sat Oct 24 16:18:50 2020 +0800 70.2 +++ b/src/share/vm/jfr/recorder/repository/jfrRepository.hpp Sat Oct 24 16:43:47 2020 +0800 70.3 @@ -55,7 +55,7 @@ 70.4 bool set_path(const char* path); 70.5 void set_chunk_path(const char* path); 70.6 bool open_chunk(bool vm_error = false); 70.7 - size_t close_chunk(jlong metadata_offset); 70.8 + size_t close_chunk(int64_t metadata_offset); 70.9 void on_vm_error(); 70.10 static void notify_on_new_chunk_path(); 70.11 static JfrChunkWriter& chunkwriter();
71.1 --- a/src/share/vm/jfr/recorder/service/jfrOptionSet.cpp Sat Oct 24 16:18:50 2020 +0800 71.2 +++ b/src/share/vm/jfr/recorder/service/jfrOptionSet.cpp Sat Oct 24 16:43:47 2020 +0800 71.3 @@ -1,5 +1,5 @@ 71.4 /* 71.5 - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. 71.6 + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. 71.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 71.8 * 71.9 * This code is free software; you can redistribute it and/or modify it 71.10 @@ -27,6 +27,7 @@ 71.11 #include "jfr/recorder/service/jfrMemorySizer.hpp" 71.12 #include "jfr/recorder/service/jfrOptionSet.hpp" 71.13 #include "jfr/utilities/jfrAllocation.hpp" 71.14 +#include "jfr/utilities/jfrTypes.hpp" 71.15 #include "memory/allocation.inline.hpp" 71.16 #include "memory/resourceArea.hpp" 71.17 #include "runtime/java.hpp" 71.18 @@ -105,10 +106,6 @@ 71.19 return _stack_depth; 71.20 } 71.21 71.22 -static const u4 STACK_DEPTH_DEFAULT = 64; 71.23 -static const u4 MIN_STACK_DEPTH = 1; 71.24 -static const u4 MAX_STACK_DEPTH = 2048; 71.25 - 71.26 void JfrOptionSet::set_stackdepth(u4 depth) { 71.27 if (depth < MIN_STACK_DEPTH) { 71.28 _stack_depth = MIN_STACK_DEPTH; 71.29 @@ -679,7 +676,7 @@ 71.30 return false; 71.31 } 71.32 71.33 -static GrowableArray<const char*>* start_flight_recording_options_array = NULL; 71.34 +static GrowableArray<const char*>* startup_recording_options_array = NULL; 71.35 71.36 bool JfrOptionSet::parse_start_flight_recording_option(const JavaVMOption** option, char* delimiter) { 71.37 assert(option != NULL, "invariant"); 71.38 @@ -702,28 +699,28 @@ 71.39 assert(value != NULL, "invariant"); 71.40 const size_t value_length = strlen(value); 71.41 71.42 - if (start_flight_recording_options_array == NULL) { 71.43 - start_flight_recording_options_array = new (ResourceObj::C_HEAP, mtTracing) GrowableArray<const char*>(8, true, mtTracing); 71.44 + if (startup_recording_options_array == NULL) { 71.45 + startup_recording_options_array = new (ResourceObj::C_HEAP, mtTracing) GrowableArray<const char*>(8, true, mtTracing); 71.46 } 71.47 - assert(start_flight_recording_options_array != NULL, "invariant"); 71.48 + assert(startup_recording_options_array != NULL, "invariant"); 71.49 char* const startup_value = NEW_C_HEAP_ARRAY(char, value_length + 1, mtTracing); 71.50 strncpy(startup_value, value, value_length + 1); 71.51 assert(strncmp(startup_value, value, value_length) == 0, "invariant"); 71.52 - start_flight_recording_options_array->append(startup_value); 71.53 + startup_recording_options_array->append(startup_value); 71.54 return false; 71.55 } 71.56 71.57 -const GrowableArray<const char*>* JfrOptionSet::start_flight_recording_options() { 71.58 - return start_flight_recording_options_array; 71.59 +const GrowableArray<const char*>* JfrOptionSet::startup_recording_options() { 71.60 + return startup_recording_options_array; 71.61 } 71.62 71.63 -void JfrOptionSet::release_start_flight_recording_options() { 71.64 - if (start_flight_recording_options_array != NULL) { 71.65 - const int length = start_flight_recording_options_array->length(); 71.66 +void JfrOptionSet::release_startup_recording_options() { 71.67 + if (startup_recording_options_array != NULL) { 71.68 + const int length = startup_recording_options_array->length(); 71.69 for (int i = 0; i < length; ++i) { 71.70 - FREE_C_HEAP_ARRAY(char, start_flight_recording_options_array->at(i), mtTracing); 71.71 + FREE_C_HEAP_ARRAY(char, startup_recording_options_array->at(i), mtTracing); 71.72 } 71.73 - delete start_flight_recording_options_array; 71.74 - start_flight_recording_options_array = NULL; 71.75 + delete startup_recording_options_array; 71.76 + startup_recording_options_array = NULL; 71.77 } 71.78 }
72.1 --- a/src/share/vm/jfr/recorder/service/jfrOptionSet.hpp Sat Oct 24 16:18:50 2020 +0800 72.2 +++ b/src/share/vm/jfr/recorder/service/jfrOptionSet.hpp Sat Oct 24 16:43:47 2020 +0800 72.3 @@ -80,8 +80,8 @@ 72.4 72.5 static bool parse_flight_recorder_option(const JavaVMOption** option, char* delimiter); 72.6 static bool parse_start_flight_recording_option(const JavaVMOption** option, char* delimiter); 72.7 - static const GrowableArray<const char*>* start_flight_recording_options(); 72.8 - static void release_start_flight_recording_options(); 72.9 + static const GrowableArray<const char*>* startup_recording_options(); 72.10 + static void release_startup_recording_options(); 72.11 }; 72.12 72.13 #endif // SHARE_VM_JFR_RECORDER_SERVICE_JFROPTIONSET_HPP
73.1 --- a/src/share/vm/jfr/recorder/service/jfrRecorderService.cpp Sat Oct 24 16:18:50 2020 +0800 73.2 +++ b/src/share/vm/jfr/recorder/service/jfrRecorderService.cpp Sat Oct 24 16:43:47 2020 +0800 73.3 @@ -131,18 +131,18 @@ 73.4 bool not_acquired() const { return !_acquired; } 73.5 }; 73.6 73.7 -static intptr_t write_checkpoint_event_prologue(JfrChunkWriter& cw, u8 type_id) { 73.8 - const intptr_t prev_cp_offset = cw.previous_checkpoint_offset(); 73.9 - const intptr_t prev_cp_relative_offset = 0 == prev_cp_offset ? 0 : prev_cp_offset - cw.current_offset(); 73.10 +static int64_t write_checkpoint_event_prologue(JfrChunkWriter& cw, u8 type_id) { 73.11 + const int64_t prev_cp_offset = cw.previous_checkpoint_offset(); 73.12 + const int64_t prev_cp_relative_offset = 0 == prev_cp_offset ? 0 : prev_cp_offset - cw.current_offset(); 73.13 cw.reserve(sizeof(u4)); 73.14 cw.write<u8>(EVENT_CHECKPOINT); 73.15 cw.write(JfrTicks::now()); 73.16 - cw.write<jlong>((jlong)0); 73.17 - cw.write<jlong>((jlong)prev_cp_relative_offset); // write previous checkpoint offset delta 73.18 + cw.write((int64_t)0); 73.19 + cw.write(prev_cp_relative_offset); // write previous checkpoint offset delta 73.20 cw.write<bool>(false); // flushpoint 73.21 - cw.write<u4>((u4)1); // nof types in this checkpoint 73.22 - cw.write<u8>(type_id); 73.23 - const intptr_t number_of_elements_offset = cw.current_offset(); 73.24 + cw.write((u4)1); // nof types in this checkpoint 73.25 + cw.write(type_id); 73.26 + const int64_t number_of_elements_offset = cw.current_offset(); 73.27 cw.reserve(sizeof(u4)); 73.28 return number_of_elements_offset; 73.29 } 73.30 @@ -162,8 +162,8 @@ 73.31 } 73.32 bool process() { 73.33 // current_cp_offset is also offset for the event size header field 73.34 - const intptr_t current_cp_offset = _cw.current_offset(); 73.35 - const intptr_t num_elements_offset = write_checkpoint_event_prologue(_cw, _type_id); 73.36 + const int64_t current_cp_offset = _cw.current_offset(); 73.37 + const int64_t num_elements_offset = write_checkpoint_event_prologue(_cw, _type_id); 73.38 // invocation 73.39 _content_functor.process(); 73.40 const u4 number_of_elements = (u4)_content_functor.processed(); 73.41 @@ -476,9 +476,9 @@ 73.42 JfrMetadataEvent::lock(); 73.43 } 73.44 73.45 -static jlong write_metadata_event(JfrChunkWriter& chunkwriter) { 73.46 +static int64_t write_metadata_event(JfrChunkWriter& chunkwriter) { 73.47 assert(chunkwriter.is_valid(), "invariant"); 73.48 - const jlong metadata_offset = chunkwriter.current_offset(); 73.49 + const int64_t metadata_offset = chunkwriter.current_offset(); 73.50 JfrMetadataEvent::write(chunkwriter, metadata_offset); 73.51 return metadata_offset; 73.52 }
74.1 --- a/src/share/vm/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp Sat Oct 24 16:18:50 2020 +0800 74.2 +++ b/src/share/vm/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp Sat Oct 24 16:43:47 2020 +0800 74.3 @@ -69,8 +69,8 @@ 74.4 } 74.5 74.6 // handle general case 74.7 - int loop_count = 0; 74.8 - int loop_max = MaxJavaStackTraceDepth * 2; 74.9 + u4 loop_count = 0; 74.10 + u4 loop_max = MAX_STACK_DEPTH * 2; 74.11 do { 74.12 loop_count++; 74.13 // By the time we get here we should never see unsafe but better safe then segv'd
75.1 --- a/src/share/vm/jfr/utilities/jfrTypes.hpp Sat Oct 24 16:18:50 2020 +0800 75.2 +++ b/src/share/vm/jfr/utilities/jfrTypes.hpp Sat Oct 24 16:43:47 2020 +0800 75.3 @@ -33,6 +33,9 @@ 75.4 typedef int fio_fd; 75.5 const int invalid_fd = -1; 75.6 const jlong invalid_offset = -1; 75.7 +const u4 STACK_DEPTH_DEFAULT = 64; 75.8 +const u4 MIN_STACK_DEPTH = 1; 75.9 +const u4 MAX_STACK_DEPTH = 2048; 75.10 75.11 enum EventStartTime { 75.12 UNTIMED,
76.1 --- a/src/share/vm/jfr/writers/jfrEventWriterHost.inline.hpp Sat Oct 24 16:18:50 2020 +0800 76.2 +++ b/src/share/vm/jfr/writers/jfrEventWriterHost.inline.hpp Sat Oct 24 16:43:47 2020 +0800 76.3 @@ -49,7 +49,7 @@ 76.4 inline intptr_t EventWriterHost<BE, IE, WriterPolicyImpl>::end_write(void) { 76.5 assert(this->is_acquired(), 76.6 "state corruption, calling end with writer with non-acquired state!"); 76.7 - return this->is_valid() ? this->used_offset() : 0; 76.8 + return this->is_valid() ? (intptr_t)this->used_offset() : 0; 76.9 } 76.10 76.11 template <typename BE, typename IE, typename WriterPolicyImpl>
77.1 --- a/src/share/vm/jfr/writers/jfrPosition.hpp Sat Oct 24 16:18:50 2020 +0800 77.2 +++ b/src/share/vm/jfr/writers/jfrPosition.hpp Sat Oct 24 16:43:47 2020 +0800 77.3 @@ -48,8 +48,8 @@ 77.4 77.5 public: 77.6 size_t available_size() const; 77.7 - intptr_t used_offset() const; 77.8 - intptr_t current_offset() const; 77.9 + int64_t used_offset() const; 77.10 + int64_t current_offset() const; 77.11 size_t used_size() const; 77.12 void reset(); 77.13 };
78.1 --- a/src/share/vm/jfr/writers/jfrPosition.inline.hpp Sat Oct 24 16:18:50 2020 +0800 78.2 +++ b/src/share/vm/jfr/writers/jfrPosition.inline.hpp Sat Oct 24 16:43:47 2020 +0800 78.3 @@ -80,12 +80,12 @@ 78.4 } 78.5 78.6 template <typename AP> 78.7 -inline intptr_t Position<AP>::used_offset() const { 78.8 +inline int64_t Position<AP>::used_offset() const { 78.9 return _current_pos - _start_pos; 78.10 } 78.11 78.12 template <typename AP> 78.13 -inline intptr_t Position<AP>::current_offset() const { 78.14 +inline int64_t Position<AP>::current_offset() const { 78.15 return this->used_offset(); 78.16 } 78.17
79.1 --- a/src/share/vm/jfr/writers/jfrStreamWriterHost.hpp Sat Oct 24 16:18:50 2020 +0800 79.2 +++ b/src/share/vm/jfr/writers/jfrStreamWriterHost.hpp Sat Oct 24 16:43:47 2020 +0800 79.3 @@ -33,9 +33,9 @@ 79.4 public: 79.5 typedef typename Adapter::StorageType StorageType; 79.6 private: 79.7 - intptr_t _stream_pos; 79.8 + int64_t _stream_pos; 79.9 fio_fd _fd; 79.10 - intptr_t current_stream_position() const; 79.11 + int64_t current_stream_position() const; 79.12 79.13 protected: 79.14 StreamWriterHost(StorageType* storage, Thread* thread); 79.15 @@ -47,8 +47,8 @@ 79.16 bool has_valid_fd() const; 79.17 79.18 public: 79.19 - intptr_t current_offset() const; 79.20 - void seek(intptr_t offset); 79.21 + int64_t current_offset() const; 79.22 + void seek(int64_t offset); 79.23 void flush(); 79.24 void write_unbuffered(const void* src, size_t len); 79.25 bool is_valid() const;
80.1 --- a/src/share/vm/jfr/writers/jfrStreamWriterHost.inline.hpp Sat Oct 24 16:18:50 2020 +0800 80.2 +++ b/src/share/vm/jfr/writers/jfrStreamWriterHost.inline.hpp Sat Oct 24 16:43:47 2020 +0800 80.3 @@ -44,7 +44,7 @@ 80.4 } 80.5 80.6 template <typename Adapter, typename AP> 80.7 -inline intptr_t StreamWriterHost<Adapter, AP>::current_stream_position() const { 80.8 +inline int64_t StreamWriterHost<Adapter, AP>::current_stream_position() const { 80.9 return this->used_offset() + _stream_pos; 80.10 } 80.11 80.12 @@ -73,7 +73,7 @@ 80.13 inline void StreamWriterHost<Adapter, AP>::flush(size_t size) { 80.14 assert(size > 0, "invariant"); 80.15 assert(this->is_valid(), "invariant"); 80.16 - _stream_pos += os::write(_fd, this->start_pos(), (int)size); 80.17 + _stream_pos += os::write(_fd, this->start_pos(), (unsigned int)size); 80.18 StorageHost<Adapter, AP>::reset(); 80.19 assert(0 == this->used_offset(), "invariant"); 80.20 } 80.21 @@ -84,12 +84,12 @@ 80.22 } 80.23 80.24 template <typename Adapter, typename AP> 80.25 -inline intptr_t StreamWriterHost<Adapter, AP>::current_offset() const { 80.26 +inline int64_t StreamWriterHost<Adapter, AP>::current_offset() const { 80.27 return current_stream_position(); 80.28 } 80.29 80.30 template <typename Adapter, typename AP> 80.31 -void StreamWriterHost<Adapter, AP>::seek(intptr_t offset) { 80.32 +void StreamWriterHost<Adapter, AP>::seek(int64_t offset) { 80.33 this->flush(); 80.34 assert(0 == this->used_offset(), "can only seek from beginning"); 80.35 _stream_pos = os::seek_to_file_offset(_fd, offset); 80.36 @@ -110,7 +110,7 @@ 80.37 this->flush(); 80.38 assert(0 == this->used_offset(), "can only seek from beginning"); 80.39 while (len > 0) { 80.40 - const int n = MIN2<int>((int)len, INT_MAX); 80.41 + const unsigned int n = MIN2((unsigned int)len, (unsigned int)INT_MAX); 80.42 _stream_pos += os::write(_fd, buf, n); 80.43 len -= n; 80.44 }
81.1 --- a/src/share/vm/jfr/writers/jfrWriterHost.hpp Sat Oct 24 16:18:50 2020 +0800 81.2 +++ b/src/share/vm/jfr/writers/jfrWriterHost.hpp Sat Oct 24 16:43:47 2020 +0800 81.3 @@ -32,7 +32,6 @@ 81.4 class ClassLoaderData; 81.5 class Klass; 81.6 class Method; 81.7 -// XXX class PackageEntry; 81.8 class Symbol; 81.9 class Thread; 81.10 81.11 @@ -80,7 +79,6 @@ 81.12 void write(const ClassLoaderData* cld); 81.13 void write(const Klass* klass); 81.14 void write(const Method* method); 81.15 -// XXX void write(const PackageEntry* package); 81.16 void write(const Symbol* symbol); 81.17 void write(const Ticks& time); 81.18 void write(const Tickspan& time); 81.19 @@ -89,12 +87,12 @@ 81.20 void bytes(const void* buf, size_t len); 81.21 void write_utf8_u2_len(const char* value); 81.22 template <typename T> 81.23 - void write_padded_at_offset(T value, intptr_t offset); 81.24 + void write_padded_at_offset(T value, int64_t offset); 81.25 template <typename T> 81.26 - void write_at_offset(T value, intptr_t offset); 81.27 + void write_at_offset(T value, int64_t offset); 81.28 template <typename T> 81.29 - void write_be_at_offset(T value, intptr_t offset); 81.30 - intptr_t reserve(size_t size); 81.31 + void write_be_at_offset(T value, int64_t offset); 81.32 + int64_t reserve(size_t size); 81.33 }; 81.34 81.35 #endif // SHARE_VM_JFR_WRITERS_JFRWRITERHOST_HPP
82.1 --- a/src/share/vm/jfr/writers/jfrWriterHost.inline.hpp Sat Oct 24 16:18:50 2020 +0800 82.2 +++ b/src/share/vm/jfr/writers/jfrWriterHost.inline.hpp Sat Oct 24 16:43:47 2020 +0800 82.3 @@ -33,7 +33,6 @@ 82.4 #include "memory/resourceArea.hpp" 82.5 #include "oops/oop.hpp" 82.6 #include "oops/symbol.hpp" 82.7 -//#include "oops/typeArrayOop.inline.hpp" - XXX 82.8 82.9 inline bool compressed_integers() { 82.10 static const bool comp_integers = JfrOptionSet::compressed_integers(); 82.11 @@ -71,7 +70,8 @@ 82.12 inline void WriterHost<BE, IE, WriterPolicyImpl>::write(const T* value, size_t len) { 82.13 assert(value != NULL, "invariant"); 82.14 assert(len > 0, "invariant"); 82.15 - u1* const pos = ensure_size(sizeof(T) * len); 82.16 + // Might need T + 1 size 82.17 + u1* const pos = ensure_size(sizeof(T) * len + len); 82.18 if (pos) { 82.19 this->set_current_pos(write(value, len, pos)); 82.20 } 82.21 @@ -125,7 +125,8 @@ 82.22 inline void WriterHost<BE, IE, WriterPolicyImpl>::be_write(const T* value, size_t len) { 82.23 assert(value != NULL, "invariant"); 82.24 assert(len > 0, "invariant"); 82.25 - u1* const pos = ensure_size(sizeof(T) * len); 82.26 + // Might need T + 1 size 82.27 + u1* const pos = ensure_size(sizeof(T) * len + len); 82.28 if (pos) { 82.29 this->set_current_pos(BE::be_write(value, len, pos)); 82.30 } 82.31 @@ -138,10 +139,17 @@ 82.32 _compressed_integers(compressed_integers()) { 82.33 } 82.34 82.35 +// Extra size added as a safety cushion when dimensioning memory. 82.36 +// With varint encoding, the worst case is 82.37 +// associated with writing negative values. 82.38 +// For example, writing a negative s1 (-1) 82.39 +// will encode as 0xff 0x0f (2 bytes). 82.40 +static const size_t size_safety_cushion = 1; 82.41 + 82.42 template <typename BE, typename IE, typename WriterPolicyImpl > 82.43 template <typename StorageType> 82.44 inline WriterHost<BE, IE, WriterPolicyImpl>::WriterHost(StorageType* storage, size_t size) : 82.45 - WriterPolicyImpl(storage, size), 82.46 + WriterPolicyImpl(storage, size + size_safety_cushion), 82.47 _compressed_integers(compressed_integers()) { 82.48 } 82.49 82.50 @@ -151,30 +159,19 @@ 82.51 _compressed_integers(compressed_integers()) { 82.52 } 82.53 82.54 -// Extra size added as a safety cushion when dimensioning memory. 82.55 -// With varint encoding, the worst case is 82.56 -// associated with writing negative values. 82.57 -// For example, writing a negative s1 (-1) 82.58 -// will encode as 0xff 0x0f (2 bytes). 82.59 -// In this example, the sizeof(T) == 1 and length == 1, 82.60 -// but the implementation will need to dimension 82.61 -// 2 bytes for the encoding. 82.62 -// Hopefully, negative values should be relatively rare. 82.63 -static const size_t size_safety_cushion = 1; 82.64 - 82.65 template <typename BE, typename IE, typename WriterPolicyImpl> 82.66 -inline u1* WriterHost<BE, IE, WriterPolicyImpl>::ensure_size(size_t requested) { 82.67 +inline u1* WriterHost<BE, IE, WriterPolicyImpl>::ensure_size(size_t requested_size) { 82.68 if (!this->is_valid()) { 82.69 // cancelled 82.70 return NULL; 82.71 } 82.72 - if (this->available_size() < requested + size_safety_cushion) { 82.73 - if (!this->accommodate(this->used_size(), requested + size_safety_cushion)) { 82.74 + if (this->available_size() < requested_size) { 82.75 + if (!this->accommodate(this->used_size(), requested_size)) { 82.76 this->cancel(); 82.77 return NULL; 82.78 } 82.79 } 82.80 - assert(requested + size_safety_cushion <= this->available_size(), "invariant"); 82.81 + assert(requested_size <= this->available_size(), "invariant"); 82.82 return this->current_pos(); 82.83 } 82.84 82.85 @@ -259,12 +256,6 @@ 82.86 tag_write(this, method); 82.87 } 82.88 82.89 -// XXX 82.90 -// template <typename BE, typename IE, typename WriterPolicyImpl> 82.91 -// void WriterHost<BE, IE, WriterPolicyImpl>::write(const PackageEntry* package) { 82.92 -// tag_write(this, package); 82.93 -// } 82.94 - 82.95 template <typename BE, typename IE, typename WriterPolicyImpl> 82.96 void WriterHost<BE, IE, WriterPolicyImpl>::write(const Symbol* symbol) { 82.97 ResourceMark rm; 82.98 @@ -313,9 +304,9 @@ 82.99 } 82.100 82.101 template <typename BE, typename IE, typename WriterPolicyImpl> 82.102 -inline intptr_t WriterHost<BE, IE, WriterPolicyImpl>::reserve(size_t size) { 82.103 +inline int64_t WriterHost<BE, IE, WriterPolicyImpl>::reserve(size_t size) { 82.104 if (ensure_size(size) != NULL) { 82.105 - intptr_t reserved_offset = this->current_offset(); 82.106 + const int64_t reserved_offset = this->current_offset(); 82.107 this->set_current_pos(size); 82.108 return reserved_offset; 82.109 } 82.110 @@ -325,9 +316,9 @@ 82.111 82.112 template <typename BE, typename IE, typename WriterPolicyImpl> 82.113 template <typename T> 82.114 -inline void WriterHost<BE, IE, WriterPolicyImpl>::write_padded_at_offset(T value, intptr_t offset) { 82.115 +inline void WriterHost<BE, IE, WriterPolicyImpl>::write_padded_at_offset(T value, int64_t offset) { 82.116 if (this->is_valid()) { 82.117 - const intptr_t current = this->current_offset(); 82.118 + const int64_t current = this->current_offset(); 82.119 this->seek(offset); 82.120 write_padded(value); 82.121 this->seek(current); // restore 82.122 @@ -336,9 +327,9 @@ 82.123 82.124 template <typename BE, typename IE, typename WriterPolicyImpl> 82.125 template <typename T> 82.126 -inline void WriterHost<BE, IE, WriterPolicyImpl>::write_at_offset(T value, intptr_t offset) { 82.127 +inline void WriterHost<BE, IE, WriterPolicyImpl>::write_at_offset(T value, int64_t offset) { 82.128 if (this->is_valid()) { 82.129 - const intptr_t current = this->current_offset(); 82.130 + const int64_t current = this->current_offset(); 82.131 this->seek(offset); 82.132 write(value); 82.133 this->seek(current); // restore 82.134 @@ -347,9 +338,9 @@ 82.135 82.136 template <typename BE, typename IE, typename WriterPolicyImpl> 82.137 template <typename T> 82.138 -inline void WriterHost<BE, IE, WriterPolicyImpl>::write_be_at_offset(T value, intptr_t offset) { 82.139 +inline void WriterHost<BE, IE, WriterPolicyImpl>::write_be_at_offset(T value, int64_t offset) { 82.140 if (this->is_valid()) { 82.141 - const intptr_t current = this->current_offset(); 82.142 + const int64_t current = this->current_offset(); 82.143 this->seek(offset); 82.144 be_write(value); 82.145 this->seek(current); // restore
83.1 --- a/src/share/vm/memory/filemap.cpp Sat Oct 24 16:18:50 2020 +0800 83.2 +++ b/src/share/vm/memory/filemap.cpp Sat Oct 24 16:43:47 2020 +0800 83.3 @@ -125,7 +125,7 @@ 83.4 } else { 83.5 // Get the hash value. Use a static seed because the hash needs to return the same 83.6 // value over multiple jvm invocations. 83.7 - unsigned int hash = AltHashing::murmur3_32(8191, (const jbyte*)vm_version, version_len); 83.8 + uint32_t hash = AltHashing::halfsiphash_32(8191, (const uint8_t*)vm_version, version_len); 83.9 83.10 // Truncate the ident, saving room for the 8 hex character hash value. 83.11 strncpy(header_version, vm_version, JVM_IDENT_MAX-9);
84.1 --- a/src/share/vm/memory/metaspaceShared.cpp Sat Oct 24 16:18:50 2020 +0800 84.2 +++ b/src/share/vm/memory/metaspaceShared.cpp Sat Oct 24 16:43:47 2020 +0800 84.3 @@ -723,12 +723,15 @@ 84.4 int class_list_path_len = (int)strlen(class_list_path_str); 84.5 if (class_list_path_len >= 3) { 84.6 if (strcmp(class_list_path_str + class_list_path_len - 3, "lib") != 0) { 84.7 - strcat(class_list_path_str, os::file_separator()); 84.8 - strcat(class_list_path_str, "lib"); 84.9 + jio_snprintf(class_list_path_str + class_list_path_len, 84.10 + sizeof(class_list_path_str) - class_list_path_len, 84.11 + "%slib", os::file_separator()); 84.12 + class_list_path_len += 4; 84.13 } 84.14 } 84.15 - strcat(class_list_path_str, os::file_separator()); 84.16 - strcat(class_list_path_str, "classlist"); 84.17 + jio_snprintf(class_list_path_str + class_list_path_len, 84.18 + sizeof(class_list_path_str) - class_list_path_len, 84.19 + "%sclasslist", os::file_separator()); 84.20 class_list_path = class_list_path_str; 84.21 } else { 84.22 class_list_path = SharedClassListFile;
85.1 --- a/src/share/vm/memory/threadLocalAllocBuffer.cpp Sat Oct 24 16:18:50 2020 +0800 85.2 +++ b/src/share/vm/memory/threadLocalAllocBuffer.cpp Sat Oct 24 16:43:47 2020 +0800 85.3 @@ -1,5 +1,5 @@ 85.4 /* 85.5 - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. 85.6 + * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. 85.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 85.8 * 85.9 * This code is free software; you can redistribute it and/or modify it 85.10 @@ -88,7 +88,8 @@ 85.11 // The result can be larger than 1.0 due to direct to old allocations. 85.12 // These allocations should ideally not be counted but since it is not possible 85.13 // to filter them out here we just cap the fraction to be at most 1.0. 85.14 - double alloc_frac = MIN2(1.0, (double) allocated_since_last_gc / used); 85.15 + // Keep alloc_frac as float and not double to avoid the double to float conversion 85.16 + float alloc_frac = MIN2(1.0f, allocated_since_last_gc / (float) used); 85.17 _allocation_fraction.sample(alloc_frac); 85.18 } 85.19 global_stats()->update_allocating_threads(); 85.20 @@ -205,7 +206,8 @@ 85.21 // this thread is redone in startup_initialization below. 85.22 if (Universe::heap() != NULL) { 85.23 size_t capacity = Universe::heap()->tlab_capacity(myThread()) / HeapWordSize; 85.24 - double alloc_frac = desired_size() * target_refills() / (double) capacity; 85.25 + // Keep alloc_frac as float and not double to avoid the double to float conversion 85.26 + float alloc_frac = desired_size() * target_refills() / (float) capacity; 85.27 _allocation_fraction.sample(alloc_frac); 85.28 } 85.29
86.1 --- a/src/share/vm/oops/constantPool.cpp Sat Oct 24 16:18:50 2020 +0800 86.2 +++ b/src/share/vm/oops/constantPool.cpp Sat Oct 24 16:43:47 2020 +0800 86.3 @@ -235,14 +235,14 @@ 86.4 86.5 86.6 // The original attempt to resolve this constant pool entry failed so find the 86.7 - // original error and throw it again (JVMS 5.4.3). 86.8 + // class of the original error and throw another error of the same class (JVMS 5.4.3). 86.9 + // If there is a detail message, pass that detail message to the error constructor. 86.10 + // The JVMS does not strictly require us to duplicate the same detail message, 86.11 + // or any internal exception fields such as cause or stacktrace. But since the 86.12 + // detail message is often a class name or other literal string, we will repeat it if 86.13 + // we can find it in the symbol table. 86.14 if (in_error) { 86.15 - Symbol* error = SystemDictionary::find_resolution_error(this_oop, which); 86.16 - guarantee(error != (Symbol*)NULL, "tag mismatch with resolution error table"); 86.17 - ResourceMark rm; 86.18 - // exception text will be the class name 86.19 - const char* className = this_oop->unresolved_klass_at(which)->as_C_string(); 86.20 - THROW_MSG_0(error, className); 86.21 + throw_resolution_error(this_oop, which, CHECK_0); 86.22 } 86.23 86.24 if (do_resolve) { 86.25 @@ -262,11 +262,6 @@ 86.26 // Failed to resolve class. We must record the errors so that subsequent attempts 86.27 // to resolve this constant pool entry fail with the same error (JVMS 5.4.3). 86.28 if (HAS_PENDING_EXCEPTION) { 86.29 - ResourceMark rm; 86.30 - Symbol* error = PENDING_EXCEPTION->klass()->name(); 86.31 - 86.32 - bool throw_orig_error = false; 86.33 - { 86.34 MonitorLockerEx ml(this_oop->lock()); 86.35 86.36 // some other thread has beaten us and has resolved the class. 86.37 @@ -276,32 +271,9 @@ 86.38 return entry.get_klass(); 86.39 } 86.40 86.41 - if (!PENDING_EXCEPTION-> 86.42 - is_a(SystemDictionary::LinkageError_klass())) { 86.43 - // Just throw the exception and don't prevent these classes from 86.44 - // being loaded due to virtual machine errors like StackOverflow 86.45 - // and OutOfMemoryError, etc, or if the thread was hit by stop() 86.46 - // Needs clarification to section 5.4.3 of the VM spec (see 6308271) 86.47 - } 86.48 - else if (!this_oop->tag_at(which).is_unresolved_klass_in_error()) { 86.49 - SystemDictionary::add_resolution_error(this_oop, which, error); 86.50 - this_oop->tag_at_put(which, JVM_CONSTANT_UnresolvedClassInError); 86.51 - } else { 86.52 - // some other thread has put the class in error state. 86.53 - error = SystemDictionary::find_resolution_error(this_oop, which); 86.54 - assert(error != NULL, "checking"); 86.55 - throw_orig_error = true; 86.56 - } 86.57 - } // unlocked 86.58 - 86.59 - if (throw_orig_error) { 86.60 - CLEAR_PENDING_EXCEPTION; 86.61 - ResourceMark rm; 86.62 - const char* className = this_oop->unresolved_klass_at(which)->as_C_string(); 86.63 - THROW_MSG_0(error, className); 86.64 - } 86.65 - 86.66 - return 0; 86.67 + // The tag could have changed to in-error before the lock but we have to 86.68 + // handle that here for the class case. 86.69 + save_and_throw_exception(this_oop, which, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_0); 86.70 } 86.71 86.72 if (TraceClassResolution && !k()->oop_is_array()) { 86.73 @@ -532,7 +504,7 @@ 86.74 } 86.75 86.76 86.77 -Symbol* ConstantPool::klass_name_at(int which) { 86.78 +Symbol* ConstantPool::klass_name_at(int which) const { 86.79 assert(tag_at(which).is_unresolved_klass() || tag_at(which).is_klass(), 86.80 "Corrupted constant pool"); 86.81 // A resolved constantPool entry will contain a Klass*, otherwise a Symbol*. 86.82 @@ -597,16 +569,51 @@ 86.83 return true; 86.84 } 86.85 86.86 -// If resolution for MethodHandle or MethodType fails, save the exception 86.87 +Symbol* ConstantPool::exception_message(constantPoolHandle this_oop, int which, constantTag tag, oop pending_exception) { 86.88 + // Dig out the detailed message to reuse if possible 86.89 + Symbol* message = java_lang_Throwable::detail_message(pending_exception); 86.90 + if (message != NULL) { 86.91 + return message; 86.92 + } 86.93 + 86.94 + // Return specific message for the tag 86.95 + switch (tag.value()) { 86.96 + case JVM_CONSTANT_UnresolvedClass: 86.97 + // return the class name in the error message 86.98 + message = this_oop->unresolved_klass_at(which); 86.99 + break; 86.100 + case JVM_CONSTANT_MethodHandle: 86.101 + // return the method handle name in the error message 86.102 + message = this_oop->method_handle_name_ref_at(which); 86.103 + break; 86.104 + case JVM_CONSTANT_MethodType: 86.105 + // return the method type signature in the error message 86.106 + message = this_oop->method_type_signature_at(which); 86.107 + break; 86.108 + default: 86.109 + ShouldNotReachHere(); 86.110 + } 86.111 + 86.112 + return message; 86.113 +} 86.114 + 86.115 +void ConstantPool::throw_resolution_error(constantPoolHandle this_oop, int which, TRAPS) { 86.116 + Symbol* message = NULL; 86.117 + Symbol* error = SystemDictionary::find_resolution_error(this_oop, which, &message); 86.118 + assert(error != NULL && message != NULL, "checking"); 86.119 + CLEAR_PENDING_EXCEPTION; 86.120 + ResourceMark rm; 86.121 + THROW_MSG(error, message->as_C_string()); 86.122 +} 86.123 + 86.124 +// If resolution for Class, MethodHandle or MethodType fails, save the exception 86.125 // in the resolution error table, so that the same exception is thrown again. 86.126 void ConstantPool::save_and_throw_exception(constantPoolHandle this_oop, int which, 86.127 - int tag, TRAPS) { 86.128 - ResourceMark rm; 86.129 + constantTag tag, TRAPS) { 86.130 + assert(this_oop->lock()->is_locked(), "constant pool lock should be held"); 86.131 Symbol* error = PENDING_EXCEPTION->klass()->name(); 86.132 - MonitorLockerEx ml(this_oop->lock()); // lock cpool to change tag. 86.133 86.134 - int error_tag = (tag == JVM_CONSTANT_MethodHandle) ? 86.135 - JVM_CONSTANT_MethodHandleInError : JVM_CONSTANT_MethodTypeInError; 86.136 + int error_tag = tag.error_value(); 86.137 86.138 if (!PENDING_EXCEPTION-> 86.139 is_a(SystemDictionary::LinkageError_klass())) { 86.140 @@ -614,20 +621,21 @@ 86.141 // being loaded due to virtual machine errors like StackOverflow 86.142 // and OutOfMemoryError, etc, or if the thread was hit by stop() 86.143 // Needs clarification to section 5.4.3 of the VM spec (see 6308271) 86.144 - 86.145 } else if (this_oop->tag_at(which).value() != error_tag) { 86.146 - SystemDictionary::add_resolution_error(this_oop, which, error); 86.147 + Symbol* message = exception_message(this_oop, which, tag, PENDING_EXCEPTION); 86.148 + SystemDictionary::add_resolution_error(this_oop, which, error, message); 86.149 this_oop->tag_at_put(which, error_tag); 86.150 } else { 86.151 - // some other thread has put the class in error state. 86.152 - error = SystemDictionary::find_resolution_error(this_oop, which); 86.153 - assert(error != NULL, "checking"); 86.154 - CLEAR_PENDING_EXCEPTION; 86.155 - THROW_MSG(error, ""); 86.156 + // some other thread put this in error state 86.157 + throw_resolution_error(this_oop, which, CHECK); 86.158 } 86.159 + 86.160 + // This exits with some pending exception 86.161 + assert(HAS_PENDING_EXCEPTION, "should not be cleared"); 86.162 } 86.163 86.164 86.165 + 86.166 // Called to resolve constants in the constant pool and return an oop. 86.167 // Some constant pool entries cache their resolved oop. This is also 86.168 // called to create oops from constants to use in arguments for invokedynamic 86.169 @@ -655,9 +663,9 @@ 86.170 86.171 jvalue prim_value; // temp used only in a few cases below 86.172 86.173 - int tag_value = this_oop->tag_at(index).value(); 86.174 + constantTag tag = this_oop->tag_at(index); 86.175 86.176 - switch (tag_value) { 86.177 + switch (tag.value()) { 86.178 86.179 case JVM_CONSTANT_UnresolvedClass: 86.180 case JVM_CONSTANT_UnresolvedClassInError: 86.181 @@ -682,10 +690,7 @@ 86.182 case JVM_CONSTANT_MethodHandleInError: 86.183 case JVM_CONSTANT_MethodTypeInError: 86.184 { 86.185 - Symbol* error = SystemDictionary::find_resolution_error(this_oop, index); 86.186 - guarantee(error != (Symbol*)NULL, "tag mismatch with resolution error table"); 86.187 - ResourceMark rm; 86.188 - THROW_MSG_0(error, ""); 86.189 + throw_resolution_error(this_oop, index, CHECK_NULL); 86.190 break; 86.191 } 86.192 86.193 @@ -709,7 +714,8 @@ 86.194 THREAD); 86.195 result_oop = value(); 86.196 if (HAS_PENDING_EXCEPTION) { 86.197 - save_and_throw_exception(this_oop, index, tag_value, CHECK_NULL); 86.198 + MonitorLockerEx ml(this_oop->lock()); // lock cpool to change tag. 86.199 + save_and_throw_exception(this_oop, index, tag, CHECK_NULL); 86.200 } 86.201 break; 86.202 } 86.203 @@ -725,7 +731,8 @@ 86.204 Handle value = SystemDictionary::find_method_handle_type(signature, klass, THREAD); 86.205 result_oop = value(); 86.206 if (HAS_PENDING_EXCEPTION) { 86.207 - save_and_throw_exception(this_oop, index, tag_value, CHECK_NULL); 86.208 + MonitorLockerEx ml(this_oop->lock()); // lock cpool to change tag. 86.209 + save_and_throw_exception(this_oop, index, tag, CHECK_NULL); 86.210 } 86.211 break; 86.212 } 86.213 @@ -756,7 +763,7 @@ 86.214 86.215 default: 86.216 DEBUG_ONLY( tty->print_cr("*** %p: tag at CP[%d/%d] = %d", 86.217 - this_oop(), index, cache_index, tag_value) ); 86.218 + this_oop(), index, cache_index, tag.value())); 86.219 assert(false, "unexpected constant tag"); 86.220 break; 86.221 }
87.1 --- a/src/share/vm/oops/constantPool.hpp Sat Oct 24 16:18:50 2020 +0800 87.2 +++ b/src/share/vm/oops/constantPool.hpp Sat Oct 24 16:43:47 2020 +0800 87.3 @@ -135,7 +135,7 @@ 87.4 private: 87.5 intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(ConstantPool)); } 87.6 87.7 - CPSlot slot_at(int which) { 87.8 + CPSlot slot_at(int which) const { 87.9 assert(is_within_bounds(which), "index out of bounds"); 87.10 // Uses volatile because the klass slot changes without a lock. 87.11 volatile intptr_t adr = (intptr_t)OrderAccess::load_ptr_acquire(obj_at_addr_raw(which)); 87.12 @@ -363,7 +363,7 @@ 87.13 return klass_at_impl(h_this, which, CHECK_NULL); 87.14 } 87.15 87.16 - Symbol* klass_name_at(int which); // Returns the name, w/o resolving. 87.17 + Symbol* klass_name_at(int which) const; // Returns the name, w/o resolving. 87.18 87.19 Klass* resolved_klass_at(int which) const { // Used by Compiler 87.20 guarantee(tag_at(which).is_klass(), "Corrupted constant pool"); 87.21 @@ -833,9 +833,13 @@ 87.22 static void resolve_string_constants_impl(constantPoolHandle this_oop, TRAPS); 87.23 87.24 static oop resolve_constant_at_impl(constantPoolHandle this_oop, int index, int cache_index, TRAPS); 87.25 - static void save_and_throw_exception(constantPoolHandle this_oop, int which, int tag_value, TRAPS); 87.26 static oop resolve_bootstrap_specifier_at_impl(constantPoolHandle this_oop, int index, TRAPS); 87.27 87.28 + // Exception handling 87.29 + static void throw_resolution_error(constantPoolHandle this_oop, int which, TRAPS); 87.30 + static Symbol* exception_message(constantPoolHandle this_oop, int which, constantTag tag, oop pending_exception); 87.31 + static void save_and_throw_exception(constantPoolHandle this_oop, int which, constantTag tag, TRAPS); 87.32 + 87.33 public: 87.34 // Merging ConstantPool* support: 87.35 bool compare_entry_to(int index1, constantPoolHandle cp2, int index2, TRAPS);
88.1 --- a/src/share/vm/oops/oop.cpp Sat Oct 24 16:18:50 2020 +0800 88.2 +++ b/src/share/vm/oops/oop.cpp Sat Oct 24 16:43:47 2020 +0800 88.3 @@ -111,7 +111,7 @@ 88.4 jchar* chars = java_lang_String::as_unicode_string(this, length, THREAD); 88.5 if (chars != NULL) { 88.6 // Use alternate hashing algorithm on the string 88.7 - return AltHashing::murmur3_32(seed, chars, length); 88.8 + return AltHashing::halfsiphash_32(seed, chars, length); 88.9 } else { 88.10 vm_exit_out_of_memory(length, OOM_MALLOC_ERROR, "unable to create Unicode strings for String table rehash"); 88.11 return 0;
89.1 --- a/src/share/vm/oops/symbol.cpp Sat Oct 24 16:18:50 2020 +0800 89.2 +++ b/src/share/vm/oops/symbol.cpp Sat Oct 24 16:43:47 2020 +0800 89.3 @@ -210,7 +210,7 @@ 89.4 unsigned int Symbol::new_hash(juint seed) { 89.5 ResourceMark rm; 89.6 // Use alternate hashing algorithm on this symbol. 89.7 - return AltHashing::murmur3_32(seed, (const jbyte*)as_C_string(), utf8_length()); 89.8 + return AltHashing::halfsiphash_32(seed, (const uint8_t*)as_C_string(), utf8_length()); 89.9 } 89.10 89.11 void Symbol::increment_refcount() {
90.1 --- a/src/share/vm/opto/addnode.cpp Sat Oct 24 16:18:50 2020 +0800 90.2 +++ b/src/share/vm/opto/addnode.cpp Sat Oct 24 16:43:47 2020 +0800 90.3 @@ -844,6 +844,14 @@ 90.4 return TypeInt::make( MAX2(r0->_lo,r1->_lo), MAX2(r0->_hi,r1->_hi), MAX2(r0->_widen,r1->_widen) ); 90.5 } 90.6 90.7 +// Check if addition of an integer with type 't' and a constant 'c' can overflow 90.8 +static bool can_overflow(const TypeInt* t, jint c) { 90.9 + jint t_lo = t->_lo; 90.10 + jint t_hi = t->_hi; 90.11 + return ((c < 0 && (java_add(t_lo, c) > t_lo)) || 90.12 + (c > 0 && (java_add(t_hi, c) < t_hi))); 90.13 +} 90.14 + 90.15 //============================================================================= 90.16 //------------------------------Idealize--------------------------------------- 90.17 // MINs show up in range-check loop limit calculations. Look for 90.18 @@ -866,7 +874,7 @@ 90.19 90.20 // Get left input & constant 90.21 Node *x = l; 90.22 - int x_off = 0; 90.23 + jint x_off = 0; 90.24 if( x->Opcode() == Op_AddI && // Check for "x+c0" and collect constant 90.25 x->in(2)->is_Con() ) { 90.26 const Type *t = x->in(2)->bottom_type(); 90.27 @@ -877,7 +885,7 @@ 90.28 90.29 // Scan a right-spline-tree for MINs 90.30 Node *y = r; 90.31 - int y_off = 0; 90.32 + jint y_off = 0; 90.33 // Check final part of MIN tree 90.34 if( y->Opcode() == Op_AddI && // Check for "y+c1" and collect constant 90.35 y->in(2)->is_Con() ) { 90.36 @@ -891,6 +899,7 @@ 90.37 return this; 90.38 } 90.39 90.40 + const TypeInt* tx = phase->type(x)->isa_int(); 90.41 90.42 if( r->Opcode() == Op_MinI ) { 90.43 assert( r != r->in(2), "dead loop in MinINode::Ideal" ); 90.44 @@ -907,18 +916,23 @@ 90.45 if( x->_idx > y->_idx ) 90.46 return new (phase->C) MinINode(r->in(1),phase->transform(new (phase->C) MinINode(l,r->in(2)))); 90.47 90.48 - // See if covers: MIN2(x+c0,MIN2(y+c1,z)) 90.49 - if( !phase->eqv(x,y) ) return NULL; 90.50 - // If (y == x) transform MIN2(x+c0, MIN2(x+c1,z)) into 90.51 - // MIN2(x+c0 or x+c1 which less, z). 90.52 - return new (phase->C) MinINode(phase->transform(new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off)))),r->in(2)); 90.53 + // Transform MIN2(x + c0, MIN2(x + c1, z)) into MIN2(x + MIN2(c0, c1), z) 90.54 + // if x == y and the additions can't overflow. 90.55 + if (phase->eqv(x,y) && 90.56 + !can_overflow(tx, x_off) && 90.57 + !can_overflow(tx, y_off)) { 90.58 + return new (phase->C) MinINode(phase->transform(new (phase->C) AddINode(x, phase->intcon(MIN2(x_off, y_off)))), r->in(2)); 90.59 + } 90.60 } else { 90.61 - // See if covers: MIN2(x+c0,y+c1) 90.62 - if( !phase->eqv(x,y) ) return NULL; 90.63 - // If (y == x) transform MIN2(x+c0,x+c1) into x+c0 or x+c1 which less. 90.64 - return new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off))); 90.65 + // Transform MIN2(x + c0, y + c1) into x + MIN2(c0, c1) 90.66 + // if x == y and the additions can't overflow. 90.67 + if (phase->eqv(x,y) && 90.68 + !can_overflow(tx, x_off) && 90.69 + !can_overflow(tx, y_off)) { 90.70 + return new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off))); 90.71 + } 90.72 } 90.73 - 90.74 + return NULL; 90.75 } 90.76 90.77 //------------------------------add_ring---------------------------------------
91.1 --- a/src/share/vm/opto/c2compiler.cpp Sat Oct 24 16:18:50 2020 +0800 91.2 +++ b/src/share/vm/opto/c2compiler.cpp Sat Oct 24 16:43:47 2020 +0800 91.3 @@ -117,7 +117,7 @@ 91.4 assert(is_initialized(), "Compiler thread must be initialized"); 91.5 91.6 bool subsume_loads = SubsumeLoads; 91.7 - bool do_escape_analysis = DoEscapeAnalysis && !env->jvmti_can_access_local_variables(); 91.8 + bool do_escape_analysis = DoEscapeAnalysis && !env->should_retain_local_variables(); 91.9 bool eliminate_boxing = EliminateAutoBox; 91.10 while (!env->failing()) { 91.11 // Attempt to compile while subsuming loads into machine instructions.
92.1 --- a/src/share/vm/opto/callnode.cpp Sat Oct 24 16:18:50 2020 +0800 92.2 +++ b/src/share/vm/opto/callnode.cpp Sat Oct 24 16:43:47 2020 +0800 92.3 @@ -1180,6 +1180,14 @@ 92.4 return (TypeFunc::Parms == idx); 92.5 } 92.6 92.7 +void SafePointNode::disconnect_from_root(PhaseIterGVN *igvn) { 92.8 + assert(Opcode() == Op_SafePoint, "only value for safepoint in loops"); 92.9 + int nb = igvn->C->root()->find_prec_edge(this); 92.10 + if (nb != -1) { 92.11 + igvn->C->root()->rm_prec(nb); 92.12 + } 92.13 +} 92.14 + 92.15 //============== SafePointScalarObjectNode ============== 92.16 92.17 SafePointScalarObjectNode::SafePointScalarObjectNode(const TypeOopPtr* tp,
93.1 --- a/src/share/vm/opto/callnode.hpp Sat Oct 24 16:18:50 2020 +0800 93.2 +++ b/src/share/vm/opto/callnode.hpp Sat Oct 24 16:43:47 2020 +0800 93.3 @@ -459,6 +459,8 @@ 93.4 return !_replaced_nodes.is_empty(); 93.5 } 93.6 93.7 + void disconnect_from_root(PhaseIterGVN *igvn); 93.8 + 93.9 // Standard Node stuff 93.10 virtual int Opcode() const; 93.11 virtual bool pinned() const { return true; }
94.1 --- a/src/share/vm/opto/compile.cpp Sat Oct 24 16:18:50 2020 +0800 94.2 +++ b/src/share/vm/opto/compile.cpp Sat Oct 24 16:43:47 2020 +0800 94.3 @@ -1170,6 +1170,9 @@ 94.4 _expensive_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); 94.5 _range_check_casts = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); 94.6 register_library_intrinsics(); 94.7 +#ifdef ASSERT 94.8 + _type_verify_symmetry = true; 94.9 +#endif 94.10 } 94.11 94.12 //---------------------------init_start---------------------------------------- 94.13 @@ -2083,6 +2086,23 @@ 94.14 } 94.15 94.16 94.17 +// Remove edges from "root" to each SafePoint at a backward branch. 94.18 +// They were inserted during parsing (see add_safepoint()) to make 94.19 +// infinite loops without calls or exceptions visible to root, i.e., 94.20 +// useful. 94.21 +void Compile::remove_root_to_sfpts_edges() { 94.22 + Node *r = root(); 94.23 + if (r != NULL) { 94.24 + for (uint i = r->req(); i < r->len(); ++i) { 94.25 + Node *n = r->in(i); 94.26 + if (n != NULL && n->is_SafePoint()) { 94.27 + r->rm_prec(i); 94.28 + --i; 94.29 + } 94.30 + } 94.31 + } 94.32 +} 94.33 + 94.34 //------------------------------Optimize--------------------------------------- 94.35 // Given a graph, optimize it. 94.36 void Compile::Optimize() { 94.37 @@ -2138,6 +2158,10 @@ 94.38 if (failing()) return; 94.39 } 94.40 94.41 + // Now that all inlining is over, cut edge from root to loop 94.42 + // safepoints 94.43 + remove_root_to_sfpts_edges(); 94.44 + 94.45 // Remove the speculative part of types and clean up the graph from 94.46 // the extra CastPP nodes whose only purpose is to carry them. Do 94.47 // that early so that optimizations are not disrupted by the extra 94.48 @@ -3020,8 +3044,10 @@ 94.49 break; 94.50 } 94.51 } 94.52 - assert(proj != NULL, "must be found"); 94.53 - p->subsume_by(proj, this); 94.54 + assert(proj != NULL || p->_con == TypeFunc::I_O, "io may be dropped at an infinite loop"); 94.55 + if (proj != NULL) { 94.56 + p->subsume_by(proj, this); 94.57 + } 94.58 } 94.59 } 94.60 break;
95.1 --- a/src/share/vm/opto/compile.hpp Sat Oct 24 16:18:50 2020 +0800 95.2 +++ b/src/share/vm/opto/compile.hpp Sat Oct 24 16:43:47 2020 +0800 95.3 @@ -959,6 +959,7 @@ 95.4 void inline_incrementally(PhaseIterGVN& igvn); 95.5 void inline_string_calls(bool parse_time); 95.6 void inline_boxing_calls(PhaseIterGVN& igvn); 95.7 + void remove_root_to_sfpts_edges(); 95.8 95.9 // Matching, CFG layout, allocation, code generation 95.10 PhaseCFG* cfg() { return _cfg; } 95.11 @@ -1223,6 +1224,9 @@ 95.12 95.13 // Auxiliary method for randomized fuzzing/stressing 95.14 static bool randomized_select(int count); 95.15 +#ifdef ASSERT 95.16 + bool _type_verify_symmetry; 95.17 +#endif 95.18 }; 95.19 95.20 #endif // SHARE_VM_OPTO_COMPILE_HPP
96.1 --- a/src/share/vm/opto/escape.cpp Sat Oct 24 16:18:50 2020 +0800 96.2 +++ b/src/share/vm/opto/escape.cpp Sat Oct 24 16:43:47 2020 +0800 96.3 @@ -1,5 +1,5 @@ 96.4 /* 96.5 - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. 96.6 + * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. 96.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 96.8 * 96.9 * This code is free software; you can redistribute it and/or modify it 96.10 @@ -2062,6 +2062,9 @@ 96.11 return NULL; 96.12 } 96.13 PointsToNode* ptn = ptnode_adr(idx); 96.14 + if (ptn == NULL) { 96.15 + return NULL; 96.16 + } 96.17 if (ptn->is_JavaObject()) { 96.18 return ptn->as_JavaObject(); 96.19 }
97.1 --- a/src/share/vm/opto/gcm.cpp Sat Oct 24 16:18:50 2020 +0800 97.2 +++ b/src/share/vm/opto/gcm.cpp Sat Oct 24 16:43:47 2020 +0800 97.3 @@ -256,6 +256,7 @@ 97.4 int is_visited = visited.test_set(in->_idx); 97.5 if (!has_block(in)) { 97.6 if (is_visited) { 97.7 + assert(false, "graph should be schedulable"); 97.8 return false; 97.9 } 97.10 // Save parent node and next input's index. 97.11 @@ -1070,6 +1071,7 @@ 97.12 97.13 if (LCA == NULL) { 97.14 // Bailout without retry 97.15 + assert(false, "graph should be schedulable"); 97.16 C->record_method_not_compilable("late schedule failed: LCA == NULL"); 97.17 return least; 97.18 } 97.19 @@ -1224,6 +1226,7 @@ 97.20 C->record_failure(C2Compiler::retry_no_subsuming_loads()); 97.21 } else { 97.22 // Bailout without retry when (early->_dom_depth > LCA->_dom_depth) 97.23 + assert(false, "graph should be schedulable"); 97.24 C->record_method_not_compilable("late schedule failed: incorrect graph"); 97.25 } 97.26 return;
98.1 --- a/src/share/vm/opto/graphKit.cpp Sat Oct 24 16:18:50 2020 +0800 98.2 +++ b/src/share/vm/opto/graphKit.cpp Sat Oct 24 16:43:47 2020 +0800 98.3 @@ -864,7 +864,7 @@ 98.4 } 98.5 } 98.6 98.7 - if (env()->jvmti_can_access_local_variables()) { 98.8 + if (env()->should_retain_local_variables()) { 98.9 // At any safepoint, this method can get breakpointed, which would 98.10 // then require an immediate deoptimization. 98.11 can_prune_locals = false; // do not prune locals
99.1 --- a/src/share/vm/opto/lcm.cpp Sat Oct 24 16:18:50 2020 +0800 99.2 +++ b/src/share/vm/opto/lcm.cpp Sat Oct 24 16:43:47 2020 +0800 99.3 @@ -969,6 +969,8 @@ 99.4 // If this is the first failure, the sentinel string will "stick" 99.5 // to the Compile object, and the C2Compiler will see it and retry. 99.6 C->record_failure(C2Compiler::retry_no_subsuming_loads()); 99.7 + } else { 99.8 + assert(false, "graph should be schedulable"); 99.9 } 99.10 // assert( phi_cnt == end_idx(), "did not schedule all" ); 99.11 return false;
100.1 --- a/src/share/vm/opto/loopTransform.cpp Sat Oct 24 16:18:50 2020 +0800 100.2 +++ b/src/share/vm/opto/loopTransform.cpp Sat Oct 24 16:43:47 2020 +0800 100.3 @@ -1223,20 +1223,14 @@ 100.4 Node *opaq = NULL; 100.5 if (adjust_min_trip) { // If not maximally unrolling, need adjustment 100.6 // Search for zero-trip guard. 100.7 - assert( loop_head->is_main_loop(), "" ); 100.8 - assert( ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, "" ); 100.9 - Node *iff = ctrl->in(0); 100.10 - assert( iff->Opcode() == Op_If, "" ); 100.11 - Node *bol = iff->in(1); 100.12 - assert( bol->Opcode() == Op_Bool, "" ); 100.13 - Node *cmp = bol->in(1); 100.14 - assert( cmp->Opcode() == Op_CmpI, "" ); 100.15 - opaq = cmp->in(2); 100.16 - // Occasionally it's possible for a zero-trip guard Opaque1 node to be 100.17 - // optimized away and then another round of loop opts attempted. 100.18 - // We can not optimize this particular loop in that case. 100.19 - if (opaq->Opcode() != Op_Opaque1) 100.20 - return; // Cannot find zero-trip guard! Bail out! 100.21 + 100.22 + // Check the shape of the graph at the loop entry. If an inappropriate 100.23 + // graph shape is encountered, the compiler bails out loop unrolling; 100.24 + // compilation of the method will still succeed. 100.25 + if (!is_canonical_main_loop_entry(loop_head)) { 100.26 + return; 100.27 + } 100.28 + opaq = ctrl->in(0)->in(1)->in(1)->in(2); 100.29 // Zero-trip test uses an 'opaque' node which is not shared. 100.30 assert(opaq->outcnt() == 1 && opaq->in(1) == limit, ""); 100.31 } 100.32 @@ -1536,65 +1530,78 @@ 100.33 } 100.34 100.35 //------------------------------adjust_limit----------------------------------- 100.36 -// Helper function for add_constraint(). 100.37 -Node* PhaseIdealLoop::adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl, bool round_up) { 100.38 - // Compute "I :: (limit-offset)/scale" 100.39 - Node *con = new (C) SubINode(rc_limit, offset); 100.40 - register_new_node(con, pre_ctrl); 100.41 - Node *X = new (C) DivINode(0, con, scale); 100.42 - register_new_node(X, pre_ctrl); 100.43 +// Helper function that computes new loop limit as (rc_limit-offset)/scale 100.44 +Node* PhaseIdealLoop::adjust_limit(bool is_positive_stride, Node* scale, Node* offset, Node* rc_limit, Node* old_limit, Node* pre_ctrl, bool round) { 100.45 + Node* sub = new (C) SubLNode(rc_limit, offset); 100.46 + register_new_node(sub, pre_ctrl); 100.47 + Node* limit = new (C) DivLNode(NULL, sub, scale); 100.48 + register_new_node(limit, pre_ctrl); 100.49 100.50 - // When the absolute value of scale is greater than one, the integer 100.51 - // division may round limit down so add one to the limit. 100.52 - if (round_up) { 100.53 - X = new (C) AddINode(X, _igvn.intcon(1)); 100.54 - register_new_node(X, pre_ctrl); 100.55 + // When the absolute value of scale is greater than one, the division 100.56 + // may round limit down/up, so add/sub one to/from the limit. 100.57 + if (round) { 100.58 + limit = new (C) AddLNode(limit, _igvn.longcon(is_positive_stride ? -1 : 1)); 100.59 + register_new_node(limit, pre_ctrl); 100.60 } 100.61 100.62 - // Adjust loop limit 100.63 - loop_limit = (stride_con > 0) 100.64 - ? (Node*)(new (C) MinINode(loop_limit, X)) 100.65 - : (Node*)(new (C) MaxINode(loop_limit, X)); 100.66 - register_new_node(loop_limit, pre_ctrl); 100.67 - return loop_limit; 100.68 + // Clamp the limit to handle integer under-/overflows. 100.69 + // When reducing the limit, clamp to [min_jint, old_limit]: 100.70 + // MIN(old_limit, MAX(limit, min_jint)) 100.71 + // When increasing the limit, clamp to [old_limit, max_jint]: 100.72 + // MAX(old_limit, MIN(limit, max_jint)) 100.73 + Node* cmp = new (C) CmpLNode(limit, _igvn.longcon(is_positive_stride ? min_jint : max_jint)); 100.74 + register_new_node(cmp, pre_ctrl); 100.75 + Node* bol = new (C) BoolNode(cmp, is_positive_stride ? BoolTest::lt : BoolTest::gt); 100.76 + register_new_node(bol, pre_ctrl); 100.77 + limit = new (C) ConvL2INode(limit); 100.78 + register_new_node(limit, pre_ctrl); 100.79 + limit = new (C) CMoveINode(bol, limit, _igvn.intcon(is_positive_stride ? min_jint : max_jint), TypeInt::INT); 100.80 + register_new_node(limit, pre_ctrl); 100.81 + 100.82 + limit = is_positive_stride ? (Node*)(new (C) MinINode(old_limit, limit)) 100.83 + : (Node*)(new (C) MaxINode(old_limit, limit)); 100.84 + register_new_node(limit, pre_ctrl); 100.85 + return limit; 100.86 } 100.87 100.88 //------------------------------add_constraint--------------------------------- 100.89 // Constrain the main loop iterations so the conditions: 100.90 -// low_limit <= scale_con * I + offset < upper_limit 100.91 -// always holds true. That is, either increase the number of iterations in 100.92 -// the pre-loop or the post-loop until the condition holds true in the main 100.93 -// loop. Stride, scale, offset and limit are all loop invariant. Further, 100.94 -// stride and scale are constants (offset and limit often are). 100.95 -void PhaseIdealLoop::add_constraint( int stride_con, int scale_con, Node *offset, Node *low_limit, Node *upper_limit, Node *pre_ctrl, Node **pre_limit, Node **main_limit ) { 100.96 - // For positive stride, the pre-loop limit always uses a MAX function 100.97 - // and the main loop a MIN function. For negative stride these are 100.98 - // reversed. 100.99 +// low_limit <= scale_con*I + offset < upper_limit 100.100 +// always hold true. That is, either increase the number of iterations in the 100.101 +// pre-loop or reduce the number of iterations in the main-loop until the condition 100.102 +// holds true in the main-loop. Stride, scale, offset and limit are all loop 100.103 +// invariant. Further, stride and scale are constants (offset and limit often are). 100.104 +void PhaseIdealLoop::add_constraint(jlong stride_con, jlong scale_con, Node* offset, Node* low_limit, Node* upper_limit, Node* pre_ctrl, Node** pre_limit, Node** main_limit) { 100.105 + assert(_igvn.type(offset)->isa_long() != NULL && _igvn.type(low_limit)->isa_long() != NULL && 100.106 + _igvn.type(upper_limit)->isa_long() != NULL, "arguments should be long values"); 100.107 100.108 - // Also for positive stride*scale the affine function is increasing, so the 100.109 - // pre-loop must check for underflow and the post-loop for overflow. 100.110 - // Negative stride*scale reverses this; pre-loop checks for overflow and 100.111 - // post-loop for underflow. 100.112 + // For a positive stride, we need to reduce the main-loop limit and 100.113 + // increase the pre-loop limit. This is reversed for a negative stride. 100.114 + bool is_positive_stride = (stride_con > 0); 100.115 100.116 - Node *scale = _igvn.intcon(scale_con); 100.117 + // If the absolute scale value is greater one, division in 'adjust_limit' may require 100.118 + // rounding. Make sure the ABS method correctly handles min_jint. 100.119 + // Only do this for the pre-loop, one less iteration of the main loop doesn't hurt. 100.120 + bool round = ABS(scale_con) > 1; 100.121 + 100.122 + Node* scale = _igvn.longcon(scale_con); 100.123 set_ctrl(scale, C->root()); 100.124 100.125 if ((stride_con^scale_con) >= 0) { // Use XOR to avoid overflow 100.126 + // Positive stride*scale: the affine function is increasing, 100.127 + // the pre-loop checks for underflow and the post-loop for overflow. 100.128 + 100.129 // The overflow limit: scale*I+offset < upper_limit 100.130 - // For main-loop compute 100.131 + // For the main-loop limit compute: 100.132 // ( if (scale > 0) /* and stride > 0 */ 100.133 // I < (upper_limit-offset)/scale 100.134 // else /* scale < 0 and stride < 0 */ 100.135 // I > (upper_limit-offset)/scale 100.136 // ) 100.137 - // 100.138 - // (upper_limit-offset) may overflow or underflow. 100.139 - // But it is fine since main loop will either have 100.140 - // less iterations or will be skipped in such case. 100.141 - *main_limit = adjust_limit(stride_con, scale, offset, upper_limit, *main_limit, pre_ctrl, false); 100.142 + *main_limit = adjust_limit(is_positive_stride, scale, offset, upper_limit, *main_limit, pre_ctrl, false); 100.143 100.144 - // The underflow limit: low_limit <= scale*I+offset. 100.145 - // For pre-loop compute 100.146 + // The underflow limit: low_limit <= scale*I+offset 100.147 + // For the pre-loop limit compute: 100.148 // NOT(scale*I+offset >= low_limit) 100.149 // scale*I+offset < low_limit 100.150 // ( if (scale > 0) /* and stride > 0 */ 100.151 @@ -1602,40 +1609,13 @@ 100.152 // else /* scale < 0 and stride < 0 */ 100.153 // I > (low_limit-offset)/scale 100.154 // ) 100.155 + *pre_limit = adjust_limit(!is_positive_stride, scale, offset, low_limit, *pre_limit, pre_ctrl, round); 100.156 + } else { 100.157 + // Negative stride*scale: the affine function is decreasing, 100.158 + // the pre-loop checks for overflow and the post-loop for underflow. 100.159 100.160 - if (low_limit->get_int() == -max_jint) { 100.161 - if (!RangeLimitCheck) return; 100.162 - // We need this guard when scale*pre_limit+offset >= limit 100.163 - // due to underflow. So we need execute pre-loop until 100.164 - // scale*I+offset >= min_int. But (min_int-offset) will 100.165 - // underflow when offset > 0 and X will be > original_limit 100.166 - // when stride > 0. To avoid it we replace positive offset with 0. 100.167 - // 100.168 - // Also (min_int+1 == -max_int) is used instead of min_int here 100.169 - // to avoid problem with scale == -1 (min_int/(-1) == min_int). 100.170 - Node* shift = _igvn.intcon(31); 100.171 - set_ctrl(shift, C->root()); 100.172 - Node* sign = new (C) RShiftINode(offset, shift); 100.173 - register_new_node(sign, pre_ctrl); 100.174 - offset = new (C) AndINode(offset, sign); 100.175 - register_new_node(offset, pre_ctrl); 100.176 - } else { 100.177 - assert(low_limit->get_int() == 0, "wrong low limit for range check"); 100.178 - // The only problem we have here when offset == min_int 100.179 - // since (0-min_int) == min_int. It may be fine for stride > 0 100.180 - // but for stride < 0 X will be < original_limit. To avoid it 100.181 - // max(pre_limit, original_limit) is used in do_range_check(). 100.182 - } 100.183 - // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond); 100.184 - *pre_limit = adjust_limit((-stride_con), scale, offset, low_limit, *pre_limit, pre_ctrl, 100.185 - scale_con > 1 && stride_con > 0); 100.186 - 100.187 - } else { // stride_con*scale_con < 0 100.188 - // For negative stride*scale pre-loop checks for overflow and 100.189 - // post-loop for underflow. 100.190 - // 100.191 // The overflow limit: scale*I+offset < upper_limit 100.192 - // For pre-loop compute 100.193 + // For the pre-loop limit compute: 100.194 // NOT(scale*I+offset < upper_limit) 100.195 // scale*I+offset >= upper_limit 100.196 // scale*I+offset+1 > upper_limit 100.197 @@ -1644,58 +1624,24 @@ 100.198 // else /* scale > 0 and stride < 0 */ 100.199 // I > (upper_limit-(offset+1))/scale 100.200 // ) 100.201 - // 100.202 - // (upper_limit-offset-1) may underflow or overflow. 100.203 - // To avoid it min(pre_limit, original_limit) is used 100.204 - // in do_range_check() for stride > 0 and max() for < 0. 100.205 - Node *one = _igvn.intcon(1); 100.206 + Node* one = _igvn.longcon(1); 100.207 set_ctrl(one, C->root()); 100.208 + Node* plus_one = new (C) AddLNode(offset, one); 100.209 + register_new_node( plus_one, pre_ctrl ); 100.210 + *pre_limit = adjust_limit(!is_positive_stride, scale, plus_one, upper_limit, *pre_limit, pre_ctrl, round); 100.211 100.212 - Node *plus_one = new (C) AddINode(offset, one); 100.213 - register_new_node( plus_one, pre_ctrl ); 100.214 - // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond); 100.215 - *pre_limit = adjust_limit((-stride_con), scale, plus_one, upper_limit, *pre_limit, pre_ctrl, 100.216 - scale_con < -1 && stride_con > 0); 100.217 - 100.218 - if (low_limit->get_int() == -max_jint) { 100.219 - if (!RangeLimitCheck) return; 100.220 - // We need this guard when scale*main_limit+offset >= limit 100.221 - // due to underflow. So we need execute main-loop while 100.222 - // scale*I+offset+1 > min_int. But (min_int-offset-1) will 100.223 - // underflow when (offset+1) > 0 and X will be < main_limit 100.224 - // when scale < 0 (and stride > 0). To avoid it we replace 100.225 - // positive (offset+1) with 0. 100.226 - // 100.227 - // Also (min_int+1 == -max_int) is used instead of min_int here 100.228 - // to avoid problem with scale == -1 (min_int/(-1) == min_int). 100.229 - Node* shift = _igvn.intcon(31); 100.230 - set_ctrl(shift, C->root()); 100.231 - Node* sign = new (C) RShiftINode(plus_one, shift); 100.232 - register_new_node(sign, pre_ctrl); 100.233 - plus_one = new (C) AndINode(plus_one, sign); 100.234 - register_new_node(plus_one, pre_ctrl); 100.235 - } else { 100.236 - assert(low_limit->get_int() == 0, "wrong low limit for range check"); 100.237 - // The only problem we have here when offset == max_int 100.238 - // since (max_int+1) == min_int and (0-min_int) == min_int. 100.239 - // But it is fine since main loop will either have 100.240 - // less iterations or will be skipped in such case. 100.241 - } 100.242 - // The underflow limit: low_limit <= scale*I+offset. 100.243 - // For main-loop compute 100.244 + // The underflow limit: low_limit <= scale*I+offset 100.245 + // For the main-loop limit compute: 100.246 // scale*I+offset+1 > low_limit 100.247 // ( if (scale < 0) /* and stride > 0 */ 100.248 // I < (low_limit-(offset+1))/scale 100.249 // else /* scale > 0 and stride < 0 */ 100.250 // I > (low_limit-(offset+1))/scale 100.251 // ) 100.252 - 100.253 - *main_limit = adjust_limit(stride_con, scale, plus_one, low_limit, *main_limit, pre_ctrl, 100.254 - false); 100.255 + *main_limit = adjust_limit(is_positive_stride, scale, plus_one, low_limit, *main_limit, pre_ctrl, false); 100.256 } 100.257 } 100.258 100.259 - 100.260 //------------------------------is_scaled_iv--------------------------------- 100.261 // Return true if exp is a constant times an induction var 100.262 bool PhaseIdealLoop::is_scaled_iv(Node* exp, Node* iv, int* p_scale) { 100.263 @@ -1806,7 +1752,6 @@ 100.264 #endif 100.265 assert(RangeCheckElimination, ""); 100.266 CountedLoopNode *cl = loop->_head->as_CountedLoop(); 100.267 - assert(cl->is_main_loop(), ""); 100.268 100.269 // protect against stride not being a constant 100.270 if (!cl->stride_is_con()) 100.271 @@ -1818,20 +1763,17 @@ 100.272 // to not ever trip end tests 100.273 Node *main_limit = cl->limit(); 100.274 100.275 + // Check graph shape. Cannot optimize a loop if zero-trip 100.276 + // Opaque1 node is optimized away and then another round 100.277 + // of loop opts attempted. 100.278 + if (!is_canonical_main_loop_entry(cl)) { 100.279 + return; 100.280 + } 100.281 + 100.282 // Need to find the main-loop zero-trip guard 100.283 Node *ctrl = cl->in(LoopNode::EntryControl); 100.284 - assert(ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, ""); 100.285 Node *iffm = ctrl->in(0); 100.286 - assert(iffm->Opcode() == Op_If, ""); 100.287 - Node *bolzm = iffm->in(1); 100.288 - assert(bolzm->Opcode() == Op_Bool, ""); 100.289 - Node *cmpzm = bolzm->in(1); 100.290 - assert(cmpzm->is_Cmp(), ""); 100.291 - Node *opqzm = cmpzm->in(2); 100.292 - // Can not optimize a loop if zero-trip Opaque1 node is optimized 100.293 - // away and then another round of loop opts attempted. 100.294 - if (opqzm->Opcode() != Op_Opaque1) 100.295 - return; 100.296 + Node *opqzm = iffm->in(1)->in(1)->in(2); 100.297 assert(opqzm->in(1) == main_limit, "do not understand situation"); 100.298 100.299 // Find the pre-loop limit; we will expand it's iterations to 100.300 @@ -1864,22 +1806,14 @@ 100.301 // Must know if its a count-up or count-down loop 100.302 100.303 int stride_con = cl->stride_con(); 100.304 - Node *zero = _igvn.intcon(0); 100.305 - Node *one = _igvn.intcon(1); 100.306 + Node* zero = _igvn.longcon(0); 100.307 + Node* one = _igvn.longcon(1); 100.308 // Use symmetrical int range [-max_jint,max_jint] 100.309 - Node *mini = _igvn.intcon(-max_jint); 100.310 + Node* mini = _igvn.longcon(-max_jint); 100.311 set_ctrl(zero, C->root()); 100.312 set_ctrl(one, C->root()); 100.313 set_ctrl(mini, C->root()); 100.314 100.315 - // Range checks that do not dominate the loop backedge (ie. 100.316 - // conditionally executed) can lengthen the pre loop limit beyond 100.317 - // the original loop limit. To prevent this, the pre limit is 100.318 - // (for stride > 0) MINed with the original loop limit (MAXed 100.319 - // stride < 0) when some range_check (rc) is conditionally 100.320 - // executed. 100.321 - bool conditional_rc = false; 100.322 - 100.323 // Check loop body for tests of trip-counter plus loop-invariant vs 100.324 // loop-invariant. 100.325 for( uint i = 0; i < loop->_body.size(); i++ ) { 100.326 @@ -1958,15 +1892,20 @@ 100.327 // stride_con and scale_con can be negative which will flip about the 100.328 // sense of the test. 100.329 100.330 + // Perform the limit computations in jlong to avoid overflow 100.331 + jlong lscale_con = scale_con; 100.332 + Node* int_offset = offset; 100.333 + offset = new (C) ConvI2LNode(offset); 100.334 + register_new_node(offset, pre_ctrl); 100.335 + Node* int_limit = limit; 100.336 + limit = new (C) ConvI2LNode(limit); 100.337 + register_new_node(limit, pre_ctrl); 100.338 + 100.339 // Adjust pre and main loop limits to guard the correct iteration set 100.340 if( cmp->Opcode() == Op_CmpU ) {// Unsigned compare is really 2 tests 100.341 if( b_test._test == BoolTest::lt ) { // Range checks always use lt 100.342 // The underflow and overflow limits: 0 <= scale*I+offset < limit 100.343 - add_constraint( stride_con, scale_con, offset, zero, limit, pre_ctrl, &pre_limit, &main_limit ); 100.344 - if (!conditional_rc) { 100.345 - // (0-offset)/scale could be outside of loop iterations range. 100.346 - conditional_rc = !loop->dominates_backedge(iff) || RangeLimitCheck; 100.347 - } 100.348 + add_constraint(stride_con, lscale_con, offset, zero, limit, pre_ctrl, &pre_limit, &main_limit); 100.349 } else { 100.350 #ifndef PRODUCT 100.351 if( PrintOpto ) 100.352 @@ -1980,16 +1919,16 @@ 100.353 // Fall into GE case 100.354 case BoolTest::ge: 100.355 // Convert (I*scale+offset) >= Limit to (I*(-scale)+(-offset)) <= -Limit 100.356 - scale_con = -scale_con; 100.357 - offset = new (C) SubINode( zero, offset ); 100.358 + lscale_con = -lscale_con; 100.359 + offset = new (C) SubLNode(zero, offset); 100.360 register_new_node( offset, pre_ctrl ); 100.361 - limit = new (C) SubINode( zero, limit ); 100.362 + limit = new (C) SubLNode(zero, limit); 100.363 register_new_node( limit, pre_ctrl ); 100.364 // Fall into LE case 100.365 case BoolTest::le: 100.366 if (b_test._test != BoolTest::gt) { 100.367 // Convert X <= Y to X < Y+1 100.368 - limit = new (C) AddINode( limit, one ); 100.369 + limit = new (C) AddLNode(limit, one); 100.370 register_new_node( limit, pre_ctrl ); 100.371 } 100.372 // Fall into LT case 100.373 @@ -1997,13 +1936,7 @@ 100.374 // The underflow and overflow limits: MIN_INT <= scale*I+offset < limit 100.375 // Note: (MIN_INT+1 == -MAX_INT) is used instead of MIN_INT here 100.376 // to avoid problem with scale == -1: MIN_INT/(-1) == MIN_INT. 100.377 - add_constraint( stride_con, scale_con, offset, mini, limit, pre_ctrl, &pre_limit, &main_limit ); 100.378 - if (!conditional_rc) { 100.379 - // ((MIN_INT+1)-offset)/scale could be outside of loop iterations range. 100.380 - // Note: negative offset is replaced with 0 but (MIN_INT+1)/scale could 100.381 - // still be outside of loop range. 100.382 - conditional_rc = !loop->dominates_backedge(iff) || RangeLimitCheck; 100.383 - } 100.384 + add_constraint(stride_con, lscale_con, offset, mini, limit, pre_ctrl, &pre_limit, &main_limit); 100.385 break; 100.386 default: 100.387 #ifndef PRODUCT 100.388 @@ -2039,7 +1972,8 @@ 100.389 } 100.390 100.391 // Update loop limits 100.392 - if (conditional_rc) { 100.393 + if (pre_limit != orig_limit) { 100.394 + // Computed pre-loop limit can be outside of loop iterations range. 100.395 pre_limit = (stride_con > 0) ? (Node*)new (C) MinINode(pre_limit, orig_limit) 100.396 : (Node*)new (C) MaxINode(pre_limit, orig_limit); 100.397 register_new_node(pre_limit, pre_ctrl);
101.1 --- a/src/share/vm/opto/loopnode.cpp Sat Oct 24 16:18:50 2020 +0800 101.2 +++ b/src/share/vm/opto/loopnode.cpp Sat Oct 24 16:43:47 2020 +0800 101.3 @@ -3282,6 +3282,41 @@ 101.4 return LCA; 101.5 } 101.6 101.7 +// Check the shape of the graph at the loop entry. In some cases, 101.8 +// the shape of the graph does not match the shape outlined below. 101.9 +// That is caused by the Opaque1 node "protecting" the shape of 101.10 +// the graph being removed by, for example, the IGVN performed 101.11 +// in PhaseIdealLoop::build_and_optimize(). 101.12 +// 101.13 +// After the Opaque1 node has been removed, optimizations (e.g., split-if, 101.14 +// loop unswitching, and IGVN, or a combination of them) can freely change 101.15 +// the graph's shape. As a result, the graph shape outlined below cannot 101.16 +// be guaranteed anymore. 101.17 +bool PhaseIdealLoop::is_canonical_main_loop_entry(CountedLoopNode* cl) { 101.18 + assert(cl->is_main_loop(), "check should be applied to main loops"); 101.19 + Node* ctrl = cl->in(LoopNode::EntryControl); 101.20 + if (ctrl == NULL || (!ctrl->is_IfTrue() && !ctrl->is_IfFalse())) { 101.21 + return false; 101.22 + } 101.23 + Node* iffm = ctrl->in(0); 101.24 + if (iffm == NULL || !iffm->is_If()) { 101.25 + return false; 101.26 + } 101.27 + Node* bolzm = iffm->in(1); 101.28 + if (bolzm == NULL || !bolzm->is_Bool()) { 101.29 + return false; 101.30 + } 101.31 + Node* cmpzm = bolzm->in(1); 101.32 + if (cmpzm == NULL || !cmpzm->is_Cmp()) { 101.33 + return false; 101.34 + } 101.35 + Node* opqzm = cmpzm->in(2); 101.36 + if (opqzm == NULL || opqzm->Opcode() != Op_Opaque1) { 101.37 + return false; 101.38 + } 101.39 + return true; 101.40 +} 101.41 + 101.42 //------------------------------get_late_ctrl---------------------------------- 101.43 // Compute latest legal control. 101.44 Node *PhaseIdealLoop::get_late_ctrl( Node *n, Node *early ) {
102.1 --- a/src/share/vm/opto/loopnode.hpp Sat Oct 24 16:18:50 2020 +0800 102.2 +++ b/src/share/vm/opto/loopnode.hpp Sat Oct 24 16:43:47 2020 +0800 102.3 @@ -619,6 +619,9 @@ 102.4 bool cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop); 102.5 102.6 public: 102.7 + 102.8 + static bool is_canonical_main_loop_entry(CountedLoopNode* cl); 102.9 + 102.10 bool has_node( Node* n ) const { 102.11 guarantee(n != NULL, "No Node."); 102.12 return _nodes[n->_idx] != NULL; 102.13 @@ -958,9 +961,9 @@ 102.14 // always holds true. That is, either increase the number of iterations in 102.15 // the pre-loop or the post-loop until the condition holds true in the main 102.16 // loop. Scale_con, offset and limit are all loop invariant. 102.17 - void add_constraint( int stride_con, int scale_con, Node *offset, Node *low_limit, Node *upper_limit, Node *pre_ctrl, Node **pre_limit, Node **main_limit ); 102.18 + void add_constraint(jlong stride_con, jlong scale_con, Node* offset, Node* low_limit, Node* upper_limit, Node* pre_ctrl, Node** pre_limit, Node** main_limit); 102.19 // Helper function for add_constraint(). 102.20 - Node* adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl, bool round_up); 102.21 + Node* adjust_limit(bool reduce, Node* scale, Node* offset, Node* rc_limit, Node* old_limit, Node* pre_ctrl, bool round); 102.22 102.23 // Partially peel loop up through last_peel node. 102.24 bool partial_peel( IdealLoopTree *loop, Node_List &old_new );
103.1 --- a/src/share/vm/opto/node.cpp Sat Oct 24 16:18:50 2020 +0800 103.2 +++ b/src/share/vm/opto/node.cpp Sat Oct 24 16:43:47 2020 +0800 103.3 @@ -937,6 +937,17 @@ 103.4 return (Node*) this; 103.5 } 103.6 103.7 +// Find out of current node that matches opcode. 103.8 +Node* Node::find_out_with(int opcode) { 103.9 + for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) { 103.10 + Node* use = fast_out(i); 103.11 + if (use->Opcode() == opcode) { 103.12 + return use; 103.13 + } 103.14 + } 103.15 + return NULL; 103.16 +} 103.17 + 103.18 //---------------------------uncast_helper------------------------------------- 103.19 Node* Node::uncast_helper(const Node* p) { 103.20 #ifdef ASSERT 103.21 @@ -1318,6 +1329,9 @@ 103.22 103.23 while (nstack.size() > 0) { 103.24 dead = nstack.pop(); 103.25 + if (dead->Opcode() == Op_SafePoint) { 103.26 + dead->as_SafePoint()->disconnect_from_root(igvn); 103.27 + } 103.28 if (dead->outcnt() > 0) { 103.29 // Keep dead node on stack until all uses are processed. 103.30 nstack.push(dead);
104.1 --- a/src/share/vm/opto/node.hpp Sat Oct 24 16:18:50 2020 +0800 104.2 +++ b/src/share/vm/opto/node.hpp Sat Oct 24 16:43:47 2020 +0800 104.3 @@ -454,6 +454,9 @@ 104.4 return (this->uncast() == n->uncast()); 104.5 } 104.6 104.7 + // Find out of current node that matches opcode. 104.8 + Node* find_out_with(int opcode); 104.9 + 104.10 private: 104.11 static Node* uncast_helper(const Node* n); 104.12
105.1 --- a/src/share/vm/opto/output.cpp Sat Oct 24 16:18:50 2020 +0800 105.2 +++ b/src/share/vm/opto/output.cpp Sat Oct 24 16:43:47 2020 +0800 105.3 @@ -1715,6 +1715,8 @@ 105.4 } 105.5 if (method() != NULL) { 105.6 method()->print_metadata(); 105.7 + } else if (stub_name() != NULL) { 105.8 + tty->print_cr("Generating RuntimeStub - %s", stub_name()); 105.9 } 105.10 dump_asm(node_offsets, node_offset_limit); 105.11 if (xtty != NULL) {
106.1 --- a/src/share/vm/opto/phaseX.cpp Sat Oct 24 16:18:50 2020 +0800 106.2 +++ b/src/share/vm/opto/phaseX.cpp Sat Oct 24 16:43:47 2020 +0800 106.3 @@ -419,20 +419,6 @@ 106.4 106.5 // Disconnect 'useless' nodes that are adjacent to useful nodes 106.6 C->remove_useless_nodes(_useful); 106.7 - 106.8 - // Remove edges from "root" to each SafePoint at a backward branch. 106.9 - // They were inserted during parsing (see add_safepoint()) to make infinite 106.10 - // loops without calls or exceptions visible to root, i.e., useful. 106.11 - Node *root = C->root(); 106.12 - if( root != NULL ) { 106.13 - for( uint i = root->req(); i < root->len(); ++i ) { 106.14 - Node *n = root->in(i); 106.15 - if( n != NULL && n->is_SafePoint() ) { 106.16 - root->rm_prec(i); 106.17 - --i; 106.18 - } 106.19 - } 106.20 - } 106.21 } 106.22 106.23 //============================================================================= 106.24 @@ -1258,6 +1244,9 @@ 106.25 106.26 while (_stack.is_nonempty()) { 106.27 dead = _stack.node(); 106.28 + if (dead->Opcode() == Op_SafePoint) { 106.29 + dead->as_SafePoint()->disconnect_from_root(this); 106.30 + } 106.31 uint progress_state = _stack.index(); 106.32 assert(dead != C->root(), "killing root, eh?"); 106.33 assert(!dead->is_top(), "add check for top when pushing"); 106.34 @@ -1352,6 +1341,9 @@ 106.35 //------------------------------subsume_node----------------------------------- 106.36 // Remove users from node 'old' and add them to node 'nn'. 106.37 void PhaseIterGVN::subsume_node( Node *old, Node *nn ) { 106.38 + if (old->Opcode() == Op_SafePoint) { 106.39 + old->as_SafePoint()->disconnect_from_root(this); 106.40 + } 106.41 assert( old != hash_find(old), "should already been removed" ); 106.42 assert( old != C->top(), "cannot subsume top node"); 106.43 // Copy debug or profile information to the new version: 106.44 @@ -1653,8 +1645,11 @@ 106.45 if (m->is_Call()) { 106.46 for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) { 106.47 Node* p = m->fast_out(i2); // Propagate changes to uses 106.48 - if (p->is_Proj() && p->as_Proj()->_con == TypeFunc::Control && p->outcnt() == 1) { 106.49 - worklist.push(p->unique_out()); 106.50 + if (p->is_Proj() && p->as_Proj()->_con == TypeFunc::Control) { 106.51 + Node* catch_node = p->find_out_with(Op_Catch); 106.52 + if (catch_node != NULL) { 106.53 + worklist.push(catch_node); 106.54 + } 106.55 } 106.56 } 106.57 }
107.1 --- a/src/share/vm/opto/superword.cpp Sat Oct 24 16:18:50 2020 +0800 107.2 +++ b/src/share/vm/opto/superword.cpp Sat Oct 24 16:43:47 2020 +0800 107.3 @@ -2209,21 +2209,13 @@ 107.4 //----------------------------get_pre_loop_end--------------------------- 107.5 // Find pre loop end from main loop. Returns null if none. 107.6 CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode* cl) { 107.7 - Node* ctrl = cl->in(LoopNode::EntryControl); 107.8 - if (!ctrl->is_IfTrue() && !ctrl->is_IfFalse()) return NULL; 107.9 - Node* iffm = ctrl->in(0); 107.10 - if (!iffm->is_If()) return NULL; 107.11 - Node* bolzm = iffm->in(1); 107.12 - if (!bolzm->is_Bool()) return NULL; 107.13 - Node* cmpzm = bolzm->in(1); 107.14 - if (!cmpzm->is_Cmp()) return NULL; 107.15 - Node* opqzm = cmpzm->in(2); 107.16 - // Can not optimize a loop if zero-trip Opaque1 node is optimized 107.17 - // away and then another round of loop opts attempted. 107.18 - if (opqzm->Opcode() != Op_Opaque1) { 107.19 + // The loop cannot be optimized if the graph shape at 107.20 + // the loop entry is inappropriate. 107.21 + if (!PhaseIdealLoop::is_canonical_main_loop_entry(cl)) { 107.22 return NULL; 107.23 } 107.24 - Node* p_f = iffm->in(0); 107.25 + 107.26 + Node* p_f = cl->in(LoopNode::EntryControl)->in(0)->in(0); 107.27 if (!p_f->is_IfFalse()) return NULL; 107.28 if (!p_f->in(0)->is_CountedLoopEnd()) return NULL; 107.29 CountedLoopEndNode* pre_end = p_f->in(0)->as_CountedLoopEnd();
108.1 --- a/src/share/vm/opto/type.cpp Sat Oct 24 16:18:50 2020 +0800 108.2 +++ b/src/share/vm/opto/type.cpp Sat Oct 24 16:43:47 2020 +0800 108.3 @@ -673,6 +673,35 @@ 108.4 108.5 #endif 108.6 108.7 +void Type::check_symmetrical(const Type *t, const Type *mt) const { 108.8 +#ifdef ASSERT 108.9 + assert(mt == t->xmeet(this), "meet not commutative"); 108.10 + const Type* dual_join = mt->_dual; 108.11 + const Type *t2t = dual_join->xmeet(t->_dual); 108.12 + const Type *t2this = dual_join->xmeet(this->_dual); 108.13 + 108.14 + // Interface meet Oop is Not Symmetric: 108.15 + // Interface:AnyNull meet Oop:AnyNull == Interface:AnyNull 108.16 + // Interface:NotNull meet Oop:NotNull == java/lang/Object:NotNull 108.17 + 108.18 + if( !interface_vs_oop(t) && (t2t != t->_dual || t2this != this->_dual) ) { 108.19 + tty->print_cr("=== Meet Not Symmetric ==="); 108.20 + tty->print("t = "); t->dump(); tty->cr(); 108.21 + tty->print("this= "); dump(); tty->cr(); 108.22 + tty->print("mt=(t meet this)= "); mt->dump(); tty->cr(); 108.23 + 108.24 + tty->print("t_dual= "); t->_dual->dump(); tty->cr(); 108.25 + tty->print("this_dual= "); _dual->dump(); tty->cr(); 108.26 + tty->print("mt_dual= "); mt->_dual->dump(); tty->cr(); 108.27 + 108.28 + tty->print("mt_dual meet t_dual= "); t2t ->dump(); tty->cr(); 108.29 + tty->print("mt_dual meet this_dual= "); t2this ->dump(); tty->cr(); 108.30 + 108.31 + fatal("meet not symmetric" ); 108.32 + } 108.33 +#endif 108.34 +} 108.35 + 108.36 //------------------------------meet------------------------------------------- 108.37 // Compute the MEET of two types. NOT virtual. It enforces that meet is 108.38 // commutative and the lattice is symmetric. 108.39 @@ -690,33 +719,28 @@ 108.40 t = t->maybe_remove_speculative(include_speculative); 108.41 108.42 const Type *mt = this_t->xmeet(t); 108.43 +#ifdef ASSERT 108.44 if (isa_narrowoop() || t->isa_narrowoop()) return mt; 108.45 if (isa_narrowklass() || t->isa_narrowklass()) return mt; 108.46 -#ifdef ASSERT 108.47 - assert(mt == t->xmeet(this_t), "meet not commutative"); 108.48 - const Type* dual_join = mt->_dual; 108.49 - const Type *t2t = dual_join->xmeet(t->_dual); 108.50 - const Type *t2this = dual_join->xmeet(this_t->_dual); 108.51 - 108.52 - // Interface meet Oop is Not Symmetric: 108.53 - // Interface:AnyNull meet Oop:AnyNull == Interface:AnyNull 108.54 - // Interface:NotNull meet Oop:NotNull == java/lang/Object:NotNull 108.55 - 108.56 - if( !interface_vs_oop(t) && (t2t != t->_dual || t2this != this_t->_dual) ) { 108.57 - tty->print_cr("=== Meet Not Symmetric ==="); 108.58 - tty->print("t = "); t->dump(); tty->cr(); 108.59 - tty->print("this= "); this_t->dump(); tty->cr(); 108.60 - tty->print("mt=(t meet this)= "); mt->dump(); tty->cr(); 108.61 - 108.62 - tty->print("t_dual= "); t->_dual->dump(); tty->cr(); 108.63 - tty->print("this_dual= "); this_t->_dual->dump(); tty->cr(); 108.64 - tty->print("mt_dual= "); mt->_dual->dump(); tty->cr(); 108.65 - 108.66 - tty->print("mt_dual meet t_dual= "); t2t ->dump(); tty->cr(); 108.67 - tty->print("mt_dual meet this_dual= "); t2this ->dump(); tty->cr(); 108.68 - 108.69 - fatal("meet not symmetric" ); 108.70 + Compile* C = Compile::current(); 108.71 + if (!C->_type_verify_symmetry) { 108.72 + return mt; 108.73 } 108.74 + this_t->check_symmetrical(t, mt); 108.75 + // In the case of an array, computing the meet above, caused the 108.76 + // computation of the meet of the elements which at verification 108.77 + // time caused the computation of the meet of the dual of the 108.78 + // elements. Computing the meet of the dual of the arrays here 108.79 + // causes the meet of the dual of the elements to be computed which 108.80 + // would cause the meet of the dual of the dual of the elements, 108.81 + // that is the meet of the elements already computed above to be 108.82 + // computed. Avoid redundant computations by requesting no 108.83 + // verification. 108.84 + C->_type_verify_symmetry = false; 108.85 + const Type *mt_dual = this_t->_dual->xmeet(t->_dual); 108.86 + this_t->_dual->check_symmetrical(t->_dual, mt_dual); 108.87 + assert(!C->_type_verify_symmetry, "shouldn't have changed"); 108.88 + C->_type_verify_symmetry = true; 108.89 #endif 108.90 return mt; 108.91 } 108.92 @@ -3971,10 +3995,10 @@ 108.93 (tap->_klass_is_exact && !tap->klass()->is_subtype_of(klass())) || 108.94 // 'this' is exact and super or unrelated: 108.95 (this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) { 108.96 - if (above_centerline(ptr)) { 108.97 + if (above_centerline(ptr) || (tary->_elem->make_ptr() && above_centerline(tary->_elem->make_ptr()->_ptr))) { 108.98 tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable); 108.99 } 108.100 - return make(NotNull, NULL, tary, lazy_klass, false, off, InstanceBot); 108.101 + return make(NotNull, NULL, tary, lazy_klass, false, off, InstanceBot, speculative, depth); 108.102 } 108.103 108.104 bool xk = false;
109.1 --- a/src/share/vm/opto/type.hpp Sat Oct 24 16:18:50 2020 +0800 109.2 +++ b/src/share/vm/opto/type.hpp Sat Oct 24 16:43:47 2020 +0800 109.3 @@ -165,6 +165,7 @@ 109.4 #endif 109.5 109.6 const Type *meet_helper(const Type *t, bool include_speculative) const; 109.7 + void check_symmetrical(const Type *t, const Type *mt) const; 109.8 109.9 protected: 109.10 // Each class of type is also identified by its base.
110.1 --- a/src/share/vm/prims/jniCheck.cpp Sat Oct 24 16:18:50 2020 +0800 110.2 +++ b/src/share/vm/prims/jniCheck.cpp Sat Oct 24 16:43:47 2020 +0800 110.3 @@ -1,5 +1,5 @@ 110.4 /* 110.5 - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. 110.6 + * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. 110.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 110.8 * 110.9 * This code is free software; you can redistribute it and/or modify it 110.10 @@ -437,21 +437,20 @@ 110.11 size_t sz; 110.12 void* orig_result = check_wrapped_array(thr, fn_name, obj, carray, &sz); 110.13 switch (mode) { 110.14 + // As we never make copies, mode 0 and JNI_COMMIT are the same. 110.15 case 0: 110.16 - memcpy(orig_result, carray, sz); 110.17 - GuardedMemory::free_copy(carray); 110.18 - break; 110.19 case JNI_COMMIT: 110.20 memcpy(orig_result, carray, sz); 110.21 break; 110.22 case JNI_ABORT: 110.23 - GuardedMemory::free_copy(carray); 110.24 break; 110.25 default: 110.26 tty->print_cr("%s: Unrecognized mode %i releasing array " 110.27 PTR_FORMAT " elements " PTR_FORMAT, fn_name, mode, p2i(obj), p2i(carray)); 110.28 NativeReportJNIFatalError(thr, "Unrecognized array release mode"); 110.29 } 110.30 + // We always need to release the copy we made with GuardedMemory 110.31 + GuardedMemory::free_copy(carray); 110.32 return orig_result; 110.33 } 110.34
111.1 --- a/src/share/vm/prims/jvm.cpp Sat Oct 24 16:18:50 2020 +0800 111.2 +++ b/src/share/vm/prims/jvm.cpp Sat Oct 24 16:43:47 2020 +0800 111.3 @@ -525,6 +525,17 @@ 111.4 JVM_END 111.5 111.6 111.7 +JVM_ENTRY_NO_ENV(jboolean, JVM_IsUseContainerSupport(void)) 111.8 + JVMWrapper("JVM_IsUseContainerSupport"); 111.9 +#ifdef TARGET_OS_FAMILY_linux 111.10 + if (UseContainerSupport) { 111.11 + return JNI_TRUE; 111.12 + } 111.13 +#endif 111.14 + return JNI_FALSE; 111.15 +JVM_END 111.16 + 111.17 + 111.18 111.19 // java.lang.Throwable ////////////////////////////////////////////////////// 111.20
112.1 --- a/src/share/vm/prims/jvm.h Sat Oct 24 16:18:50 2020 +0800 112.2 +++ b/src/share/vm/prims/jvm.h Sat Oct 24 16:43:47 2020 +0800 112.3 @@ -202,6 +202,9 @@ 112.4 JNIEXPORT jint JNICALL 112.5 JVM_ActiveProcessorCount(void); 112.6 112.7 +JNIEXPORT jboolean JNICALL 112.8 +JVM_IsUseContainerSupport(void); 112.9 + 112.10 JNIEXPORT void * JNICALL 112.11 JVM_LoadLibrary(const char *name); 112.12
113.1 --- a/src/share/vm/prims/nativeLookup.cpp Sat Oct 24 16:18:50 2020 +0800 113.2 +++ b/src/share/vm/prims/nativeLookup.cpp Sat Oct 24 16:43:47 2020 +0800 113.3 @@ -61,27 +61,118 @@ 113.4 #endif 113.5 113.6 113.7 -static void mangle_name_on(outputStream* st, Symbol* name, int begin, int end) { 113.8 +/* 113.9 + 113.10 +The JNI specification defines the mapping from a Java native method name to 113.11 +a C native library implementation function name as follows: 113.12 + 113.13 + The mapping produces a native method name by concatenating the following components 113.14 + derived from a `native` method declaration: 113.15 + 113.16 + 1. the prefix Java_ 113.17 + 2. given the binary name, in internal form, of the class which declares the native method: 113.18 + the result of escaping the name. 113.19 + 3. an underscore ("_") 113.20 + 4. the escaped method name 113.21 + 5. if the native method declaration is overloaded: two underscores ("__") followed by the 113.22 + escaped parameter descriptor (JVMS 4.3.3) of the method declaration. 113.23 + 113.24 + Escaping leaves every alphanumeric ASCII character (A-Za-z0-9) unchanged, and replaces each 113.25 + UTF-16 code unit n the table below with the corresponding escape sequence. If the name to be 113.26 + escaped contains a surrogate pair, then the high-surrogate code unit and the low-surrogate code 113.27 + unit are escaped separately. The result of escaping is a string consisting only of the ASCII 113.28 + characters A-Za-z0-9 and underscore. 113.29 + 113.30 + ------------------------------ ------------------------------------ 113.31 + UTF-16 code unit Escape sequence 113.32 + ------------------------------ ------------------------------------ 113.33 + Forward slash (/, U+002F) _ 113.34 + Underscore (_, U+005F) _1 113.35 + Semicolon (;, U+003B) _2 113.36 + Left square bracket ([, U+005B) _3 113.37 + Any UTF-16 code unit \u_WXYZ_ that does not _0wxyz where w, x, y, and z are the lower-case 113.38 + represent alphanumeric ASCII (A-Za-z0-9), forms of the hexadecimal digits W, X, Y, and Z. 113.39 + forward slash, underscore, semicolon, (For example, U+ABCD becomes _0abcd.) 113.40 + or left square bracket 113.41 + ------------------------------ ------------------------------------ 113.42 + 113.43 + Note that escape sequences can safely begin _0, _1, etc, because class and method 113.44 + names in Java source code never begin with a number. However, that is not the case in 113.45 + class files that were not generated from Java source code. 113.46 + 113.47 + To preserve the 1:1 mapping to a native method name, the VM checks the resulting name as 113.48 + follows. If the process of escaping any precursor string from the native method declaration 113.49 + (class or method name, or argument type) causes a "0", "1", "2", or "3" character 113.50 + from the precursor string to appear unchanged in the result *either* immediately after an 113.51 + underscore *or* at the beginning of the escaped string (where it will follow an underscore 113.52 + in the fully assembled name), then the escaping process is said to have "failed". 113.53 + In such cases, no native library search is performed, and the attempt to link the native 113.54 + method invocation will throw UnsatisfiedLinkError. 113.55 + 113.56 + 113.57 +For example: 113.58 + 113.59 + package/my_class/method 113.60 + 113.61 +and 113.62 + 113.63 + package/my/1class/method 113.64 + 113.65 +both map to 113.66 + 113.67 + Java_package_my_1class_method 113.68 + 113.69 +To address this potential conflict we need only check if the character after 113.70 +/ is a digit 0..3, or if the first character after an injected '_' seperator 113.71 +is a digit 0..3. If we encounter an invalid identifier we reset the 113.72 +stringStream and return false. Otherwise the stringStream contains the mapped 113.73 +name and we return true. 113.74 + 113.75 +To address legacy compatibility, the UseLegacyJNINameEscaping flag can be set 113.76 +which skips the extra checks. 113.77 + 113.78 +*/ 113.79 +static bool map_escaped_name_on(stringStream* st, Symbol* name, int begin, int end) { 113.80 char* bytes = (char*)name->bytes() + begin; 113.81 char* end_bytes = (char*)name->bytes() + end; 113.82 + bool check_escape_char = true; // initially true as first character here follows '_' 113.83 while (bytes < end_bytes) { 113.84 jchar c; 113.85 bytes = UTF8::next(bytes, &c); 113.86 if (c <= 0x7f && isalnum(c)) { 113.87 + if (check_escape_char && (c >= '0' && c <= '3') && 113.88 + !UseLegacyJNINameEscaping) { 113.89 + // This is a non-Java identifier and we won't escape it to 113.90 + // ensure no name collisions with a Java identifier. 113.91 + if (PrintJNIResolving) { 113.92 + ResourceMark rm; 113.93 + tty->print_cr("[Lookup of native method with non-Java identifier rejected: %s]", 113.94 + name->as_C_string()); 113.95 + } 113.96 + st->reset(); // restore to "" on error 113.97 + return false; 113.98 + } 113.99 st->put((char) c); 113.100 + check_escape_char = false; 113.101 } else { 113.102 - if (c == '_') st->print("_1"); 113.103 - else if (c == '/') st->print("_"); 113.104 + check_escape_char = false; 113.105 + if (c == '_') st->print("_1"); 113.106 + else if (c == '/') { 113.107 + st->print("_"); 113.108 + // Following a / we must have non-escape character 113.109 + check_escape_char = true; 113.110 + } 113.111 else if (c == ';') st->print("_2"); 113.112 else if (c == '[') st->print("_3"); 113.113 else st->print("_%.5x", c); 113.114 } 113.115 } 113.116 + return true; 113.117 } 113.118 113.119 113.120 -static void mangle_name_on(outputStream* st, Symbol* name) { 113.121 - mangle_name_on(st, name, 0, name->utf8_length()); 113.122 +static bool map_escaped_name_on(stringStream* st, Symbol* name) { 113.123 + return map_escaped_name_on(st, name, 0, name->utf8_length()); 113.124 } 113.125 113.126 113.127 @@ -90,10 +181,14 @@ 113.128 // Prefix 113.129 st.print("Java_"); 113.130 // Klass name 113.131 - mangle_name_on(&st, method->klass_name()); 113.132 + if (!map_escaped_name_on(&st, method->klass_name())) { 113.133 + return NULL; 113.134 + } 113.135 st.print("_"); 113.136 // Method name 113.137 - mangle_name_on(&st, method->name()); 113.138 + if (!map_escaped_name_on(&st, method->name())) { 113.139 + return NULL; 113.140 + } 113.141 return st.as_string(); 113.142 } 113.143 113.144 @@ -103,16 +198,20 @@ 113.145 // Prefix 113.146 st.print("JavaCritical_"); 113.147 // Klass name 113.148 - mangle_name_on(&st, method->klass_name()); 113.149 + if (!map_escaped_name_on(&st, method->klass_name())) { 113.150 + return NULL; 113.151 + } 113.152 st.print("_"); 113.153 // Method name 113.154 - mangle_name_on(&st, method->name()); 113.155 + if (!map_escaped_name_on(&st, method->name())) { 113.156 + return NULL; 113.157 + } 113.158 return st.as_string(); 113.159 } 113.160 113.161 113.162 char* NativeLookup::long_jni_name(methodHandle method) { 113.163 - // Signature ignore the wrapping parenteses and the trailing return type 113.164 + // Signatures ignore the wrapping parentheses and the trailing return type 113.165 stringStream st; 113.166 Symbol* signature = method->signature(); 113.167 st.print("__"); 113.168 @@ -120,7 +219,10 @@ 113.169 int end; 113.170 for (end = 0; end < signature->utf8_length() && signature->byte_at(end) != ')'; end++); 113.171 // skip first '(' 113.172 - mangle_name_on(&st, signature, 1, end); 113.173 + if (!map_escaped_name_on(&st, signature, 1, end)) { 113.174 + return NULL; 113.175 + } 113.176 + 113.177 return st.as_string(); 113.178 } 113.179 113.180 @@ -247,6 +349,11 @@ 113.181 in_base_library = false; 113.182 // Compute pure name 113.183 char* pure_name = pure_jni_name(method); 113.184 + if (pure_name == NULL) { 113.185 + // JNI name mapping rejected this method so return 113.186 + // NULL to indicate UnsatisfiedLinkError should be thrown. 113.187 + return NULL; 113.188 + } 113.189 113.190 // Compute argument size 113.191 int args_size = 1 // JNIEnv 113.192 @@ -260,6 +367,11 @@ 113.193 113.194 // Compute long name 113.195 char* long_name = long_jni_name(method); 113.196 + if (long_name == NULL) { 113.197 + // JNI name mapping rejected this method so return 113.198 + // NULL to indicate UnsatisfiedLinkError should be thrown. 113.199 + return NULL; 113.200 + } 113.201 113.202 // 2) Try JNI long style 113.203 entry = lookup_style(method, pure_name, long_name, args_size, true, in_base_library, CHECK_NULL); 113.204 @@ -299,6 +411,11 @@ 113.205 113.206 // Compute critical name 113.207 char* critical_name = critical_jni_name(method); 113.208 + if (critical_name == NULL) { 113.209 + // JNI name mapping rejected this method so return 113.210 + // NULL to indicate UnsatisfiedLinkError should be thrown. 113.211 + return NULL; 113.212 + } 113.213 113.214 // Compute argument size 113.215 int args_size = 1 // JNIEnv 113.216 @@ -312,6 +429,11 @@ 113.217 113.218 // Compute long name 113.219 char* long_name = long_jni_name(method); 113.220 + if (long_name == NULL) { 113.221 + // JNI name mapping rejected this method so return 113.222 + // NULL to indicate UnsatisfiedLinkError should be thrown. 113.223 + return NULL; 113.224 + } 113.225 113.226 // 2) Try JNI long style 113.227 entry = lookup_critical_style(method, critical_name, long_name, args_size, true);
114.1 --- a/src/share/vm/runtime/globals.hpp Sat Oct 24 16:18:50 2020 +0800 114.2 +++ b/src/share/vm/runtime/globals.hpp Sat Oct 24 16:43:47 2020 +0800 114.3 @@ -718,6 +718,9 @@ 114.4 product(bool, CriticalJNINatives, true, \ 114.5 "Check for critical JNI entry points") \ 114.6 \ 114.7 + product(bool, UseLegacyJNINameEscaping, false, \ 114.8 + "Use the original JNI name escaping scheme") \ 114.9 + \ 114.10 notproduct(bool, StressCriticalJNINatives, false, \ 114.11 "Exercise register saving code in critical natives") \ 114.12 \ 114.13 @@ -1351,7 +1354,7 @@ 114.14 develop(bool, TraceClassInitialization, false, \ 114.15 "Trace class initialization") \ 114.16 \ 114.17 - develop(bool, TraceExceptions, false, \ 114.18 + product(bool, TraceExceptions, false, \ 114.19 "Trace exceptions") \ 114.20 \ 114.21 develop(bool, TraceICs, false, \ 114.22 @@ -2031,7 +2034,7 @@ 114.23 experimental(uintx, WorkStealingSpinToYieldRatio, 10, \ 114.24 "Ratio of hard spins to calls to yield") \ 114.25 \ 114.26 - develop(uintx, ObjArrayMarkingStride, 512, \ 114.27 + develop(uintx, ObjArrayMarkingStride, 2048, \ 114.28 "Number of object array elements to push onto the marking stack " \ 114.29 "before pushing a continuation entry") \ 114.30 \
115.1 --- a/src/share/vm/runtime/java.hpp Sat Oct 24 16:18:50 2020 +0800 115.2 +++ b/src/share/vm/runtime/java.hpp Sat Oct 24 16:43:47 2020 +0800 115.3 @@ -138,7 +138,7 @@ 115.4 return JDK_Version(m); 115.5 } 115.6 115.7 - static JDK_Version jdk_update(uint8_t major, uint8_t update_number) { 115.8 + static JDK_Version jdk_update(uint8_t major, uint16_t update_number) { 115.9 return JDK_Version(major, 0, 0, update_number); 115.10 } 115.11
116.1 --- a/src/share/vm/runtime/os.cpp Sat Oct 24 16:18:50 2020 +0800 116.2 +++ b/src/share/vm/runtime/os.cpp Sat Oct 24 16:43:47 2020 +0800 116.3 @@ -868,10 +868,9 @@ 116.4 } 116.5 116.6 double t = os::elapsedTime(); 116.7 - // NOTE: It tends to crash after a SEGV if we want to printf("%f",...) in 116.8 - // Linux. Must be a bug in glibc ? Workaround is to round "t" to int 116.9 - // before printf. We lost some precision, but who cares? 116.10 + // NOTE: a crash using printf("%f",...) on Linux was historically noted here. 116.11 int eltime = (int)t; // elapsed time in seconds 116.12 + int eltimeFraction = (int) ((t - eltime) * 1000000); 116.13 116.14 // print elapsed time in a human-readable format: 116.15 int eldays = eltime / secs_per_day; 116.16 @@ -881,7 +880,7 @@ 116.17 int elmins = (eltime - day_secs - hour_secs) / secs_per_min; 116.18 int minute_secs = elmins * secs_per_min; 116.19 int elsecs = (eltime - day_secs - hour_secs - minute_secs); 116.20 - st->print_cr("elapsed time: %d seconds (%dd %dh %dm %ds)", eltime, eldays, elhours, elmins, elsecs); 116.21 + st->print_cr("elapsed time: %d.%06d seconds (%dd %dh %dm %ds)", eltime, eltimeFraction, eldays, elhours, elmins, elsecs); 116.22 } 116.23 116.24 // moved from debug.cpp (used to be find()) but still called from there
117.1 --- a/src/share/vm/runtime/thread.cpp Sat Oct 24 16:18:50 2020 +0800 117.2 +++ b/src/share/vm/runtime/thread.cpp Sat Oct 24 16:43:47 2020 +0800 117.3 @@ -3446,7 +3446,7 @@ 117.4 return status; 117.5 } 117.6 117.7 - JFR_ONLY(Jfr::on_create_vm_1();) 117.8 + JFR_ONLY(Jfr::on_vm_init();) 117.9 117.10 #if defined MIPS && !defined ZERO 117.11 /* 2013/11/5 Jin: To be accessed in NativeGeneralJump::patch_verified_entry() */ 117.12 @@ -3502,16 +3502,12 @@ 117.13 ShouldNotReachHere(); 117.14 } 117.15 117.16 -#if !INCLUDE_JFR 117.17 - // if JFR is not enabled at the build time keep the original JvmtiExport location 117.18 - 117.19 // Always call even when there are not JVMTI environments yet, since environments 117.20 // may be attached late and JVMTI must track phases of VM execution 117.21 JvmtiExport::enter_start_phase(); 117.22 117.23 // Notify JVMTI agents that VM has started (JNI is up) - nop if no agents. 117.24 JvmtiExport::post_vm_start(); 117.25 -#endif 117.26 117.27 { 117.28 TraceTime timer("Initialize java.lang classes", TraceStartupTime); 117.29 @@ -3558,19 +3554,6 @@ 117.30 initialize_class(vmSymbols::java_lang_IllegalArgumentException(), CHECK_0); 117.31 } 117.32 117.33 - JFR_ONLY( 117.34 - Jfr::on_create_vm_2(); 117.35 - 117.36 - // if JFR is enabled at build time the JVMTI needs to be handled only after on_create_vm_2() call 117.37 - 117.38 - // Always call even when there are not JVMTI environments yet, since environments 117.39 - // may be attached late and JVMTI must track phases of VM execution 117.40 - JvmtiExport::enter_start_phase(); 117.41 - 117.42 - // Notify JVMTI agents that VM has started (JNI is up) - nop if no agents. 117.43 - JvmtiExport::post_vm_start(); 117.44 - ) 117.45 - 117.46 // See : bugid 4211085. 117.47 // Background : the static initializer of java.lang.Compiler tries to read 117.48 // property"java.compiler" and read & write property "java.vm.info". 117.49 @@ -3665,7 +3648,7 @@ 117.50 // Notify JVMTI agents that VM initialization is complete - nop if no agents. 117.51 JvmtiExport::post_vm_initialized(); 117.52 117.53 - JFR_ONLY(Jfr::on_create_vm_3();) 117.54 + JFR_ONLY(Jfr::on_vm_start();) 117.55 117.56 if (CleanChunkPoolAsync) { 117.57 Chunk::start_chunk_pool_cleaner_task();
118.1 --- a/src/share/vm/runtime/vm_version.cpp Sat Oct 24 16:18:50 2020 +0800 118.2 +++ b/src/share/vm/runtime/vm_version.cpp Sat Oct 24 16:43:47 2020 +0800 118.3 @@ -242,10 +242,26 @@ 118.4 #define HOTSPOT_BUILD_COMPILER "MS VC++ 12.0 (VS2013)" 118.5 #elif _MSC_VER == 1900 118.6 #define HOTSPOT_BUILD_COMPILER "MS VC++ 14.0 (VS2015)" 118.7 + #elif _MSC_VER == 1911 118.8 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.3 (VS2017)" 118.9 #elif _MSC_VER == 1912 118.10 #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.5 (VS2017)" 118.11 #elif _MSC_VER == 1913 118.12 #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.6 (VS2017)" 118.13 + #elif _MSC_VER == 1914 118.14 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.7 (VS2017)" 118.15 + #elif _MSC_VER == 1915 118.16 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.8 (VS2017)" 118.17 + #elif _MSC_VER == 1916 118.18 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.9 (VS2017)" 118.19 + #elif _MSC_VER == 1920 118.20 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 16.0 (VS2019)" 118.21 + #elif _MSC_VER == 1921 118.22 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 16.1 (VS2019)" 118.23 + #elif _MSC_VER == 1922 118.24 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 16.2 (VS2019)" 118.25 + #elif _MSC_VER == 1923 118.26 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 16.3 (VS2019)" 118.27 #else 118.28 #define HOTSPOT_BUILD_COMPILER "unknown MS VC++:" XSTR(_MSC_VER) 118.29 #endif
119.1 --- a/src/share/vm/services/jmm.h Sat Oct 24 16:18:50 2020 +0800 119.2 +++ b/src/share/vm/services/jmm.h Sat Oct 24 16:43:47 2020 +0800 119.3 @@ -1,5 +1,5 @@ 119.4 /* 119.5 - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 119.6 + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. 119.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 119.8 * 119.9 * This code is free software; you can redistribute it and/or modify it 119.10 @@ -143,7 +143,8 @@ 119.11 JMM_VMGLOBAL_TYPE_UNKNOWN = 0, 119.12 JMM_VMGLOBAL_TYPE_JBOOLEAN = 1, 119.13 JMM_VMGLOBAL_TYPE_JSTRING = 2, 119.14 - JMM_VMGLOBAL_TYPE_JLONG = 3 119.15 + JMM_VMGLOBAL_TYPE_JLONG = 3, 119.16 + JMM_VMGLOBAL_TYPE_JDOUBLE = 4 119.17 } jmmVMGlobalType; 119.18 119.19 typedef enum {
120.1 --- a/src/share/vm/services/management.cpp Sat Oct 24 16:18:50 2020 +0800 120.2 +++ b/src/share/vm/services/management.cpp Sat Oct 24 16:43:47 2020 +0800 120.3 @@ -1578,6 +1578,9 @@ 120.4 } else if (flag->is_uint64_t()) { 120.5 global->value.j = (jlong)flag->get_uint64_t(); 120.6 global->type = JMM_VMGLOBAL_TYPE_JLONG; 120.7 + } else if (flag->is_double()) { 120.8 + global->value.d = (jdouble)flag->get_double(); 120.9 + global->type = JMM_VMGLOBAL_TYPE_JDOUBLE; 120.10 } else if (flag->is_ccstr()) { 120.11 Handle str = java_lang_String::create_from_str(flag->get_ccstr(), CHECK_false); 120.12 global->value.l = (jobject)JNIHandles::make_local(env, str());
121.1 --- a/src/share/vm/utilities/constantTag.cpp Sat Oct 24 16:18:50 2020 +0800 121.2 +++ b/src/share/vm/utilities/constantTag.cpp Sat Oct 24 16:43:47 2020 +0800 121.3 @@ -76,6 +76,20 @@ 121.4 } 121.5 121.6 121.7 +jbyte constantTag::error_value() const { 121.8 + switch (_tag) { 121.9 + case JVM_CONSTANT_UnresolvedClass: 121.10 + return JVM_CONSTANT_UnresolvedClassInError; 121.11 + case JVM_CONSTANT_MethodHandle: 121.12 + return JVM_CONSTANT_MethodHandleInError; 121.13 + case JVM_CONSTANT_MethodType: 121.14 + return JVM_CONSTANT_MethodTypeInError; 121.15 + default: 121.16 + ShouldNotReachHere(); 121.17 + return JVM_CONSTANT_Invalid; 121.18 + } 121.19 +} 121.20 + 121.21 const char* constantTag::internal_name() const { 121.22 switch (_tag) { 121.23 case JVM_CONSTANT_Invalid :
122.1 --- a/src/share/vm/utilities/constantTag.hpp Sat Oct 24 16:18:50 2020 +0800 122.2 +++ b/src/share/vm/utilities/constantTag.hpp Sat Oct 24 16:43:47 2020 +0800 122.3 @@ -1,5 +1,5 @@ 122.4 /* 122.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 122.6 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 122.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 122.8 * 122.9 * This code is free software; you can redistribute it and/or modify it 122.10 @@ -109,6 +109,7 @@ 122.11 } 122.12 122.13 jbyte value() const { return _tag; } 122.14 + jbyte error_value() const; 122.15 jbyte non_error_value() const; 122.16 122.17 BasicType basic_type() const; // if used with ldc, what kind of value gets pushed?
123.1 --- a/src/share/vm/utilities/globalDefinitions.hpp Sat Oct 24 16:18:50 2020 +0800 123.2 +++ b/src/share/vm/utilities/globalDefinitions.hpp Sat Oct 24 16:43:47 2020 +0800 123.3 @@ -1067,6 +1067,7 @@ 123.4 const intptr_t badAddressVal = -2; // generic "bad address" value 123.5 const intptr_t badOopVal = -1; // generic "bad oop" value 123.6 const intptr_t badHeapOopVal = (intptr_t) CONST64(0x2BAD4B0BBAADBABE); // value used to zap heap after GC 123.7 +const int badStackSegVal = 0xCA; // value used to zap stack segments 123.8 const int badHandleValue = 0xBC; // value used to zap vm handle area 123.9 const int badResourceValue = 0xAB; // value used to zap resource area 123.10 const int freeBlockPad = 0xBA; // value used to pad freed blocks.
124.1 --- a/src/share/vm/utilities/stack.inline.hpp Sat Oct 24 16:18:50 2020 +0800 124.2 +++ b/src/share/vm/utilities/stack.inline.hpp Sat Oct 24 16:43:47 2020 +0800 124.3 @@ -26,6 +26,7 @@ 124.4 #define SHARE_VM_UTILITIES_STACK_INLINE_HPP 124.5 124.6 #include "utilities/stack.hpp" 124.7 +#include "utilities/copy.hpp" 124.8 124.9 template <MEMFLAGS F> StackBase<F>::StackBase(size_t segment_size, size_t max_cache_size, 124.10 size_t max_size): 124.11 @@ -227,11 +228,7 @@ 124.12 { 124.13 if (!ZapStackSegments) return; 124.14 const size_t zap_bytes = segment_bytes() - (zap_link_field ? 0 : sizeof(E*)); 124.15 - uint32_t* cur = (uint32_t*)seg; 124.16 - const uint32_t* end = cur + zap_bytes / sizeof(uint32_t); 124.17 - while (cur < end) { 124.18 - *cur++ = 0xfadfaded; 124.19 - } 124.20 + Copy::fill_to_bytes(seg, zap_bytes, badStackSegVal); 124.21 } 124.22 #endif 124.23
125.1 --- a/src/share/vm/utilities/taskqueue.hpp Sat Oct 24 16:18:50 2020 +0800 125.2 +++ b/src/share/vm/utilities/taskqueue.hpp Sat Oct 24 16:43:47 2020 +0800 125.3 @@ -381,7 +381,8 @@ 125.4 // index, &_elems[index], _elems[index]); 125.5 E* t = (E*)&_elems[index]; // cast away volatility 125.6 oop* p = (oop*)t; 125.7 - assert((*t)->is_oop_or_null(), "Not an oop or null"); 125.8 + // G1 does its own checking 125.9 + assert(UseG1GC || (*t)->is_oop_or_null(), "Not an oop or null"); 125.10 f->do_oop(p); 125.11 } 125.12 // tty->print_cr("END OopTaskQueue::oops_do");
126.1 --- a/test/compiler/7177917/Test7177917.java Sat Oct 24 16:18:50 2020 +0800 126.2 +++ b/test/compiler/7177917/Test7177917.java Sat Oct 24 16:43:47 2020 +0800 126.3 @@ -22,8 +22,12 @@ 126.4 * 126.5 */ 126.6 126.7 -/* 126.8 - * Micro-benchmark for Math.pow() and Math.exp() 126.9 +/** 126.10 + * @test 126.11 + * @bug 7177917 126.12 + * @summary Micro-benchmark for Math.pow() and Math.exp() 126.13 + * 126.14 + * @run main Test7177917 126.15 */ 126.16 126.17 import java.util.*;
127.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 127.2 +++ b/test/compiler/conversions/Conversion.jasm Sat Oct 24 16:43:47 2020 +0800 127.3 @@ -0,0 +1,130 @@ 127.4 +/* 127.5 + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 127.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 127.7 + * 127.8 + * This code is free software; you can redistribute it and/or modify it 127.9 + * under the terms of the GNU General Public License version 2 only, as 127.10 + * published by the Free Software Foundation. 127.11 + * 127.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 127.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 127.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 127.15 + * version 2 for more details (a copy is included in the LICENSE file that 127.16 + * accompanied this code). 127.17 + * 127.18 + * You should have received a copy of the GNU General Public License version 127.19 + * 2 along with this work; if not, write to the Free Software Foundation, 127.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 127.21 + * 127.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 127.23 + * or visit www.oracle.com if you need additional information or have any 127.24 + * questions. 127.25 + */ 127.26 + 127.27 +package compiler/conversions; 127.28 + 127.29 +public class Conversion 127.30 + version 52:0 127.31 +{ 127.32 + Field booleanFld:Z; 127.33 + Field byteFld:B; 127.34 + Field charFld:C; 127.35 + Field shortFld:S; 127.36 + Field intFld:I; 127.37 + 127.38 + public Method "<init>":"()V" 127.39 + stack 1 locals 1 127.40 + { 127.41 + aload_0; 127.42 + invokespecial Method java/lang/Object."<init>":"()V"; 127.43 + return; 127.44 + } 127.45 + 127.46 + public Method testBooleanConst:"()I" 127.47 + stack 5 locals 1 127.48 + { 127.49 + aload_0; 127.50 + ldc_w int 2; // 2^1 (maximum boolean value is 1) 127.51 + putfield Field booleanFld:"Z"; 127.52 + aload_0; 127.53 + getfield Field booleanFld:"Z"; 127.54 + ireturn; 127.55 + } 127.56 + 127.57 + public Method testBoolean:"(I)I" 127.58 + stack 5 locals 2 127.59 + { 127.60 + aload_0; 127.61 + iload_1; 127.62 + putfield Field booleanFld:"Z"; 127.63 + aload_0; 127.64 + getfield Field booleanFld:"Z"; 127.65 + ireturn; 127.66 + } 127.67 + 127.68 + public Method testByteConst:"()I" 127.69 + stack 5 locals 1 127.70 + { 127.71 + aload_0; 127.72 + ldc_w int 256; // 2^8 (maximum byte value is 2^7-1) 127.73 + putfield Field byteFld:"B"; 127.74 + aload_0; 127.75 + getfield Field byteFld:"B"; 127.76 + ireturn; 127.77 + } 127.78 + 127.79 + public Method testByte:"(I)I" 127.80 + stack 5 locals 2 127.81 + { 127.82 + aload_0; 127.83 + iload_1; 127.84 + putfield Field byteFld:"B"; 127.85 + aload_0; 127.86 + getfield Field byteFld:"B"; 127.87 + ireturn; 127.88 + } 127.89 + 127.90 + public Method testCharConst:"()I" 127.91 + stack 5 locals 1 127.92 + { 127.93 + aload_0; 127.94 + ldc_w int 131072; // 2^17 (maximum char value is 2^16-1) 127.95 + putfield Field charFld:"C"; 127.96 + aload_0; 127.97 + getfield Field charFld:"C"; 127.98 + ireturn; 127.99 + } 127.100 + 127.101 + public Method testChar:"(I)I" 127.102 + stack 5 locals 2 127.103 + { 127.104 + aload_0; 127.105 + iload_1; 127.106 + putfield Field charFld:"C"; 127.107 + aload_0; 127.108 + getfield Field charFld:"C"; 127.109 + ireturn; 127.110 + } 127.111 + 127.112 + public Method testShortConst:"()I" 127.113 + stack 5 locals 1 127.114 + { 127.115 + aload_0; 127.116 + ldc_w int 65536; // 2^16 (maximum short value is 2^15-1) 127.117 + putfield Field shortFld:"S"; 127.118 + aload_0; 127.119 + getfield Field shortFld:"S"; 127.120 + ireturn; 127.121 + } 127.122 + 127.123 + public Method testShort:"(I)I" 127.124 + stack 5 locals 2 127.125 + { 127.126 + aload_0; 127.127 + iload_1; 127.128 + putfield Field shortFld:"S"; 127.129 + aload_0; 127.130 + getfield Field shortFld:"S"; 127.131 + ireturn; 127.132 + } 127.133 +}
128.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 128.2 +++ b/test/compiler/conversions/TestPrimitiveConversions.java Sat Oct 24 16:43:47 2020 +0800 128.3 @@ -0,0 +1,60 @@ 128.4 +/* 128.5 + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 128.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 128.7 + * 128.8 + * This code is free software; you can redistribute it and/or modify it 128.9 + * under the terms of the GNU General Public License version 2 only, as 128.10 + * published by the Free Software Foundation. 128.11 + * 128.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 128.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 128.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 128.15 + * version 2 for more details (a copy is included in the LICENSE file that 128.16 + * accompanied this code). 128.17 + * 128.18 + * You should have received a copy of the GNU General Public License version 128.19 + * 2 along with this work; if not, write to the Free Software Foundation, 128.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 128.21 + * 128.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 128.23 + * or visit www.oracle.com if you need additional information or have any 128.24 + * questions. 128.25 + */ 128.26 + 128.27 +package compiler.conversions; 128.28 + 128.29 +import com.oracle.java.testlibrary.Asserts; 128.30 + 128.31 +/* 128.32 + * @test 128.33 + * @bug 8234617 128.34 + * @summary Test implicit narrowing conversion of primivite values at putfield. 128.35 + * @library /testlibrary 128.36 + * @compile Conversion.jasm 128.37 + * @run main/othervm -Xbatch -XX:CompileCommand=dontinline,compiler.conversions.Conversion::* 128.38 + * compiler.conversions.TestPrimitiveConversions 128.39 + */ 128.40 +public class TestPrimitiveConversions { 128.41 + 128.42 + public static void main(String[] args) { 128.43 + Conversion conv = new Conversion(); 128.44 + for (int i = 0; i < 100_000; ++i) { 128.45 + int res = conv.testBooleanConst(); 128.46 + Asserts.assertEquals(res, 0); 128.47 + res = conv.testBoolean(2); // 2^1 (maximum boolean value is 1) 128.48 + Asserts.assertEquals(res, 0); 128.49 + res = conv.testByteConst(); 128.50 + Asserts.assertEquals(res, 0); 128.51 + res = conv.testByte(256); // 2^8 (maximum byte value is 2^7-1) 128.52 + Asserts.assertEquals(res, 0); 128.53 + res = conv.testCharConst(); 128.54 + Asserts.assertEquals(res, 0); 128.55 + res = conv.testChar(131072); // 2^17 (maximum char value is 2^16-1) 128.56 + Asserts.assertEquals(res, 0); 128.57 + res = conv.testShortConst(); 128.58 + Asserts.assertEquals(res, 0); 128.59 + res = conv.testShort(65536); // 2^16 (maximum short value is 2^15-1) 128.60 + Asserts.assertEquals(res, 0); 128.61 + } 128.62 + } 128.63 +}
129.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 129.2 +++ b/test/compiler/inlining/StringConcatInfiniteLoop.java Sat Oct 24 16:43:47 2020 +0800 129.3 @@ -0,0 +1,54 @@ 129.4 +/* 129.5 + * Copyright (c) 2018, Red Hat, Inc. All rights reserved. 129.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 129.7 + * 129.8 + * This code is free software; you can redistribute it and/or modify it 129.9 + * under the terms of the GNU General Public License version 2 only, as 129.10 + * published by the Free Software Foundation. 129.11 + * 129.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 129.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 129.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 129.15 + * version 2 for more details (a copy is included in the LICENSE file that 129.16 + * accompanied this code). 129.17 + * 129.18 + * You should have received a copy of the GNU General Public License version 129.19 + * 2 along with this work; if not, write to the Free Software Foundation, 129.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 129.21 + * 129.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 129.23 + * or visit www.oracle.com if you need additional information or have any 129.24 + * questions. 129.25 + */ 129.26 + 129.27 +/* 129.28 + * @test 8214862 129.29 + * @summary Multiple passes of PhaseRemoveUseless causes infinite loop to be optimized out 129.30 + * 129.31 + * @run main/othervm -XX:-TieredCompilation -Xcomp -XX:CompileOnly=StringConcatInfiniteLoop::test -XX:CompileCommand=dontinline,*StringBuilder::* StringConcatInfiniteLoop 129.32 + * 129.33 + */ 129.34 + 129.35 +public class StringConcatInfiniteLoop { 129.36 + public static void main(String[] args) { 129.37 + StringBuilder sb = new StringBuilder(); 129.38 + test(sb, "foo", "bar", true); 129.39 + } 129.40 + 129.41 + private static void test(Object v, String s1, String s2, boolean flag) { 129.42 + if (flag) { 129.43 + return; 129.44 + } 129.45 + int i = 0; 129.46 + for (; i < 10; i++); 129.47 + if (i == 10) { 129.48 + v = null; 129.49 + } 129.50 + StringBuilder sb = new StringBuilder(s1); 129.51 + sb.append(s2); 129.52 + while (v == null); 129.53 + } 129.54 + 129.55 + private static class A { 129.56 + } 129.57 +}
130.1 --- a/test/compiler/tiered/NonTieredLevelsTest.java Sat Oct 24 16:18:50 2020 +0800 130.2 +++ b/test/compiler/tiered/NonTieredLevelsTest.java Sat Oct 24 16:43:47 2020 +0800 130.3 @@ -46,8 +46,7 @@ 130.4 } else if (vmName.endsWith(" Client VM") 130.5 || vmName.endsWith(" Minimal VM")) { 130.6 AVAILABLE_COMP_LEVEL = COMP_LEVEL_SIMPLE; 130.7 - IS_AVAILABLE_COMPLEVEL = x -> x >= COMP_LEVEL_SIMPLE 130.8 - && x <= COMP_LEVEL_FULL_PROFILE; 130.9 + IS_AVAILABLE_COMPLEVEL = x -> x == COMP_LEVEL_SIMPLE; 130.10 } else { 130.11 throw new RuntimeException("Unknown VM: " + vmName); 130.12 }
131.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 131.2 +++ b/test/compiler/types/TestArrayMeetNotSymmetrical.java Sat Oct 24 16:43:47 2020 +0800 131.3 @@ -0,0 +1,70 @@ 131.4 +/* 131.5 + * Copyright (c) 2020, Red Hat, Inc. All rights reserved. 131.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 131.7 + * 131.8 + * This code is free software; you can redistribute it and/or modify it 131.9 + * under the terms of the GNU General Public License version 2 only, as 131.10 + * published by the Free Software Foundation. 131.11 + * 131.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 131.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 131.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 131.15 + * version 2 for more details (a copy is included in the LICENSE file that 131.16 + * accompanied this code). 131.17 + * 131.18 + * You should have received a copy of the GNU General Public License version 131.19 + * 2 along with this work; if not, write to the Free Software Foundation, 131.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 131.21 + * 131.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 131.23 + * or visit www.oracle.com if you need additional information or have any 131.24 + * questions. 131.25 + */ 131.26 + 131.27 +/** 131.28 + * @test 131.29 + * @bug 8240676 131.30 + * @summary Meet not symmetric failure when running lucene on jdk8 131.31 + * 131.32 + * @run main/othervm -XX:-BackgroundCompilation TestArrayMeetNotSymmetrical 131.33 + * 131.34 + */ 131.35 + 131.36 +public class TestArrayMeetNotSymmetrical { 131.37 + private static final Object field = new Object[0]; 131.38 + private static final Object field2 = new A[0]; 131.39 + 131.40 + public static void main(String[] args) { 131.41 + Object array = new A[10]; 131.42 + for (int i = 0; i < 20_000; i++) { 131.43 + test1(true, 10); 131.44 + test1(false, 10); 131.45 + test2(true); 131.46 + test2(false); 131.47 + } 131.48 + } 131.49 + 131.50 + private static Object test1(boolean flag, int len) { 131.51 + Object o; 131.52 + if (flag) { 131.53 + o = field; 131.54 + } else { 131.55 + o = new A[len]; 131.56 + } 131.57 + return o; 131.58 + } 131.59 + 131.60 + private static Object test2(boolean flag) { 131.61 + Object o; 131.62 + if (flag) { 131.63 + o = field; 131.64 + } else { 131.65 + o = field2; 131.66 + } 131.67 + return o; 131.68 + } 131.69 + 131.70 + 131.71 + private static class A { 131.72 + } 131.73 +}
132.1 --- a/test/runtime/8233197/T.java Sat Oct 24 16:18:50 2020 +0800 132.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 132.3 @@ -1,11 +0,0 @@ 132.4 -public class T 132.5 -{ 132.6 - public static void main(String[] args) throws Exception 132.7 - { 132.8 - for (int i = 0; i < 50; i++) { 132.9 - System.out.print("+"); 132.10 - Thread.sleep(1); 132.11 - } 132.12 - System.out.println(); 132.13 - } 132.14 -}
133.1 --- a/test/runtime/8233197/Test8233197.sh Sat Oct 24 16:18:50 2020 +0800 133.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 133.3 @@ -1,153 +0,0 @@ 133.4 -#!/bin/sh 133.5 - 133.6 -# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 133.7 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 133.8 -# 133.9 -# This code is free software; you can redistribute it and/or modify it 133.10 -# under the terms of the GNU General Public License version 2 only, as 133.11 -# published by the Free Software Foundation. 133.12 -# 133.13 -# This code is distributed in the hope that it will be useful, but WITHOUT 133.14 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 133.15 -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 133.16 -# version 2 for more details (a copy is included in the LICENSE file that 133.17 -# accompanied this code). 133.18 -# 133.19 -# You should have received a copy of the GNU General Public License version 133.20 -# 2 along with this work; if not, write to the Free Software Foundation, 133.21 -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 133.22 -# 133.23 -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 133.24 -# or visit www.oracle.com if you need additional information or have any 133.25 -# questions. 133.26 - 133.27 -## 133.28 -## @test Test8233197.sh 133.29 -## @bug 8233197 133.30 -## @summary Check that JFR subsystem can be initialized from VMStart JVMTI event 133.31 -## @compile T.java 133.32 -## @run shell Test8233197.sh 133.33 -## 133.34 - 133.35 -set -x 133.36 -if [ "${TESTSRC}" = "" ] 133.37 -then 133.38 - TESTSRC=${PWD} 133.39 - echo "TESTSRC not set. Using "${TESTSRC}" as default" 133.40 -fi 133.41 -echo "TESTSRC=${TESTSRC}" 133.42 -## Adding common setup Variables for running shell tests. 133.43 -. ${TESTSRC}/../../test_env.sh 133.44 - 133.45 -# set platform-dependent variables 133.46 -OS=`uname -s` 133.47 -case "$OS" in 133.48 - Linux) 133.49 - gcc_cmd=`which gcc` 133.50 - if [ "x$gcc_cmd" == "x" ]; then 133.51 - echo "WARNING: gcc not found. Cannot execute test." 2>&1 133.52 - exit 0; 133.53 - fi 133.54 - NULL=/dev/null 133.55 - PS=":" 133.56 - FS="/" 133.57 - ;; 133.58 - * ) 133.59 - echo "Test passed; only valid for Linux" 133.60 - exit 0; 133.61 - ;; 133.62 -esac 133.63 - 133.64 -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xinternalversion > vm_version.out 2>&1 133.65 - 133.66 -# Bitness: 133.67 -# Cannot simply look at TESTVMOPTS as -d64 is not 133.68 -# passed if there is only a 64-bit JVM available. 133.69 - 133.70 -grep "64-Bit" vm_version.out > ${NULL} 133.71 -if [ "$?" = "0" ] 133.72 -then 133.73 - COMP_FLAG="-m64" 133.74 -else 133.75 - COMP_FLAG="-m32" 133.76 -fi 133.77 - 133.78 - 133.79 -# Architecture: 133.80 -# Translate uname output to JVM directory name, but permit testing 133.81 -# 32-bit x86 on an x64 platform. 133.82 -ARCH=`uname -m` 133.83 -case "$ARCH" in 133.84 - x86_64) 133.85 - if [ "$COMP_FLAG" = "-m32" ]; then 133.86 - ARCH=i386 133.87 - else 133.88 - ARCH=amd64 133.89 - fi 133.90 - ;; 133.91 - ppc64) 133.92 - if [ "$COMP_FLAG" = "-m32" ]; then 133.93 - ARCH=ppc 133.94 - else 133.95 - ARCH=ppc64 133.96 - fi 133.97 - ;; 133.98 - sparc64) 133.99 - if [ "$COMP_FLAG" = "-m32" ]; then 133.100 - ARCH=sparc 133.101 - else 133.102 - ARCH=sparc64 133.103 - fi 133.104 - ;; 133.105 - arm*) 133.106 - # 32-bit ARM machine: compiler may not recognise -m32 133.107 - COMP_FLAG="" 133.108 - ARCH=arm 133.109 - ;; 133.110 - aarch64) 133.111 - # 64-bit arm machine, could be testing 32 or 64-bit: 133.112 - if [ "$COMP_FLAG" = "-m32" ]; then 133.113 - ARCH=arm 133.114 - else 133.115 - ARCH=aarch64 133.116 - fi 133.117 - ;; 133.118 - i586) 133.119 - ARCH=i386 133.120 - ;; 133.121 - i686) 133.122 - ARCH=i386 133.123 - ;; 133.124 - # Assuming other ARCH values need no translation 133.125 -esac 133.126 - 133.127 - 133.128 -# VM type: need to know server or client 133.129 -VMTYPE=client 133.130 -grep Server vm_version.out > ${NULL} 133.131 -if [ "$?" = "0" ] 133.132 -then 133.133 - VMTYPE=server 133.134 -fi 133.135 - 133.136 - 133.137 -LD_LIBRARY_PATH=.:${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE}:/usr/lib:$LD_LIBRARY_PATH 133.138 -export LD_LIBRARY_PATH 133.139 - 133.140 -cp ${TESTSRC}${FS}libJvmtiAgent.c . 133.141 - 133.142 -# Copy the result of our @compile action: 133.143 -cp ${TESTCLASSES}${FS}T.class . 133.144 - 133.145 -echo "Architecture: ${ARCH}" 133.146 -echo "Compilation flag: ${COMP_FLAG}" 133.147 -echo "VM type: ${VMTYPE}" 133.148 - 133.149 -$gcc_cmd -DLINUX ${COMP_FLAG} -Wl, -g -fno-strict-aliasing -fPIC -fno-omit-frame-pointer -W -Wall -Wno-unused -Wno-parentheses -c -o libJvmtiAgent.o \ 133.150 - -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \ 133.151 - -L${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE} \ 133.152 - libJvmtiAgent.c 133.153 -$gcc_cmd -shared -o libJvmtiAgent.so libJvmtiAgent.o 133.154 - 133.155 -"$TESTJAVA/bin/java" $TESTVMOPTS -agentlib:JvmtiAgent -cp $(pwd) T > T.out 133.156 -exit $? 133.157 \ No newline at end of file
134.1 --- a/test/runtime/8233197/libJvmtiAgent.c Sat Oct 24 16:18:50 2020 +0800 134.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 134.3 @@ -1,124 +0,0 @@ 134.4 -/* 134.5 - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 134.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 134.7 - * 134.8 - * This code is free software; you can redistribute it and/or modify it 134.9 - * under the terms of the GNU General Public License version 2 only, as 134.10 - * published by the Free Software Foundation. 134.11 - * 134.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 134.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 134.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 134.15 - * version 2 for more details (a copy is included in the LICENSE file that 134.16 - * accompanied this code). 134.17 - * 134.18 - * You should have received a copy of the GNU General Public License version 134.19 - * 2 along with this work; if not, write to the Free Software Foundation, 134.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 134.21 - * 134.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 134.23 - * or visit www.oracle.com if you need additional information or have any 134.24 - * questions. 134.25 - */ 134.26 - 134.27 -#include <stdio.h> 134.28 -#include <stdlib.h> 134.29 -#include <string.h> 134.30 -#include "jvmti.h" 134.31 - 134.32 -#ifdef __cplusplus 134.33 -extern "C" { 134.34 -#endif 134.35 - 134.36 -#ifndef JNI_ENV_ARG 134.37 - 134.38 -#ifdef __cplusplus 134.39 -#define JNI_ENV_ARG(x, y) y 134.40 -#define JNI_ENV_PTR(x) x 134.41 -#else 134.42 -#define JNI_ENV_ARG(x,y) x, y 134.43 -#define JNI_ENV_PTR(x) (*x) 134.44 -#endif 134.45 - 134.46 -#endif 134.47 - 134.48 -#define TranslateError(err) "JVMTI error" 134.49 - 134.50 -static jvmtiEnv *jvmti = NULL; 134.51 - 134.52 -static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved); 134.53 - 134.54 -JNIEXPORT 134.55 -jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) { 134.56 - return Agent_Initialize(jvm, options, reserved); 134.57 -} 134.58 - 134.59 -JNIEXPORT 134.60 -jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) { 134.61 - return Agent_Initialize(jvm, options, reserved); 134.62 -} 134.63 - 134.64 -JNIEXPORT 134.65 -jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) { 134.66 - return JNI_VERSION_1_8; 134.67 -} 134.68 - 134.69 -static void JNICALL 134.70 -Callback_VMStart(jvmtiEnv *jvmti_env, JNIEnv *env) { 134.71 - printf("Localizing jdk.jfr.FlightRecorder\n"); 134.72 - // without fix for 8233197 the process will crash at the following line 134.73 - jclass cls = (*env)->FindClass(env, "jdk/jfr/FlightRecorder"); 134.74 - jmethodID mid = (*env)->GetStaticMethodID(env, cls, "getFlightRecorder", "()Ljdk/jfr/FlightRecorder;"); 134.75 - if (mid == 0) { 134.76 - printf("Unable to localize jdk.jfr.FlightRecorder#getFlightRecorder() method\n"); 134.77 - // crash the tested JVM to make the test fail 134.78 - exit(-1); 134.79 - } 134.80 - printf("Going to initialize JFR subsystem ...\n"); 134.81 - jobject jfr = (*env)->CallStaticObjectMethod(env, cls, mid); 134.82 - 134.83 - if (!(*env)->ExceptionCheck(env)) { 134.84 - // crash the tested JVM to make the test fail 134.85 - printf("JFR subsystem is wrongly initialized too early\n"); 134.86 - exit(-2); 134.87 - } 134.88 - // exit VM 134.89 - exit(0); 134.90 -} 134.91 - 134.92 -static 134.93 -jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 134.94 - jint res, size; 134.95 - jvmtiCapabilities caps; 134.96 - jvmtiEventCallbacks callbacks; 134.97 - jvmtiError err; 134.98 - 134.99 - res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti), 134.100 - JVMTI_VERSION_1_2); 134.101 - if (res != JNI_OK || jvmti == NULL) { 134.102 - printf(" Error: wrong result of a valid call to GetEnv!\n"); 134.103 - return JNI_ERR; 134.104 - } 134.105 - 134.106 - size = (jint)sizeof(callbacks); 134.107 - 134.108 - memset(&callbacks, 0, sizeof(callbacks)); 134.109 - callbacks.VMStart = Callback_VMStart; 134.110 - 134.111 - err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, size); 134.112 - if (err != JVMTI_ERROR_NONE) { 134.113 - printf(" Error in SetEventCallbacks: %s (%d)\n", TranslateError(err), err); 134.114 - return JNI_ERR; 134.115 - } 134.116 - 134.117 - err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_START, (jthread)NULL); 134.118 - if (err != JVMTI_ERROR_NONE) { 134.119 - printf(" Error in SetEventNotificationMode: %s (%d)\n", TranslateError(err), err); 134.120 - return JNI_ERR; 134.121 - } 134.122 - return JNI_OK; 134.123 -} 134.124 - 134.125 -#ifdef __cplusplus 134.126 -} 134.127 -#endif
135.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 135.2 +++ b/test/runtime/ClassResolutionFail/Property.java Sat Oct 24 16:43:47 2020 +0800 135.3 @@ -0,0 +1,27 @@ 135.4 +/* 135.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 135.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 135.7 + * 135.8 + * This code is free software; you can redistribute it and/or modify it 135.9 + * under the terms of the GNU General Public License version 2 only, as 135.10 + * published by the Free Software Foundation. 135.11 + * 135.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 135.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 135.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 135.15 + * version 2 for more details (a copy is included in the LICENSE file that 135.16 + * accompanied this code). 135.17 + * 135.18 + * You should have received a copy of the GNU General Public License version 135.19 + * 2 along with this work; if not, write to the Free Software Foundation, 135.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 135.21 + * 135.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 135.23 + * or visit www.oracle.com if you need additional information or have any 135.24 + * questions. 135.25 + */ 135.26 + 135.27 +// Class PropertySuper is not found. 135.28 + 135.29 +public class Property extends PropertySuper { 135.30 +}
136.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 136.2 +++ b/test/runtime/ClassResolutionFail/PropertySuper.java Sat Oct 24 16:43:47 2020 +0800 136.3 @@ -0,0 +1,28 @@ 136.4 +/* 136.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 136.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 136.7 + * 136.8 + * This code is free software; you can redistribute it and/or modify it 136.9 + * under the terms of the GNU General Public License version 2 only, as 136.10 + * published by the Free Software Foundation. 136.11 + * 136.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 136.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 136.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 136.15 + * version 2 for more details (a copy is included in the LICENSE file that 136.16 + * accompanied this code). 136.17 + * 136.18 + * You should have received a copy of the GNU General Public License version 136.19 + * 2 along with this work; if not, write to the Free Software Foundation, 136.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 136.21 + * 136.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 136.23 + * or visit www.oracle.com if you need additional information or have any 136.24 + * questions. 136.25 + */ 136.26 + 136.27 +// Class PropertySuper should be removed. 136.28 + 136.29 +public class PropertySuper { 136.30 + PropertySuper() { System.out.println("remove me for NoClassDefFoundError"); } 136.31 +}
137.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 137.2 +++ b/test/runtime/ClassResolutionFail/TestClassResolutionFail.java Sat Oct 24 16:43:47 2020 +0800 137.3 @@ -0,0 +1,57 @@ 137.4 +/* 137.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 137.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 137.7 + * 137.8 + * This code is free software; you can redistribute it and/or modify it 137.9 + * under the terms of the GNU General Public License version 2 only, as 137.10 + * published by the Free Software Foundation. 137.11 + * 137.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 137.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 137.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 137.15 + * version 2 for more details (a copy is included in the LICENSE file that 137.16 + * accompanied this code). 137.17 + * 137.18 + * You should have received a copy of the GNU General Public License version 137.19 + * 2 along with this work; if not, write to the Free Software Foundation, 137.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 137.21 + * 137.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 137.23 + * or visit www.oracle.com if you need additional information or have any 137.24 + * questions. 137.25 + */ 137.26 + 137.27 +/* 137.28 + * @test TestClassResolutionFail 137.29 + * @bug 8023697 137.30 + * @summary This tests that failed class resolution doesn't report different class name in detail message for the first and subsequent times 137.31 + */ 137.32 + 137.33 +import java.io.File; 137.34 + 137.35 +public class TestClassResolutionFail { 137.36 + static String message; 137.37 + public static void test1() throws RuntimeException { 137.38 + try { 137.39 + Property p = new Property(); 137.40 + } catch (LinkageError e) { 137.41 + message = e.getMessage(); 137.42 + } 137.43 + try { 137.44 + Property p = new Property(); 137.45 + } catch (LinkageError e) { 137.46 + System.out.println(e.getMessage()); 137.47 + if (!e.getMessage().equals(message)) { 137.48 + throw new RuntimeException("Wrong message: " + message + " != " + e.getMessage()); 137.49 + } 137.50 + } 137.51 + } 137.52 + public static void main(java.lang.String[] unused) throws Exception { 137.53 + // Remove PropertySuper class 137.54 + String testClasses = System.getProperty("test.classes", "."); 137.55 + File f = new File(testClasses + File.separator + "PropertySuper.class"); 137.56 + f.delete(); 137.57 + test1(); 137.58 + } 137.59 +} 137.60 +
138.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 138.2 +++ b/test/runtime/CommandLine/TraceExceptionsTest.java Sat Oct 24 16:43:47 2020 +0800 138.3 @@ -0,0 +1,43 @@ 138.4 +/* 138.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 138.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 138.7 + * 138.8 + * This code is free software; you can redistribute it and/or modify it 138.9 + * under the terms of the GNU General Public License version 2 only, as 138.10 + * published by the Free Software Foundation. 138.11 + * 138.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 138.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 138.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 138.15 + * version 2 for more details (a copy is included in the LICENSE file that 138.16 + * accompanied this code). 138.17 + * 138.18 + * You should have received a copy of the GNU General Public License version 138.19 + * 2 along with this work; if not, write to the Free Software Foundation, 138.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 138.21 + * 138.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 138.23 + * or visit www.oracle.com if you need additional information or have any 138.24 + * questions. 138.25 + */ 138.26 + 138.27 +/* 138.28 + * @test 138.29 + * @bug 8048933 138.30 + * @summary TraceExceptions output should have the exception message - useful for ClassNotFoundExceptions especially 138.31 + * @library /testlibrary 138.32 + */ 138.33 + 138.34 +import com.oracle.java.testlibrary.*; 138.35 + 138.36 +public class TraceExceptionsTest { 138.37 + public static void main(String[] args) throws Exception { 138.38 + 138.39 + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 138.40 + "-XX:+TraceExceptions", "NoClassFound"); 138.41 + OutputAnalyzer output = new OutputAnalyzer(pb.start()); 138.42 + output.shouldContain("<a 'java/lang/ClassNotFoundException': NoClassFound>"); 138.43 + output.shouldNotContain("<a 'java/lang/ClassNotFoundException'>"); 138.44 + output.shouldHaveExitValue(1); 138.45 + } 138.46 +}
139.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 139.2 +++ b/test/runtime/containers/docker/CheckOperatingSystemMXBean.java Sat Oct 24 16:43:47 2020 +0800 139.3 @@ -0,0 +1,43 @@ 139.4 +/* 139.5 + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 139.6 + * Copyright (c) 2019, Red Hat Inc. All rights reserved. 139.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 139.8 + * 139.9 + * This code is free software; you can redistribute it and/or modify it 139.10 + * under the terms of the GNU General Public License version 2 only, as 139.11 + * published by the Free Software Foundation. 139.12 + * 139.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 139.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 139.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 139.16 + * version 2 for more details (a copy is included in the LICENSE file that 139.17 + * accompanied this code). 139.18 + * 139.19 + * You should have received a copy of the GNU General Public License version 139.20 + * 2 along with this work; if not, write to the Free Software Foundation, 139.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 139.22 + * 139.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 139.24 + * or visit www.oracle.com if you need additional information or have any 139.25 + * questions. 139.26 + */ 139.27 + 139.28 +import com.sun.management.OperatingSystemMXBean; 139.29 +import java.lang.management.ManagementFactory; 139.30 + 139.31 +public class CheckOperatingSystemMXBean { 139.32 + 139.33 + public static void main(String[] args) { 139.34 + System.out.println("Checking OperatingSystemMXBean"); 139.35 + 139.36 + OperatingSystemMXBean osBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); 139.37 + System.out.println(String.format("Runtime.availableProcessors: %d", Runtime.getRuntime().availableProcessors())); 139.38 + System.out.println(String.format("OperatingSystemMXBean.getAvailableProcessors: %d", osBean.getAvailableProcessors())); 139.39 + System.out.println(String.format("OperatingSystemMXBean.getTotalPhysicalMemorySize: %d", osBean.getTotalPhysicalMemorySize())); 139.40 + System.out.println(String.format("OperatingSystemMXBean.getFreePhysicalMemorySize: %d", osBean.getFreePhysicalMemorySize())); 139.41 + System.out.println(String.format("OperatingSystemMXBean.getTotalSwapSpaceSize: %d", osBean.getTotalSwapSpaceSize())); 139.42 + System.out.println(String.format("OperatingSystemMXBean.getFreeSwapSpaceSize: %d", osBean.getFreeSwapSpaceSize())); 139.43 + System.out.println(String.format("OperatingSystemMXBean.getSystemCpuLoad: %f", osBean.getSystemCpuLoad())); 139.44 + } 139.45 + 139.46 +}
140.1 --- a/test/runtime/containers/docker/Dockerfile-BasicTest Sat Oct 24 16:18:50 2020 +0800 140.2 +++ b/test/runtime/containers/docker/Dockerfile-BasicTest Sat Oct 24 16:43:47 2020 +0800 140.3 @@ -1,4 +1,4 @@ 140.4 -FROM oraclelinux:7.2 140.5 +FROM oraclelinux:7.6 140.6 MAINTAINER mikhailo.seledtsov@oracle.com 140.7 140.8 COPY /jdk /jdk
141.1 --- a/test/runtime/containers/docker/TestCPUAwareness.java Sat Oct 24 16:18:50 2020 +0800 141.2 +++ b/test/runtime/containers/docker/TestCPUAwareness.java Sat Oct 24 16:43:47 2020 +0800 141.3 @@ -25,7 +25,9 @@ 141.4 /* 141.5 * @test 141.6 * @summary Test JVM's CPU resource awareness when running inside docker container 141.7 - * @library /testlibrary 141.8 + * @library /testlibrary /testlibrary/whitebox 141.9 + * @build sun.hotspot.WhiteBox PrintContainerInfo CheckOperatingSystemMXBean 141.10 + * @run driver ClassFileInstaller -jar whitebox.jar sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission 141.11 * @run driver TestCPUAwareness 141.12 */ 141.13 141.14 @@ -72,6 +74,14 @@ 141.15 testCpuQuotaAndPeriod(150*1000, 100*1000); 141.16 testCpuQuotaAndPeriod(400*1000, 100*1000); 141.17 141.18 + testOperatingSystemMXBeanAwareness("0.5", "1"); 141.19 + testOperatingSystemMXBeanAwareness("1.0", "1"); 141.20 + if (availableCPUs > 2) { 141.21 + testOperatingSystemMXBeanAwareness("1.2", "2"); 141.22 + testOperatingSystemMXBeanAwareness("1.8", "2"); 141.23 + testOperatingSystemMXBeanAwareness("2.0", "2"); 141.24 + } 141.25 + 141.26 } finally { 141.27 DockerTestUtils.removeDockerImage(imageName); 141.28 } 141.29 @@ -202,4 +212,21 @@ 141.30 .shouldMatch("CPU Shares is.*" + shares) 141.31 .shouldMatch("active_processor_count.*" + expectedAPC); 141.32 } 141.33 + 141.34 + private static void testOperatingSystemMXBeanAwareness(String cpuAllocation, String expectedCpus) throws Exception { 141.35 + Common.logNewTestCase("Check OperatingSystemMXBean"); 141.36 + 141.37 + DockerRunOptions opts = Common.newOpts(imageName, "CheckOperatingSystemMXBean") 141.38 + .addDockerOpts( 141.39 + "--cpus", cpuAllocation 141.40 + ); 141.41 + 141.42 + DockerTestUtils.dockerRunJava(opts) 141.43 + .shouldHaveExitValue(0) 141.44 + .shouldContain("Checking OperatingSystemMXBean") 141.45 + .shouldContain("Runtime.availableProcessors: " + expectedCpus) 141.46 + .shouldContain("OperatingSystemMXBean.getAvailableProcessors: " + expectedCpus) 141.47 + .shouldMatch("OperatingSystemMXBean\\.getSystemCpuLoad: [0-9]+\\.[0-9]+") 141.48 + ; 141.49 + } 141.50 }
142.1 --- a/test/runtime/containers/docker/TestMemoryAwareness.java Sat Oct 24 16:18:50 2020 +0800 142.2 +++ b/test/runtime/containers/docker/TestMemoryAwareness.java Sat Oct 24 16:43:47 2020 +0800 142.3 @@ -26,7 +26,7 @@ 142.4 * @test 142.5 * @summary Test JVM's memory resource awareness when running inside docker container 142.6 * @library /testlibrary /testlibrary/whitebox 142.7 - * @build AttemptOOM sun.hotspot.WhiteBox PrintContainerInfo 142.8 + * @build AttemptOOM sun.hotspot.WhiteBox PrintContainerInfo CheckOperatingSystemMXBean 142.9 * @run driver ClassFileInstaller -jar whitebox.jar sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission 142.10 * @run driver TestMemoryAwareness 142.11 */ 142.12 @@ -59,6 +59,18 @@ 142.13 // Add extra 10 Mb to allocator limit, to be sure to cause OOM 142.14 testOOM("256m", 256 + 10); 142.15 142.16 + testOperatingSystemMXBeanAwareness( 142.17 + "100M", Integer.toString(((int) Math.pow(2, 20)) * 100), 142.18 + "150M", Integer.toString(((int) Math.pow(2, 20)) * (150 - 100)) 142.19 + ); 142.20 + testOperatingSystemMXBeanAwareness( 142.21 + "128M", Integer.toString(((int) Math.pow(2, 20)) * 128), 142.22 + "256M", Integer.toString(((int) Math.pow(2, 20)) * (256 - 128)) 142.23 + ); 142.24 + testOperatingSystemMXBeanAwareness( 142.25 + "1G", Integer.toString(((int) Math.pow(2, 20)) * 1024), 142.26 + "1500M", Integer.toString(((int) Math.pow(2, 20)) * (1500 - 1024)) 142.27 + ); 142.28 } finally { 142.29 DockerTestUtils.removeDockerImage(imageName); 142.30 } 142.31 @@ -106,4 +118,24 @@ 142.32 .shouldContain("java.lang.OutOfMemoryError"); 142.33 } 142.34 142.35 + private static void testOperatingSystemMXBeanAwareness(String memoryAllocation, String expectedMemory, 142.36 + String swapAllocation, String expectedSwap) throws Exception { 142.37 + Common.logNewTestCase("Check OperatingSystemMXBean"); 142.38 + 142.39 + DockerRunOptions opts = Common.newOpts(imageName, "CheckOperatingSystemMXBean") 142.40 + .addDockerOpts( 142.41 + "--memory", memoryAllocation, 142.42 + "--memory-swap", swapAllocation 142.43 + ); 142.44 + 142.45 + DockerTestUtils.dockerRunJava(opts) 142.46 + .shouldHaveExitValue(0) 142.47 + .shouldContain("Checking OperatingSystemMXBean") 142.48 + .shouldContain("OperatingSystemMXBean.getTotalPhysicalMemorySize: " + expectedMemory) 142.49 + .shouldMatch("OperatingSystemMXBean\\.getFreePhysicalMemorySize: [1-9][0-9]+") 142.50 + .shouldContain("OperatingSystemMXBean.getTotalSwapSpaceSize: " + expectedSwap) 142.51 + .shouldMatch("OperatingSystemMXBean\\.getFreeSwapSpaceSize: [1-9][0-9]+") 142.52 + ; 142.53 + } 142.54 + 142.55 }
143.1 --- a/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java Sat Oct 24 16:18:50 2020 +0800 143.2 +++ b/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java Sat Oct 24 16:43:47 2020 +0800 143.3 @@ -374,14 +374,14 @@ 143.4 * - exit code 143.5 * Note: the command line is printed by the ProcessTools 143.6 */ 143.7 - private void reportDiagnosticSummary() { 143.8 - String msg = 143.9 - " stdout: [" + stdout + "];\n" + 143.10 - " stderr: [" + stderr + "]\n" + 143.11 - " exitValue = " + getExitValue() + "\n"; 143.12 + public void reportDiagnosticSummary() { 143.13 + String msg = 143.14 + " stdout: [" + stdout + "];\n" + 143.15 + " stderr: [" + stderr + "]\n" + 143.16 + " exitValue = " + getExitValue() + "\n"; 143.17 143.18 - System.err.println(msg); 143.19 - } 143.20 + System.err.println(msg); 143.21 + } 143.22 143.23 143.24 /**
144.1 --- a/test/testlibrary_tests/whitebox/vm_flags/DoubleTest.java Sat Oct 24 16:18:50 2020 +0800 144.2 +++ b/test/testlibrary_tests/whitebox/vm_flags/DoubleTest.java Sat Oct 24 16:43:47 2020 +0800 144.3 @@ -33,7 +33,7 @@ 144.4 */ 144.5 144.6 public class DoubleTest { 144.7 - private static final String FLAG_NAME = null; 144.8 + private static final String FLAG_NAME = "InitialRAMPercentage"; 144.9 private static final Double[] TESTS = {0d, -0d, -1d, 1d, 144.10 Double.MAX_VALUE, Double.MIN_VALUE, Double.NaN, 144.11 Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY};
145.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 145.2 +++ b/test/vmTestbase/nsk/jdb/monitor/monitor002/monitor002.java Sat Oct 24 16:43:47 2020 +0800 145.3 @@ -0,0 +1,136 @@ 145.4 +/* 145.5 + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 145.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 145.7 + * 145.8 + * This code is free software; you can redistribute it and/or modify it 145.9 + * under the terms of the GNU General Public License version 2 only, as 145.10 + * published by the Free Software Foundation. 145.11 + * 145.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 145.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 145.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 145.15 + * version 2 for more details (a copy is included in the LICENSE file that 145.16 + * accompanied this code). 145.17 + * 145.18 + * You should have received a copy of the GNU General Public License version 145.19 + * 2 along with this work; if not, write to the Free Software Foundation, 145.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 145.21 + * 145.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 145.23 + * or visit www.oracle.com if you need additional information or have any 145.24 + * questions. 145.25 + */ 145.26 + 145.27 + 145.28 +/* 145.29 + * @test 145.30 + * 145.31 + * @summary JDB problem running monitor command 145.32 + * VM Testbase keywords: [jpda, jdb] 145.33 + * VM Testbase readme: 145.34 + * DESCRIPTION 145.35 + * Make sure 'monitor unmonitor 1' does not cause ConcurrentModificationException 145.36 + * in the debugger. 145.37 + * The jdb sets up line breakpoint at the debugged application. Then one command 145.38 + * 'monitor unmonitor 1' is set. After resuming the debuggee stops at the breakpoint. 145.39 + * The test passes if correct reply for "unmonitor 1" commanda is found in jdb stdout 145.40 + * stream. 145.41 + * The test consists of two program: 145.42 + * monitor002.java - launches jdb and debuggee, writes commands to jdb, reads the jdb output, 145.43 + * monitor002a.java - the debugged application. 145.44 + * 145.45 + * @library /vmTestbase 145.46 + * /test/lib 145.47 + * @run driver jdk.test.lib.FileInstaller . . 145.48 + * @build nsk.jdb.monitor.monitor002.monitor002 145.49 + * nsk.jdb.monitor.monitor002.monitor002a 145.50 + * @run main/othervm PropertyResolvingWrapper nsk.jdb.monitor.monitor002.monitor002 145.51 + * -arch=${os.family}-${os.simpleArch} 145.52 + * -waittime=5 145.53 + * -debugee.vmkind=java 145.54 + * -transport.address=dynamic 145.55 + * -jdb=${test.jdk}/bin/jdb 145.56 + * -java.options="${test.vm.opts} ${test.java.opts}" 145.57 + * -workdir=. 145.58 + * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}" 145.59 + */ 145.60 + 145.61 +package nsk.jdb.monitor.monitor002; 145.62 + 145.63 +import nsk.share.*; 145.64 +import nsk.share.jdb.*; 145.65 + 145.66 +import java.io.*; 145.67 +import java.util.*; 145.68 + 145.69 +public class monitor002 extends JdbTest { 145.70 + 145.71 + public static void main (String argv[]) { 145.72 + System.exit(run(argv, System.out) + JCK_STATUS_BASE); 145.73 + } 145.74 + 145.75 + public static int run(String argv[], PrintStream out) { 145.76 + debuggeeClass = DEBUGGEE_CLASS; 145.77 + firstBreak = FIRST_BREAK; 145.78 + lastBreak = LAST_BREAK; 145.79 + return new monitor002().runTest(argv, out); 145.80 + } 145.81 + 145.82 + static final String PACKAGE_NAME = "nsk.jdb.monitor.monitor002"; 145.83 + static final String TEST_CLASS = PACKAGE_NAME + ".monitor002"; 145.84 + static final String DEBUGGEE_CLASS = TEST_CLASS + "a"; 145.85 + static final String FIRST_BREAK = DEBUGGEE_CLASS + ".main"; 145.86 + static final String LAST_BREAK = DEBUGGEE_CLASS + ".lastBreak"; 145.87 + static final int LINE_NUMBER = 47; 145.88 + 145.89 + static final String[] CHECKED_COMMANDS = { 145.90 + JdbCommand.unmonitor + "1" 145.91 + }; 145.92 + 145.93 + protected void runCases() { 145.94 + String[] reply; 145.95 + Paragrep grep; 145.96 + int count; 145.97 + Vector v; 145.98 + String found; 145.99 + 145.100 + reply = jdb.receiveReplyFor(JdbCommand.stop_at + DEBUGGEE_CLASS + ":" + LINE_NUMBER); 145.101 + 145.102 + for (int i = 0; i < CHECKED_COMMANDS.length; i++) { 145.103 + reply = jdb.receiveReplyFor(JdbCommand.monitor + CHECKED_COMMANDS[i]); 145.104 + } 145.105 + 145.106 + int repliesCount = CHECKED_COMMANDS.length + 1; 145.107 + reply = jdb.receiveReplyFor(JdbCommand.cont, true, repliesCount); 145.108 + 145.109 + reply = jdb.receiveReplyFor(JdbCommand.monitor); 145.110 + if (reply.length != 1) { 145.111 + log.complain("Expected no active monitors after exectuting monitored command: " + CHECKED_COMMANDS[0]); 145.112 + success = false; 145.113 + } 145.114 + 145.115 + jdb.contToExit(1); 145.116 + 145.117 + reply = jdb.getTotalReply(); 145.118 + 145.119 + if (!checkCommands(reply)) { 145.120 + success = false; 145.121 + } 145.122 + } 145.123 + 145.124 + private boolean checkCommands(String[] reply) { 145.125 + Paragrep grep; 145.126 + boolean result = true; 145.127 + int count; 145.128 + 145.129 + grep = new Paragrep(reply); 145.130 + 145.131 + if ((count = grep.find("Unmonitoring 1: unmonitor 1")) != 1) { 145.132 + log.complain("Wrong number of execution of monitored command: " + CHECKED_COMMANDS[0]); 145.133 + log.complain(" Expected: 1; found: " + count); 145.134 + result = false; 145.135 + } 145.136 + 145.137 + return result; 145.138 + } 145.139 +}
146.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 146.2 +++ b/test/vmTestbase/nsk/jdb/monitor/monitor002/monitor002a.java Sat Oct 24 16:43:47 2020 +0800 146.3 @@ -0,0 +1,52 @@ 146.4 +/* 146.5 + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 146.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 146.7 + * 146.8 + * This code is free software; you can redistribute it and/or modify it 146.9 + * under the terms of the GNU General Public License version 2 only, as 146.10 + * published by the Free Software Foundation. 146.11 + * 146.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 146.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 146.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 146.15 + * version 2 for more details (a copy is included in the LICENSE file that 146.16 + * accompanied this code). 146.17 + * 146.18 + * You should have received a copy of the GNU General Public License version 146.19 + * 2 along with this work; if not, write to the Free Software Foundation, 146.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 146.21 + * 146.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 146.23 + * or visit www.oracle.com if you need additional information or have any 146.24 + * questions. 146.25 + */ 146.26 + 146.27 +package nsk.jdb.monitor.monitor002; 146.28 + 146.29 +import nsk.share.*; 146.30 +import nsk.share.jpda.*; 146.31 +import nsk.share.jdb.*; 146.32 + 146.33 +import java.io.*; 146.34 + 146.35 +// THIS TEST IS LINE NUMBER SENSITIVE 146.36 + 146.37 +/* This is debuggee aplication */ 146.38 +public class monitor002a { 146.39 + static monitor002a _monitor002a = new monitor002a(); 146.40 + 146.41 + public static void main(String args[]) { 146.42 + System.exit(monitor002.JCK_STATUS_BASE + _monitor002a.runIt(args, System.out)); 146.43 + } 146.44 + 146.45 + static void lastBreak () {} 146.46 + 146.47 + public int runIt(String args[], PrintStream out) { 146.48 + JdbArgumentHandler argumentHandler = new JdbArgumentHandler(args); 146.49 + Log log = new Log(out, argumentHandler); 146.50 + int localInt = 0; // monitor002.LINE_NUMBER 146.51 + localInt++; // dummy breakpoint 146.52 + log.display("Debuggee PASSED"); 146.53 + return monitor002.PASSED; 146.54 + } 146.55 +}