--- a/.hgtags Fri Sep 27 13:32:52 2019 +0200
+++ b/.hgtags Sun Sep 29 13:59:54 2019 +0200
@@ -588,3 +588,4 @@
cddef3bde924f3ff4f17f3d369280cf69d0450e5 jdk-14+14
9c250a7600e12bdb1e611835250af3204d4aa152 jdk-13-ga
778fc2dcbdaa8981e07e929a2cacef979c72261e jdk-14+15
+d29f0181ba424a95d881aba5eabf2e393abcc70f jdk-14+16
--- a/make/common/NativeCompilation.gmk Fri Sep 27 13:32:52 2019 +0200
+++ b/make/common/NativeCompilation.gmk Sun Sep 29 13:59:54 2019 +0200
@@ -760,34 +760,6 @@
endif
endif
- # Create a rule to collect all the individual make dependency files into a
- # single makefile.
- $1_DEPS_FILE := $$($1_OBJECT_DIR)/$1.d
-
- $$($1_DEPS_FILE): $$($1_ALL_OBJS)
- $(RM) $$@
- # CD into dir to reduce risk of hitting command length limits, which
- # could otherwise happen if TOPDIR is a very long path.
- $(CD) $$($1_OBJECT_DIR) && $(CAT) *.d > $$@.tmp
- $(CD) $$($1_OBJECT_DIR) && $(CAT) *.d.targets | $(SORT) -u >> $$@.tmp
- # After generating the file, which happens after all objects have been
- # compiled, copy it to .old extension. On the next make invocation, this
- # .old file will be included by make.
- $(CP) $$@.tmp $$@.old
- $(MV) $$@.tmp $$@
-
- $1 += $$($1_DEPS_FILE)
-
- # The include must be on the .old file, which represents the state from the
- # previous invocation of make. The file being included must not have a rule
- # defined for it as otherwise make will think it has to run the rule before
- # being able to include the file, which would be wrong since we specifically
- # need the file as it was generated by a previous make invocation.
- ifneq ($$(wildcard $$($1_DEPS_FILE).old), )
- $1_DEPS_FILE_LOADED := true
- -include $$($1_DEPS_FILE).old
- endif
-
# Now call SetupCompileNativeFile for each source file we are going to compile.
$$(foreach file, $$($1_SRCS), \
$$(eval $$(call SetupCompileNativeFile, $1_$$(notdir $$(file)),\
@@ -850,6 +822,34 @@
endif
endif
+ # Create a rule to collect all the individual make dependency files into a
+ # single makefile.
+ $1_DEPS_FILE := $$($1_OBJECT_DIR)/$1.d
+
+ $$($1_DEPS_FILE): $$($1_ALL_OBJS) $$($1_RES)
+ $(RM) $$@
+ # CD into dir to reduce risk of hitting command length limits, which
+ # could otherwise happen if TOPDIR is a very long path.
+ $(CD) $$($1_OBJECT_DIR) && $(CAT) *.d > $$@.tmp
+ $(CD) $$($1_OBJECT_DIR) && $(CAT) *.d.targets | $(SORT) -u >> $$@.tmp
+ # After generating the file, which happens after all objects have been
+ # compiled, copy it to .old extension. On the next make invocation, this
+ # .old file will be included by make.
+ $(CP) $$@.tmp $$@.old
+ $(MV) $$@.tmp $$@
+
+ $1 += $$($1_DEPS_FILE)
+
+ # The include must be on the .old file, which represents the state from the
+ # previous invocation of make. The file being included must not have a rule
+ # defined for it as otherwise make will think it has to run the rule before
+ # being able to include the file, which would be wrong since we specifically
+ # need the file as it was generated by a previous make invocation.
+ ifneq ($$(wildcard $$($1_DEPS_FILE).old), )
+ $1_DEPS_FILE_LOADED := true
+ -include $$($1_DEPS_FILE).old
+ endif
+
ifneq ($(DISABLE_MAPFILES), true)
$1_REAL_MAPFILE := $$($1_MAPFILE)
ifeq ($(call isTargetOs, windows), false)
--- a/src/hotspot/cpu/ppc/c1_FrameMap_ppc.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/cpu/ppc/c1_FrameMap_ppc.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,7 @@
//}
if (r_2->is_Register() && (type == T_LONG || type == T_DOUBLE)) {
opr = as_long_opr(reg);
- } else if (type == T_OBJECT || type == T_ARRAY) {
+ } else if (is_reference_type(type)) {
opr = as_oop_opr(reg);
} else {
opr = as_opr(reg);
--- a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1237,7 +1237,7 @@
} else {
ShouldNotReachHere();
}
- if (to_reg->type() == T_OBJECT || to_reg->type() == T_ARRAY) {
+ if (is_reference_type(to_reg->type())) {
__ verify_oop(to_reg->as_register());
}
}
@@ -1253,7 +1253,7 @@
Register disp_reg = noreg;
int disp_value = addr->disp();
bool needs_patching = (patch_code != lir_patch_none);
- bool compress_oop = (type == T_ARRAY || type == T_OBJECT) && UseCompressedOops && !wide &&
+ bool compress_oop = (is_reference_type(type)) && UseCompressedOops && !wide &&
CompressedOops::mode() != CompressedOops::UnscaledNarrowOop;
bool load_disp = addr->index()->is_illegal() && !Assembler::is_simm16(disp_value);
bool use_R29 = compress_oop && load_disp; // Avoid register conflict, also do null check before killing R29.
@@ -1473,7 +1473,7 @@
}
} else {
assert(opr1->type() != T_ADDRESS && opr2->type() != T_ADDRESS, "currently unsupported");
- if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) {
+ if (is_reference_type(opr1->type())) {
// There are only equal/notequal comparisons on objects.
assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "oops");
__ cmpd(BOOL_RESULT, opr1->as_register(), opr2->as_register());
@@ -2315,8 +2315,8 @@
void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) {
LP64_ONLY( __ extsw(op->len()->as_register(), op->len()->as_register()); )
if (UseSlowPath ||
- (!UseFastNewObjectArray && (op->type() == T_OBJECT || op->type() == T_ARRAY)) ||
- (!UseFastNewTypeArray && (op->type() != T_OBJECT && op->type() != T_ARRAY))) {
+ (!UseFastNewObjectArray && (is_reference_type(op->type()))) ||
+ (!UseFastNewTypeArray && (!is_reference_type(op->type())))) {
__ b(*op->stub()->entry());
} else {
__ allocate_array(op->obj()->as_register(),
--- a/src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2017, SAP SE. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -648,7 +648,7 @@
__ membar_release();
}
- if (type == T_OBJECT || type == T_ARRAY) {
+ if (is_reference_type(type)) {
if (UseCompressedOops) {
t1 = new_register(T_OBJECT);
t2 = new_register(T_OBJECT);
--- a/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2018, SAP SE. All rights reserved.
+ * Copyright (c) 2018, 2019, SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -305,7 +305,7 @@
void G1BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Register base, RegisterOrConstant ind_or_offs, Register dst,
Register tmp1, Register tmp2, bool needs_frame, Label *L_handle_null) {
- bool on_oop = type == T_OBJECT || type == T_ARRAY;
+ bool on_oop = is_reference_type(type);
bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
bool on_reference = on_weak || on_phantom;
--- a/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2018, SAP SE. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -59,7 +59,7 @@
void ModRefBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Register base, RegisterOrConstant ind_or_offs, Register val,
Register tmp1, Register tmp2, Register tmp3, bool needs_frame) {
- if (type == T_OBJECT || type == T_ARRAY) {
+ if (is_reference_type(type)) {
oop_store_at(masm, decorators, type, base, ind_or_offs, val, tmp1, tmp2, tmp3, needs_frame);
} else {
BarrierSetAssembler::store_at(masm, decorators, type, base, ind_or_offs, val, tmp1, tmp2, tmp3, needs_frame);
--- a/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.hpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.hpp Sun Sep 29 13:59:54 2019 +0200
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2018, SAP SE. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1,6 +1,6 @@
/*
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2018 SAP SE. All rights reserved.
+ * Copyright (c) 2012, 2019 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1142,7 +1142,7 @@
}
if (!r_2->is_valid()) {
// Not sure we need to do this but it shouldn't hurt.
- if (sig_bt[i] == T_OBJECT || sig_bt[i] == T_ADDRESS || sig_bt[i] == T_ARRAY) {
+ if (is_reference_type(sig_bt[i]) || sig_bt[i] == T_ADDRESS) {
__ ld(r, ld_offset, ld_ptr);
ld_offset-=wordSize;
} else {
@@ -1739,8 +1739,7 @@
Register temp_reg = R19_method; // not part of any compiled calling seq
if (VerifyOops) {
for (int i = 0; i < method->size_of_parameters(); i++) {
- if (sig_bt[i] == T_OBJECT ||
- sig_bt[i] == T_ARRAY) {
+ if (is_reference_type(sig_bt[i])) {
VMReg r = regs[i].first();
assert(r->is_valid(), "bad oop arg");
if (r->is_stack()) {
@@ -2602,7 +2601,7 @@
// Unbox oop result, e.g. JNIHandles::resolve value.
// --------------------------------------------------------------------------
- if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
+ if (is_reference_type(ret_type)) {
__ resolve_jobject(R3_RET, r_temp_1, r_temp_2, /* needs_frame */ false);
}
--- a/src/hotspot/cpu/s390/c1_FrameMap_s390.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/cpu/s390/c1_FrameMap_s390.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,7 +46,7 @@
Register reg = r_1->as_Register();
if (r_2->is_Register() && (type == T_LONG || type == T_DOUBLE)) {
opr = as_long_opr(reg);
- } else if (type == T_OBJECT || type == T_ARRAY) {
+ } else if (is_reference_type(type)) {
opr = as_oop_opr(reg);
} else if (type == T_METADATA) {
opr = as_metadata_opr(reg);
--- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -972,6 +972,7 @@
} else {
__ z_lg(dest->as_register(), disp_value, disp_reg, src);
}
+ __ verify_oop(dest->as_register());
break;
}
case T_FLOAT:
@@ -991,9 +992,6 @@
case T_LONG : __ z_lg(dest->as_register_lo(), disp_value, disp_reg, src); break;
default : ShouldNotReachHere();
}
- if (type == T_ARRAY || type == T_OBJECT) {
- __ verify_oop(dest->as_register());
- }
if (patch != NULL) {
patching_epilog(patch, patch_code, src, info);
@@ -1006,7 +1004,7 @@
assert(dest->is_register(), "should not call otherwise");
if (dest->is_single_cpu()) {
- if (type == T_ARRAY || type == T_OBJECT) {
+ if (is_reference_type(type)) {
__ mem2reg_opt(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()), true);
__ verify_oop(dest->as_register());
} else if (type == T_METADATA) {
@@ -1034,7 +1032,7 @@
if (src->is_single_cpu()) {
const Address dst = frame_map()->address_for_slot(dest->single_stack_ix());
- if (type == T_OBJECT || type == T_ARRAY) {
+ if (is_reference_type(type)) {
__ verify_oop(src->as_register());
__ reg2mem_opt(src->as_register(), dst, true);
} else if (type == T_METADATA) {
@@ -1080,7 +1078,7 @@
} else {
ShouldNotReachHere();
}
- if (to_reg->type() == T_OBJECT || to_reg->type() == T_ARRAY) {
+ if (is_reference_type(to_reg->type())) {
__ verify_oop(to_reg->as_register());
}
}
@@ -1131,7 +1129,7 @@
assert(disp_reg != Z_R0 || Immediate::is_simm20(disp_value), "should have set this up");
- if (type == T_ARRAY || type == T_OBJECT) {
+ if (is_reference_type(type)) {
__ verify_oop(from->as_register());
}
@@ -1294,10 +1292,10 @@
Register reg1 = opr1->as_register();
if (opr2->is_single_cpu()) {
// cpu register - cpu register
- if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) {
+ if (is_reference_type(opr1->type())) {
__ z_clgr(reg1, opr2->as_register());
} else {
- assert(opr2->type() != T_OBJECT && opr2->type() != T_ARRAY, "cmp int, oop?");
+ assert(!is_reference_type(opr2->type()), "cmp int, oop?");
if (unsigned_comp) {
__ z_clr(reg1, opr2->as_register());
} else {
@@ -1306,7 +1304,7 @@
}
} else if (opr2->is_stack()) {
// cpu register - stack
- if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) {
+ if (is_reference_type(opr1->type())) {
__ z_cg(reg1, frame_map()->address_for_slot(opr2->single_stack_ix()));
} else {
if (unsigned_comp) {
@@ -1324,7 +1322,7 @@
} else {
__ z_cfi(reg1, c->as_jint());
}
- } else if (c->type() == T_OBJECT || c->type() == T_ARRAY) {
+ } else if (is_reference_type(c->type())) {
// In 64bit oops are single register.
jobject o = c->as_jobject();
if (o == NULL) {
@@ -1767,7 +1765,7 @@
}
} else {
Register r_lo;
- if (right->type() == T_OBJECT || right->type() == T_ARRAY) {
+ if (is_reference_type(right->type())) {
r_lo = right->as_register();
} else {
r_lo = right->as_register_lo();
@@ -2413,8 +2411,8 @@
__ move_reg_if_needed(len, T_LONG, len, T_INT); // sign extend
if (UseSlowPath ||
- (!UseFastNewObjectArray && (op->type() == T_OBJECT || op->type() == T_ARRAY)) ||
- (!UseFastNewTypeArray && (op->type() != T_OBJECT && op->type() != T_ARRAY))) {
+ (!UseFastNewObjectArray && (is_reference_type(op->type()))) ||
+ (!UseFastNewTypeArray && (!is_reference_type(op->type())))) {
__ z_brul(*op->stub()->entry());
} else {
__ allocate_array(op->obj()->as_register(),
--- a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2018, SAP SE. All rights reserved.
+ * Copyright (c) 2018, 2019, SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -100,7 +100,7 @@
void G1BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
const Address& src, Register dst, Register tmp1, Register tmp2, Label *L_handle_null) {
- bool on_oop = type == T_OBJECT || type == T_ARRAY;
+ bool on_oop = is_reference_type(type);
bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
bool on_reference = on_weak || on_phantom;
--- a/src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2018, SAP SE. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,14 +36,14 @@
void ModRefBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Register src, Register dst, Register count) {
- if (type == T_OBJECT || type == T_ARRAY) {
+ if (is_reference_type(type)) {
gen_write_ref_array_pre_barrier(masm, decorators, dst, count);
}
}
void ModRefBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Register dst, Register count, bool do_return) {
- if (type == T_OBJECT || type == T_ARRAY) {
+ if (is_reference_type(type)) {
gen_write_ref_array_post_barrier(masm, decorators, dst, count, do_return);
} else {
if (do_return) { __ z_br(Z_R14); }
@@ -52,7 +52,7 @@
void ModRefBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
const Address& dst, Register val, Register tmp1, Register tmp2, Register tmp3) {
- if (type == T_OBJECT || type == T_ARRAY) {
+ if (is_reference_type(type)) {
oop_store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3);
} else {
BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3);
--- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016, 2018 SAP SE. All rights reserved.
+ * Copyright (c) 2016, 2019, SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -883,7 +883,7 @@
if (!VerifyOops) { return; }
for (int i = 0; i < total_args_passed; i++) {
- if (sig_bt[i] == T_OBJECT || sig_bt[i] == T_ARRAY) {
+ if (is_reference_type(sig_bt[i])) {
VMReg r = regs[i].first();
assert(r->is_valid(), "bad oop arg");
@@ -2318,7 +2318,7 @@
__ reset_last_Java_frame();
// Unpack oop result, e.g. JNIHandles::resolve result.
- if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
+ if (is_reference_type(ret_type)) {
__ resolve_jobject(Z_RET, /* tmp1 */ Z_R13, /* tmp2 */ Z_R7);
}
@@ -2621,7 +2621,7 @@
} else {
if (!r_2->is_valid()) {
// Not sure we need to do this but it shouldn't hurt.
- if (sig_bt[i] == T_OBJECT || sig_bt[i] == T_ADDRESS || sig_bt[i] == T_ARRAY) {
+ if (is_reference_type(sig_bt[i]) || sig_bt[i] == T_ADDRESS) {
__ z_lg(r_1->as_Register(), ld_offset, ld_ptr);
} else {
__ z_l(r_1->as_Register(), ld_offset, ld_ptr);
--- a/src/hotspot/os/aix/os_aix.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/os/aix/os_aix.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1027,17 +1027,15 @@
// Time since start-up in seconds to a fine granularity.
// Used by VMSelfDestructTimer and the MemProfiler.
double os::elapsedTime() {
- return (double)(os::elapsed_counter()) * 0.000001;
+ return ((double)os::elapsed_counter()) / os::elapsed_frequency(); // nanosecond resolution
}
jlong os::elapsed_counter() {
- timeval time;
- int status = gettimeofday(&time, NULL);
- return jlong(time.tv_sec) * 1000 * 1000 + jlong(time.tv_usec) - initial_time_count;
+ return javaTimeNanos() - initial_time_count;
}
jlong os::elapsed_frequency() {
- return (1000 * 1000);
+ return NANOSECS_PER_SEC; // nanosecond resolution
}
bool os::supports_vtime() { return true; }
@@ -3498,7 +3496,7 @@
// _main_thread points to the thread that created/loaded the JVM.
Aix::_main_thread = pthread_self();
- initial_time_count = os::elapsed_counter();
+ initial_time_count = javaTimeNanos();
os::Posix::init();
}
--- a/src/hotspot/share/ci/ciEnv.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/ci/ciEnv.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -154,6 +154,7 @@
_the_null_string = NULL;
_the_min_jint_string = NULL;
+ _jvmti_redefinition_count = 0;
_jvmti_can_hotswap_or_post_breakpoint = false;
_jvmti_can_access_local_variables = false;
_jvmti_can_post_on_exceptions = false;
@@ -209,6 +210,7 @@
_the_null_string = NULL;
_the_min_jint_string = NULL;
+ _jvmti_redefinition_count = 0;
_jvmti_can_hotswap_or_post_breakpoint = false;
_jvmti_can_access_local_variables = false;
_jvmti_can_post_on_exceptions = false;
@@ -231,6 +233,7 @@
VM_ENTRY_MARK;
// Get Jvmti capabilities under lock to get consistant values.
MutexLocker mu(JvmtiThreadState_lock);
+ _jvmti_redefinition_count = JvmtiExport::redefinition_count();
_jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint();
_jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables();
_jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions();
@@ -238,6 +241,11 @@
}
bool ciEnv::jvmti_state_changed() const {
+ // Some classes were redefined
+ if (_jvmti_redefinition_count != JvmtiExport::redefinition_count()) {
+ return true;
+ }
+
if (!_jvmti_can_access_local_variables &&
JvmtiExport::can_access_local_variables()) {
return true;
@@ -254,6 +262,7 @@
JvmtiExport::can_pop_frame()) {
return true;
}
+
return false;
}
--- a/src/hotspot/share/ci/ciEnv.hpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/ci/ciEnv.hpp Sun Sep 29 13:59:54 2019 +0200
@@ -68,6 +68,7 @@
int _name_buffer_len;
// Cache Jvmti state
+ uint64_t _jvmti_redefinition_count;
bool _jvmti_can_hotswap_or_post_breakpoint;
bool _jvmti_can_access_local_variables;
bool _jvmti_can_post_on_exceptions;
--- a/src/hotspot/share/classfile/classLoaderData.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/classfile/classLoaderData.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -129,8 +129,8 @@
ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_unsafe_anonymous) :
_metaspace(NULL),
- _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,
- Monitor::_safepoint_check_never)),
+ _metaspace_lock(new Mutex(Mutex::leaf+1, "Metaspace allocation lock", true,
+ Mutex::_safepoint_check_never)),
_unloading(false), _is_unsafe_anonymous(is_unsafe_anonymous),
_modified_oops(true), _accumulated_modified_oops(false),
// An unsafe anonymous class loader data doesn't have anything to keep
--- a/src/hotspot/share/code/nmethod.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/code/nmethod.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1293,7 +1293,6 @@
*/
bool nmethod::make_not_entrant_or_zombie(int state) {
assert(state == zombie || state == not_entrant, "must be zombie or not_entrant");
- assert(!is_zombie(), "should not already be a zombie");
if (Atomic::load(&_state) >= state) {
// Avoid taking the lock if already in required state.
@@ -1316,20 +1315,18 @@
// This flag is used to remember whether we need to later lock and unregister.
bool nmethod_needs_unregister = false;
- // invalidate osr nmethod before acquiring the patching lock since
- // they both acquire leaf locks and we don't want a deadlock.
- // This logic is equivalent to the logic below for patching the
- // verified entry point of regular methods. We check that the
- // nmethod is in use to ensure that it is invalidated only once.
- if (is_osr_method() && is_in_use()) {
- // this effectively makes the osr nmethod not entrant
- invalidate_osr_method();
- }
-
{
// Enter critical section. Does not block for safepoint.
MutexLocker ml(CompiledMethod_lock->owned_by_self() ? NULL : CompiledMethod_lock, Mutex::_no_safepoint_check_flag);
+ // This logic is equivalent to the logic below for patching the
+ // verified entry point of regular methods. We check that the
+ // nmethod is in use to ensure that it is invalidated only once.
+ if (is_osr_method() && is_in_use()) {
+ // this effectively makes the osr nmethod not entrant
+ invalidate_osr_method();
+ }
+
if (Atomic::load(&_state) >= state) {
// another thread already performed this transition so nothing
// to do, but return false to indicate this.
@@ -2192,6 +2189,17 @@
virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
};
+class VerifyMetadataClosure: public MetadataClosure {
+ public:
+ void do_metadata(Metadata* md) {
+ if (md->is_method()) {
+ Method* method = (Method*)md;
+ assert(!method->is_old(), "Should not be installing old methods");
+ }
+ }
+};
+
+
void nmethod::verify() {
// Hmm. OSR methods can be deopted but not marked as zombie or not_entrant
@@ -2255,6 +2263,10 @@
Universe::heap()->verify_nmethod(this);
verify_scopes();
+
+ CompiledICLocker nm_verify(this);
+ VerifyMetadataClosure vmc;
+ metadata_do(&vmc);
}
--- a/src/hotspot/share/compiler/compilerDefinitions.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/compiler/compilerDefinitions.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -188,14 +188,6 @@
#endif // TIERED
void CompilerConfig::set_tiered_flags() {
- // With tiered, set default policy to SimpleThresholdPolicy, which is 2.
- if (FLAG_IS_DEFAULT(CompilationPolicyChoice)) {
- FLAG_SET_DEFAULT(CompilationPolicyChoice, 2);
- }
- if (CompilationPolicyChoice < 2) {
- vm_exit_during_initialization(
- "Incompatible compilation policy selected", NULL);
- }
// Increase the code cache size - tiered compiles a lot more.
if (FLAG_IS_DEFAULT(ReservedCodeCacheSize)) {
FLAG_SET_ERGO(ReservedCodeCacheSize,
@@ -420,17 +412,6 @@
if (TieredCompilation) {
set_tiered_flags();
} else {
- int max_compilation_policy_choice = 1;
-#ifdef COMPILER2
- if (is_server_compilation_mode_vm()) {
- max_compilation_policy_choice = 2;
- }
-#endif
- // Check if the policy is valid.
- if (CompilationPolicyChoice >= max_compilation_policy_choice) {
- vm_exit_during_initialization(
- "Incompatible compilation policy selected", NULL);
- }
// Scale CompileThreshold
// CompileThresholdScaling == 0.0 is equivalent to -Xint and leaves CompileThreshold unchanged.
if (!FLAG_IS_DEFAULT(CompileThresholdScaling) && CompileThresholdScaling > 0.0) {
--- a/src/hotspot/share/gc/g1/g1RootProcessor.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/gc/g1/g1RootProcessor.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -71,7 +71,7 @@
_g1h(g1h),
_process_strong_tasks(G1RP_PS_NumElements),
_srs(n_workers),
- _lock(Mutex::leaf, "G1 Root Scan barrier lock", false, Monitor::_safepoint_check_never),
+ _lock(Mutex::leaf, "G1 Root Scan barrier lock", false, Mutex::_safepoint_check_never),
_n_workers_discovered_strong_classes(0) {}
void G1RootProcessor::evacuate_roots(G1ParScanThreadState* pss, uint worker_id) {
--- a/src/hotspot/share/gc/g1/heapRegionRemSet.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/gc/g1/heapRegionRemSet.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -428,7 +428,7 @@
HeapRegion* hr)
: _bot(bot),
_code_roots(),
- _m(Mutex::leaf, FormatBuffer<128>("HeapRegionRemSet lock #%u", hr->hrm_index()), true, Monitor::_safepoint_check_never),
+ _m(Mutex::leaf, FormatBuffer<128>("HeapRegionRemSet lock #%u", hr->hrm_index()), true, Mutex::_safepoint_check_never),
_other_regions(&_m),
_hr(hr),
_state(Untracked)
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1272,6 +1272,18 @@
}
if ((ctrl->is_Proj() && ctrl->in(0)->is_CallJava()) || ctrl->is_CallJava()) {
CallNode* call = ctrl->is_Proj() ? ctrl->in(0)->as_CallJava() : ctrl->as_CallJava();
+ if (call->entry_point() == OptoRuntime::rethrow_stub()) {
+ // The rethrow call may have too many projections to be
+ // properly handled here. Given there's no reason for a
+ // barrier to depend on the call, move it above the call
+ if (phase->get_ctrl(val) == ctrl) {
+ assert(val->Opcode() == Op_DecodeN, "unexpected node");
+ assert(phase->is_dominator(phase->get_ctrl(val->in(1)), call->in(0)), "Load is too low");
+ phase->set_ctrl(val, call->in(0));
+ }
+ phase->set_ctrl(lrb, call->in(0));
+ continue;
+ }
CallProjections projs;
call->extract_projections(&projs, false, false);
--- a/src/hotspot/share/gc/z/zNMethod.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/gc/z/zNMethod.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -294,13 +294,14 @@
return;
}
- ZLocker<ZReentrantLock> locker(ZNMethod::lock_for_nmethod(nm));
-
if (nm->is_unloading()) {
+ ZLocker<ZReentrantLock> locker(ZNMethod::lock_for_nmethod(nm));
unlink(nm);
return;
}
+ ZLocker<ZReentrantLock> locker(ZNMethod::lock_for_nmethod(nm));
+
// Heal oops and disarm
ZNMethodOopClosure cl;
ZNMethod::nmethod_oops_do(nm, &cl);
--- a/src/hotspot/share/include/jmm.h Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/include/jmm.h Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -50,8 +50,9 @@
JMM_VERSION_1_2 = 0x20010200, // JDK 7
JMM_VERSION_1_2_1 = 0x20010201, // JDK 7 GA
JMM_VERSION_1_2_2 = 0x20010202,
- JMM_VERSION_2 = 0x20020000, // JDK 10
- JMM_VERSION = 0x20020000
+ JMM_VERSION_2 = 0x20020000, // JDK 10
+ JMM_VERSION_3 = 0x20030000, // JDK 14
+ JMM_VERSION = JMM_VERSION_3
};
typedef struct {
@@ -239,6 +240,9 @@
jobject (JNICALL *GetMemoryPoolUsage) (JNIEnv* env, jobject pool);
jobject (JNICALL *GetPeakMemoryPoolUsage) (JNIEnv* env, jobject pool);
+ jlong (JNICALL *GetOneThreadAllocatedMemory)
+ (JNIEnv *env,
+ jlong thread_id);
void (JNICALL *GetThreadAllocatedMemory)
(JNIEnv *env,
jlongArray ids,
--- a/src/hotspot/share/jvmci/jvmciEnv.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/jvmci/jvmciEnv.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -44,6 +44,7 @@
_failure_reason_on_C_heap(false) {
// Get Jvmti capabilities under lock to get consistent values.
MutexLocker mu(JvmtiThreadState_lock);
+ _jvmti_redefinition_count = JvmtiExport::redefinition_count();
_jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint() ? 1 : 0;
_jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables() ? 1 : 0;
_jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions() ? 1 : 0;
@@ -51,6 +52,10 @@
}
bool JVMCICompileState::jvmti_state_changed() const {
+ // Some classes were redefined
+ if (jvmti_redefinition_count() != JvmtiExport::redefinition_count()) {
+ return true;
+ }
if (!jvmti_can_access_local_variables() &&
JvmtiExport::can_access_local_variables()) {
return true;
--- a/src/hotspot/share/jvmci/jvmciEnv.hpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/jvmci/jvmciEnv.hpp Sun Sep 29 13:59:54 2019 +0200
@@ -94,6 +94,7 @@
// Cache JVMTI state. Defined as bytes so that reading them from Java
// via Unsafe is well defined (the C++ type for bool is implementation
// defined and may not be the same as a Java boolean).
+ uint64_t _jvmti_redefinition_count;
jbyte _jvmti_can_hotswap_or_post_breakpoint;
jbyte _jvmti_can_access_local_variables;
jbyte _jvmti_can_post_on_exceptions;
@@ -113,6 +114,7 @@
CompileTask* task() { return _task; }
bool jvmti_state_changed() const;
+ uint64_t jvmti_redefinition_count() const { return _jvmti_redefinition_count; }
bool jvmti_can_hotswap_or_post_breakpoint() const { return _jvmti_can_hotswap_or_post_breakpoint != 0; }
bool jvmti_can_access_local_variables() const { return _jvmti_can_access_local_variables != 0; }
bool jvmti_can_post_on_exceptions() const { return _jvmti_can_post_on_exceptions != 0; }
--- a/src/hotspot/share/oops/methodData.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/oops/methodData.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1212,7 +1212,7 @@
// Initialize the MethodData* corresponding to a given method.
MethodData::MethodData(const methodHandle& method, int size, TRAPS)
- : _extra_data_lock(Monitor::leaf, "MDO extra data lock"),
+ : _extra_data_lock(Mutex::leaf, "MDO extra data lock"),
_parameters_type_data_di(parameters_uninitialized) {
// Set the method back-pointer.
_method = method();
--- a/src/hotspot/share/oops/methodData.hpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/oops/methodData.hpp Sun Sep 29 13:59:54 2019 +0200
@@ -2011,7 +2011,7 @@
MethodData(const methodHandle& method, int size, TRAPS);
public:
static MethodData* allocate(ClassLoaderData* loader_data, const methodHandle& method, TRAPS);
- MethodData() : _extra_data_lock(Monitor::leaf, "MDO extra data lock") {}; // For ciMethodData
+ MethodData() : _extra_data_lock(Mutex::leaf, "MDO extra data lock") {}; // For ciMethodData
bool is_methodData() const volatile { return true; }
void initialize();
--- a/src/hotspot/share/opto/callnode.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/opto/callnode.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1397,6 +1397,18 @@
_is_allocation_MemBar_redundant = true;
}
}
+Node *AllocateNode::make_ideal_mark(PhaseGVN *phase, Node* obj, Node* control, Node* mem) {
+ Node* mark_node = NULL;
+ // For now only enable fast locking for non-array types
+ if (UseBiasedLocking && Opcode() == Op_Allocate) {
+ Node* klass_node = in(AllocateNode::KlassNode);
+ Node* proto_adr = phase->transform(new AddPNode(klass_node, klass_node, phase->MakeConX(in_bytes(Klass::prototype_header_offset()))));
+ mark_node = LoadNode::make(*phase, control, mem, proto_adr, TypeRawPtr::BOTTOM, TypeX_X, TypeX_X->basic_type(), MemNode::unordered);
+ } else {
+ mark_node = phase->MakeConX(markWord::prototype().value());
+ }
+ return mark_node;
+}
//=============================================================================
Node* AllocateArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) {
--- a/src/hotspot/share/opto/callnode.hpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/opto/callnode.hpp Sun Sep 29 13:59:54 2019 +0200
@@ -936,6 +936,8 @@
// allocation node.
void compute_MemBar_redundancy(ciMethod* initializer);
bool is_allocation_MemBar_redundant() { return _is_allocation_MemBar_redundant; }
+
+ Node* make_ideal_mark(PhaseGVN *phase, Node* obj, Node* control, Node* mem);
};
//------------------------------AllocateArray---------------------------------
--- a/src/hotspot/share/opto/loopPredicate.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/opto/loopPredicate.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1381,7 +1381,6 @@
} // end while
}
- Node_List if_proj_list_freq(area);
if (follow_branches) {
PathFrequency pf(loop->_head, this);
@@ -1399,6 +1398,7 @@
// And look into all branches
Node_Stack stack(0);
VectorSet seen(Thread::current()->resource_area());
+ Node_List if_proj_list_freq(area);
while (regions.size() > 0) {
Node* c = regions.pop();
loop_predication_follow_branches(c, loop, loop_trip_cnt, pf, stack, seen, if_proj_list_freq);
--- a/src/hotspot/share/opto/loopTransform.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/opto/loopTransform.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -671,76 +671,50 @@
loop->record_for_igvn();
}
-// The Estimated Loop Unroll Size: UnrollFactor * (106% * BodySize + BC) + CC,
-// where BC and CC are (totally) ad-hoc/magic "body" and "clone" constants,
-// respectively, used to ensure that node usage estimates made are on the safe
-// side, for the most part. This is a simplified version of the loop clone
-// size calculation in est_loop_clone_sz(), defined for unroll factors larger
-// than one (>1), performing an overflow check and returning 'UINT_MAX' in
-// case of an overflow.
-static uint est_loop_unroll_sz(uint factor, uint size) {
- precond(0 < factor);
-
- uint const bc = 5;
- uint const cc = 7;
- uint const sz = size + (size + 15) / 16;
- uint estimate = factor * (sz + bc) + cc;
-
- return (estimate - cc) / factor == sz + bc ? estimate : UINT_MAX;
-}
-
-#define EMPTY_LOOP_SIZE 7 // Number of nodes in an empty loop.
-
//------------------------------policy_maximally_unroll------------------------
// Calculate the exact loop trip-count and return TRUE if loop can be fully,
// i.e. maximally, unrolled, otherwise return FALSE. When TRUE, the estimated
// node budget is also requested.
-bool IdealLoopTree::policy_maximally_unroll(PhaseIdealLoop *phase) const {
- CountedLoopNode *cl = _head->as_CountedLoop();
+bool IdealLoopTree::policy_maximally_unroll(PhaseIdealLoop* phase) const {
+ CountedLoopNode* cl = _head->as_CountedLoop();
assert(cl->is_normal_loop(), "");
if (!cl->is_valid_counted_loop()) {
- return false; // Malformed counted loop
+ return false; // Malformed counted loop.
}
if (!cl->has_exact_trip_count()) {
- // Trip count is not exact.
- return false;
+ return false; // Trip count is not exact.
}
uint trip_count = cl->trip_count();
// Note, max_juint is used to indicate unknown trip count.
assert(trip_count > 1, "one iteration loop should be optimized out already");
- assert(trip_count < max_juint, "exact trip_count should be less than max_uint.");
+ assert(trip_count < max_juint, "exact trip_count should be less than max_juint.");
// If nodes are depleted, some transform has miscalculated its needs.
assert(!phase->exceeding_node_budget(), "sanity");
- // Real policy: if we maximally unroll, does it get too big?
- // Allow the unrolled mess to get larger than standard loop
- // size. After all, it will no longer be a loop.
- uint body_size = _body.size();
+ // Allow the unrolled body to get larger than the standard loop size limit.
uint unroll_limit = (uint)LoopUnrollLimit * 4;
assert((intx)unroll_limit == LoopUnrollLimit * 4, "LoopUnrollLimit must fit in 32bits");
- if (trip_count > unroll_limit || body_size > unroll_limit) {
+ if (trip_count > unroll_limit || _body.size() > unroll_limit) {
return false;
}
- // Take into account that after unroll conjoined heads and tails will fold,
- // otherwise policy_unroll() may allow more unrolling than max unrolling.
- uint new_body_size = est_loop_unroll_sz(trip_count, body_size - EMPTY_LOOP_SIZE);
+ uint new_body_size = est_loop_unroll_sz(trip_count);
if (new_body_size == UINT_MAX) { // Check for bad estimate (overflow).
return false;
}
- // Fully unroll a loop with few iterations regardless next conditions since
- // following loop optimizations will split such loop anyway (pre-main-post).
+ // Fully unroll a loop with few iterations, regardless of other conditions,
+ // since the following (general) loop optimizations will split such loop in
+ // any case (into pre-main-post).
if (trip_count <= 3) {
return phase->may_require_nodes(new_body_size);
}
- if (new_body_size > unroll_limit ||
- // Unrolling can result in a large amount of node construction
- phase->exceeding_node_budget(new_body_size)) {
+ // Reject if unrolling will result in too much node construction.
+ if (new_body_size > unroll_limit || phase->exceeding_node_budget(new_body_size)) {
return false;
}
--- a/src/hotspot/share/opto/loopnode.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/opto/loopnode.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -2471,6 +2471,39 @@
assert((estimate - cc) / factor == sz + bc, "overflow");
+ return estimate + est_loop_flow_merge_sz();
+}
+
+// The Estimated Loop (full-) Unroll Size:
+// UnrollFactor * (~106% * BodySize) + CC + FanOutTerm,
+// where CC is a (totally) ad-hoc/magic "clone" constant, used to ensure that
+// node usage estimates made are on the safe side, for the most part. This is
+// a "light" version of the loop clone size calculation (above), based on the
+// assumption that most of the loop-construct overhead will be unraveled when
+// (fully) unrolled. Defined for unroll factors larger or equal to one (>=1),
+// including an overflow check and returning UINT_MAX in case of an overflow.
+uint IdealLoopTree::est_loop_unroll_sz(uint factor) const {
+
+ precond(factor > 0);
+
+ // Take into account that after unroll conjoined heads and tails will fold.
+ uint const b0 = _body.size() - EMPTY_LOOP_SIZE;
+ uint const cc = 7;
+ uint const sz = b0 + (b0 + 15) / 16;
+ uint estimate = factor * sz + cc;
+
+ if ((estimate - cc) / factor != sz) {
+ return UINT_MAX;
+ }
+
+ return estimate + est_loop_flow_merge_sz();
+}
+
+// Estimate the growth effect (in nodes) of merging control and data flow when
+// cloning a loop body, based on the amount of control and data flow reaching
+// outside of the (current) loop body.
+uint IdealLoopTree::est_loop_flow_merge_sz() const {
+
uint ctrl_edge_out_cnt = 0;
uint data_edge_out_cnt = 0;
@@ -2494,24 +2527,21 @@
}
}
}
- // Add data and control count (x2.0) to estimate iff both are > 0. This is
+ // Use data and control count (x2.0) in estimate iff both are > 0. This is
// a rather pessimistic estimate for the most part, in particular for some
// complex loops, but still not enough to capture all loops.
if (ctrl_edge_out_cnt > 0 && data_edge_out_cnt > 0) {
- estimate += 2 * (ctrl_edge_out_cnt + data_edge_out_cnt);
+ return 2 * (ctrl_edge_out_cnt + data_edge_out_cnt);
}
-
- return estimate;
+ return 0;
}
#ifndef PRODUCT
//------------------------------dump_head--------------------------------------
// Dump 1 liner for loop header info
void IdealLoopTree::dump_head() const {
- for (uint i = 0; i < _nest; i++) {
- tty->print(" ");
- }
- tty->print("Loop: N%d/N%d ",_head->_idx,_tail->_idx);
+ tty->sp(2 * _nest);
+ tty->print("Loop: N%d/N%d ", _head->_idx, _tail->_idx);
if (_irreducible) tty->print(" IRREDUCIBLE");
Node* entry = _head->is_Loop() ? _head->as_Loop()->skip_strip_mined(-1)->in(LoopNode::EntryControl) : _head->in(LoopNode::EntryControl);
Node* predicate = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
@@ -4501,69 +4531,67 @@
#ifndef PRODUCT
//------------------------------dump-------------------------------------------
-void PhaseIdealLoop::dump( ) const {
+void PhaseIdealLoop::dump() const {
ResourceMark rm;
Arena* arena = Thread::current()->resource_area();
Node_Stack stack(arena, C->live_nodes() >> 2);
Node_List rpo_list;
VectorSet visited(arena);
visited.set(C->top()->_idx);
- rpo( C->root(), stack, visited, rpo_list );
+ rpo(C->root(), stack, visited, rpo_list);
// Dump root loop indexed by last element in PO order
- dump( _ltree_root, rpo_list.size(), rpo_list );
+ dump(_ltree_root, rpo_list.size(), rpo_list);
}
-void PhaseIdealLoop::dump( IdealLoopTree *loop, uint idx, Node_List &rpo_list ) const {
+void PhaseIdealLoop::dump(IdealLoopTree* loop, uint idx, Node_List &rpo_list) const {
loop->dump_head();
// Now scan for CFG nodes in the same loop
- for( uint j=idx; j > 0; j-- ) {
- Node *n = rpo_list[j-1];
- if( !_nodes[n->_idx] ) // Skip dead nodes
+ for (uint j = idx; j > 0; j--) {
+ Node* n = rpo_list[j-1];
+ if (!_nodes[n->_idx]) // Skip dead nodes
continue;
- if( get_loop(n) != loop ) { // Wrong loop nest
- if( get_loop(n)->_head == n && // Found nested loop?
- get_loop(n)->_parent == loop )
- dump(get_loop(n),rpo_list.size(),rpo_list); // Print it nested-ly
+
+ if (get_loop(n) != loop) { // Wrong loop nest
+ if (get_loop(n)->_head == n && // Found nested loop?
+ get_loop(n)->_parent == loop)
+ dump(get_loop(n), rpo_list.size(), rpo_list); // Print it nested-ly
continue;
}
// Dump controlling node
- for( uint x = 0; x < loop->_nest; x++ )
- tty->print(" ");
+ tty->sp(2 * loop->_nest);
tty->print("C");
- if( n == C->root() ) {
+ if (n == C->root()) {
n->dump();
} else {
Node* cached_idom = idom_no_update(n);
- Node *computed_idom = n->in(0);
- if( n->is_Region() ) {
+ Node* computed_idom = n->in(0);
+ if (n->is_Region()) {
computed_idom = compute_idom(n);
// computed_idom() will return n->in(0) when idom(n) is an IfNode (or
// any MultiBranch ctrl node), so apply a similar transform to
// the cached idom returned from idom_no_update.
cached_idom = find_non_split_ctrl(cached_idom);
}
- tty->print(" ID:%d",computed_idom->_idx);
+ tty->print(" ID:%d", computed_idom->_idx);
n->dump();
- if( cached_idom != computed_idom ) {
+ if (cached_idom != computed_idom) {
tty->print_cr("*** BROKEN IDOM! Computed as: %d, cached as: %d",
computed_idom->_idx, cached_idom->_idx);
}
}
// Dump nodes it controls
- for( uint k = 0; k < _nodes.Size(); k++ ) {
+ for (uint k = 0; k < _nodes.Size(); k++) {
// (k < C->unique() && get_ctrl(find(k)) == n)
if (k < C->unique() && _nodes[k] == (Node*)((intptr_t)n + 1)) {
- Node *m = C->root()->find(k);
- if( m && m->outcnt() > 0 ) {
+ Node* m = C->root()->find(k);
+ if (m && m->outcnt() > 0) {
if (!(has_ctrl(m) && get_ctrl_no_update(m) == n)) {
tty->print_cr("*** BROKEN CTRL ACCESSOR! _nodes[k] is %p, ctrl is %p",
_nodes[k], has_ctrl(m) ? get_ctrl_no_update(m) : NULL);
}
- for( uint j = 0; j < loop->_nest; j++ )
- tty->print(" ");
- tty->print(" ");
+ tty->sp(2 * loop->_nest + 1);
m->dump();
}
}
@@ -4574,7 +4602,7 @@
// Collect a R-P-O for the whole CFG.
// Result list is in post-order (scan backwards for RPO)
-void PhaseIdealLoop::rpo( Node *start, Node_Stack &stk, VectorSet &visited, Node_List &rpo_list ) const {
+void PhaseIdealLoop::rpo(Node* start, Node_Stack &stk, VectorSet &visited, Node_List &rpo_list) const {
stk.push(start, 0);
visited.set(start->_idx);
@@ -4596,7 +4624,7 @@
//=============================================================================
-//------------------------------LoopTreeIterator-----------------------------------
+//------------------------------LoopTreeIterator-------------------------------
// Advance to next loop tree using a preorder, left-to-right traversal.
void LoopTreeIterator::next() {
--- a/src/hotspot/share/opto/loopnode.hpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/opto/loopnode.hpp Sun Sep 29 13:59:54 2019 +0200
@@ -623,6 +623,8 @@
// Estimate the number of nodes required when cloning a loop (body).
uint est_loop_clone_sz(uint factor) const;
+ // Estimate the number of nodes required when unrolling a loop (body).
+ uint est_loop_unroll_sz(uint factor) const;
// Compute loop trip count if possible
void compute_trip_count(PhaseIdealLoop* phase);
@@ -654,11 +656,16 @@
void remove_main_post_loops(CountedLoopNode *cl, PhaseIdealLoop *phase);
#ifndef PRODUCT
- void dump_head( ) const; // Dump loop head only
+ void dump_head() const; // Dump loop head only
void dump() const; // Dump this loop recursively
void verify_tree(IdealLoopTree *loop, const IdealLoopTree *parent) const;
#endif
+ private:
+ enum { EMPTY_LOOP_SIZE = 7 }; // Number of nodes in an empty loop.
+
+ // Estimate the number of nodes resulting from control and data flow merge.
+ uint est_loop_flow_merge_sz() const;
};
// -----------------------------PhaseIdealLoop---------------------------------
@@ -675,7 +682,7 @@
PhaseIterGVN &_igvn;
// Head of loop tree
- IdealLoopTree *_ltree_root;
+ IdealLoopTree* _ltree_root;
// Array of pre-order numbers, plus post-visited bit.
// ZERO for not pre-visited. EVEN for pre-visited but not post-visited.
@@ -1017,9 +1024,9 @@
bool _has_irreducible_loops;
// Per-Node transform
- virtual Node *transform( Node *a_node ) { return 0; }
+ virtual Node* transform(Node* n) { return 0; }
- bool is_counted_loop(Node* x, IdealLoopTree*& loop);
+ bool is_counted_loop(Node* n, IdealLoopTree* &loop);
IdealLoopTree* create_outer_strip_mined_loop(BoolNode *test, Node *cmp, Node *init_control,
IdealLoopTree* loop, float cl_prob, float le_fcnt,
Node*& entry_control, Node*& iffalse);
@@ -1034,7 +1041,7 @@
return (IdealLoopTree*)_nodes[n->_idx];
}
- IdealLoopTree *ltree_root() const { return _ltree_root; }
+ IdealLoopTree* ltree_root() const { return _ltree_root; }
// Is 'n' a (nested) member of 'loop'?
int is_member( const IdealLoopTree *loop, Node *n ) const {
@@ -1319,7 +1326,7 @@
// same block. Split thru the Region.
void do_split_if( Node *iff );
- // Conversion of fill/copy patterns into intrisic versions
+ // Conversion of fill/copy patterns into intrinsic versions
bool do_intrinsify_fill();
bool intrinsify_fill(IdealLoopTree* lpt);
bool match_fill_loop(IdealLoopTree* lpt, Node*& store, Node*& store_value,
@@ -1419,18 +1426,18 @@
public:
void set_created_loop_node() { _created_loop_node = true; }
bool created_loop_node() { return _created_loop_node; }
- void register_new_node( Node *n, Node *blk );
+ void register_new_node(Node* n, Node* blk);
#ifdef ASSERT
void dump_bad_graph(const char* msg, Node* n, Node* early, Node* LCA);
#endif
#ifndef PRODUCT
- void dump( ) const;
- void dump( IdealLoopTree *loop, uint rpo_idx, Node_List &rpo_list ) const;
+ void dump() const;
+ void dump(IdealLoopTree* loop, uint rpo_idx, Node_List &rpo_list) const;
void verify() const; // Major slow :-)
- void verify_compare( Node *n, const PhaseIdealLoop *loop_verify, VectorSet &visited ) const;
- IdealLoopTree *get_loop_idx(Node* n) const {
+ void verify_compare(Node* n, const PhaseIdealLoop* loop_verify, VectorSet &visited) const;
+ IdealLoopTree* get_loop_idx(Node* n) const {
// Dead nodes have no loop, so return the top level loop instead
return _nodes[n->_idx] ? (IdealLoopTree*)_nodes[n->_idx] : _ltree_root;
}
@@ -1439,7 +1446,8 @@
static int _loop_invokes; // Count of PhaseIdealLoop invokes
static int _loop_work; // Sum of PhaseIdealLoop x _unique
#endif
- void rpo( Node *start, Node_Stack &stk, VectorSet &visited, Node_List &rpo_list ) const;
+
+ void rpo(Node* start, Node_Stack &stk, VectorSet &visited, Node_List &rpo_list) const;
};
--- a/src/hotspot/share/opto/loopopts.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/opto/loopopts.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -653,7 +653,10 @@
}
}//for
Node* bol = iff->in(1);
- assert(bol->Opcode() == Op_Bool, "");
+ if (bol->Opcode() == Op_Opaque4) {
+ return NULL; // Ignore loop predicate checks (the Opaque4 ensures they will go away)
+ }
+ assert(bol->Opcode() == Op_Bool, "Unexpected node");
int cmp_op = bol->in(1)->Opcode();
// It is expensive to generate flags from a float compare.
// Avoid duplicated float compare.
--- a/src/hotspot/share/opto/macro.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/opto/macro.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1652,14 +1652,11 @@
Node* size_in_bytes) {
InitializeNode* init = alloc->initialization();
// Store the klass & mark bits
- Node* mark_node = NULL;
- // For now only enable fast locking for non-array types
- if (UseBiasedLocking && (length == NULL)) {
- mark_node = make_load(control, rawmem, klass_node, in_bytes(Klass::prototype_header_offset()), TypeRawPtr::BOTTOM, T_ADDRESS);
- } else {
- mark_node = makecon(TypeRawPtr::make((address)markWord::prototype().value()));
+ Node* mark_node = alloc->make_ideal_mark(&_igvn, object, control, rawmem);
+ if (!mark_node->is_Con()) {
+ transform_later(mark_node);
}
- rawmem = make_store(control, rawmem, object, oopDesc::mark_offset_in_bytes(), mark_node, T_ADDRESS);
+ rawmem = make_store(control, rawmem, object, oopDesc::mark_offset_in_bytes(), mark_node, TypeX_X->basic_type());
rawmem = make_store(control, rawmem, object, oopDesc::klass_offset_in_bytes(), klass_node, T_METADATA);
int header_size = alloc->minimum_header_size(); // conservatively small
@@ -2596,15 +2593,36 @@
if (_igvn.type(n) == Type::TOP || (n->in(0) != NULL && n->in(0)->is_top())) {
// node is unreachable, so don't try to expand it
C->remove_macro_node(n);
- } else if (n->is_ArrayCopy()){
- int macro_count = C->macro_count();
+ continue;
+ }
+ int macro_count = C->macro_count();
+ switch (n->class_id()) {
+ case Node::Class_Lock:
+ expand_lock_node(n->as_Lock());
+ assert(C->macro_count() < macro_count, "must have deleted a node from macro list");
+ break;
+ case Node::Class_Unlock:
+ expand_unlock_node(n->as_Unlock());
+ assert(C->macro_count() < macro_count, "must have deleted a node from macro list");
+ break;
+ case Node::Class_ArrayCopy:
expand_arraycopy_node(n->as_ArrayCopy());
assert(C->macro_count() < macro_count, "must have deleted a node from macro list");
+ break;
}
if (C->failing()) return true;
macro_idx --;
}
+ // All nodes except Allocate nodes are expanded now. There could be
+ // new optimization opportunities (such as folding newly created
+ // load from a just allocated object). Run IGVN.
+ _igvn.set_delay_transform(false);
+ _igvn.optimize();
+ if (C->failing()) return true;
+
+ _igvn.set_delay_transform(true);
+
// expand "macro" nodes
// nodes are removed from the macro list as they are processed
while (C->macro_count() > 0) {
@@ -2623,12 +2641,6 @@
case Node::Class_AllocateArray:
expand_allocate_array(n->as_AllocateArray());
break;
- case Node::Class_Lock:
- expand_lock_node(n->as_Lock());
- break;
- case Node::Class_Unlock:
- expand_unlock_node(n->as_Unlock());
- break;
default:
assert(false, "unknown node type in macro list");
}
--- a/src/hotspot/share/opto/memnode.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/opto/memnode.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1555,6 +1555,22 @@
return phi;
}
+AllocateNode* LoadNode::is_new_object_mark_load(PhaseGVN *phase) const {
+ if (Opcode() == Op_LoadX) {
+ Node* address = in(MemNode::Address);
+ AllocateNode* alloc = AllocateNode::Ideal_allocation(address, phase);
+ Node* mem = in(MemNode::Memory);
+ if (alloc != NULL && mem->is_Proj() &&
+ mem->in(0) != NULL &&
+ mem->in(0) == alloc->initialization() &&
+ alloc->initialization()->proj_out_or_null(0) != NULL) {
+ return alloc;
+ }
+ }
+ return NULL;
+}
+
+
//------------------------------Ideal------------------------------------------
// If the load is from Field memory and the pointer is non-null, it might be possible to
// zero out the control input.
@@ -1683,6 +1699,13 @@
}
}
+ AllocateNode* alloc = is_new_object_mark_load(phase);
+ if (alloc != NULL && alloc->Opcode() == Op_Allocate && UseBiasedLocking) {
+ InitializeNode* init = alloc->initialization();
+ Node* control = init->proj_out(0);
+ return alloc->make_ideal_mark(phase, address, control, mem);
+ }
+
return progress ? this : NULL;
}
@@ -1941,6 +1964,12 @@
return Type::get_zero_type(_type->basic_type());
}
}
+
+ Node* alloc = is_new_object_mark_load(phase);
+ if (alloc != NULL && !(alloc->Opcode() == Op_Allocate && UseBiasedLocking)) {
+ return TypeX::make(markWord::prototype().value());
+ }
+
return _type;
}
--- a/src/hotspot/share/opto/memnode.hpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/opto/memnode.hpp Sun Sep 29 13:59:54 2019 +0200
@@ -183,6 +183,8 @@
uint _barrier; // Bit field with barrier information
+ AllocateNode* is_new_object_mark_load(PhaseGVN *phase) const;
+
protected:
virtual bool cmp(const Node &n) const;
virtual uint size_of() const; // Size is bigger
--- a/src/hotspot/share/opto/type.hpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/opto/type.hpp Sun Sep 29 13:59:54 2019 +0200
@@ -1791,6 +1791,7 @@
#define Op_SubX Op_SubL
#define Op_XorX Op_XorL
#define Op_URShiftX Op_URShiftL
+#define Op_LoadX Op_LoadL
// conversions
#define ConvI2X(x) ConvI2L(x)
#define ConvL2X(x) (x)
@@ -1838,6 +1839,7 @@
#define Op_SubX Op_SubI
#define Op_XorX Op_XorI
#define Op_URShiftX Op_URShiftI
+#define Op_LoadX Op_LoadI
// conversions
#define ConvI2X(x) (x)
#define ConvL2X(x) ConvL2I(x)
--- a/src/hotspot/share/prims/jvmtiExport.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/prims/jvmtiExport.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -304,7 +304,7 @@
bool JvmtiExport::_can_modify_any_class = false;
bool JvmtiExport::_can_walk_any_space = false;
-bool JvmtiExport::_has_redefined_a_class = false;
+uint64_t JvmtiExport::_redefinition_count = 0;
bool JvmtiExport::_all_dependencies_are_recorded = false;
//
--- a/src/hotspot/share/prims/jvmtiExport.hpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/prims/jvmtiExport.hpp Sun Sep 29 13:59:54 2019 +0200
@@ -173,10 +173,10 @@
// one or more classes during the lifetime of the VM. The flag should
// only be set by the friend class and can be queried by other sub
// systems as needed to relax invariant checks.
- static bool _has_redefined_a_class;
+ static uint64_t _redefinition_count;
friend class VM_RedefineClasses;
- inline static void set_has_redefined_a_class() {
- JVMTI_ONLY(_has_redefined_a_class = true;)
+ inline static void increment_redefinition_count() {
+ JVMTI_ONLY(_redefinition_count++;)
}
// Flag to indicate if the compiler has recorded all dependencies. When the
// can_redefine_classes capability is enabled in the OnLoad phase then the compiler
@@ -188,10 +188,16 @@
public:
inline static bool has_redefined_a_class() {
- JVMTI_ONLY(return _has_redefined_a_class);
+ JVMTI_ONLY(return _redefinition_count != 0);
NOT_JVMTI(return false);
}
+ // Only set in safepoint, so no memory ordering needed.
+ inline static uint64_t redefinition_count() {
+ JVMTI_ONLY(return _redefinition_count);
+ NOT_JVMTI(return 0);
+ }
+
inline static bool all_dependencies_are_recorded() {
return _all_dependencies_are_recorded;
}
--- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -232,9 +232,9 @@
ResolvedMethodTable::adjust_method_entries(&trace_name_printed);
}
- // Set flag indicating that some invariants are no longer true.
+ // Increment flag indicating that some invariants are no longer true.
// See jvmtiExport.hpp for detailed explanation.
- JvmtiExport::set_has_redefined_a_class();
+ JvmtiExport::increment_redefinition_count();
// check_class() is optionally called for product bits, but is
// always called for non-product bits.
--- a/src/hotspot/share/prims/whitebox.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/prims/whitebox.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1735,12 +1735,12 @@
WB_END
WB_ENTRY(void, WB_AssertMatchingSafepointCalls(JNIEnv* env, jobject o, jboolean mutexSafepointValue, jboolean attemptedNoSafepointValue))
- Monitor::SafepointCheckRequired sfpt_check_required = mutexSafepointValue ?
- Monitor::_safepoint_check_always :
- Monitor::_safepoint_check_never;
- Monitor::SafepointCheckFlag sfpt_check_attempted = attemptedNoSafepointValue ?
- Monitor::_no_safepoint_check_flag :
- Monitor::_safepoint_check_flag;
+ Mutex::SafepointCheckRequired sfpt_check_required = mutexSafepointValue ?
+ Mutex::_safepoint_check_always :
+ Mutex::_safepoint_check_never;
+ Mutex::SafepointCheckFlag sfpt_check_attempted = attemptedNoSafepointValue ?
+ Mutex::_no_safepoint_check_flag :
+ Mutex::_safepoint_check_flag;
MutexLocker ml(new Mutex(Mutex::leaf, "SFPT_Test_lock", true, sfpt_check_required),
sfpt_check_attempted);
WB_END
--- a/src/hotspot/share/runtime/arguments.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/runtime/arguments.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -526,7 +526,6 @@
{ "MinRAMFraction", JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() },
{ "InitialRAMFraction", JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() },
{ "UseMembar", JDK_Version::jdk(10), JDK_Version::jdk(12), JDK_Version::undefined() },
- { "CompilationPolicyChoice", JDK_Version::jdk(13), JDK_Version::jdk(14), JDK_Version::undefined() },
{ "AllowJNIEnvProxy", JDK_Version::jdk(13), JDK_Version::jdk(14), JDK_Version::jdk(15) },
{ "ThreadLocalHandshakes", JDK_Version::jdk(13), JDK_Version::jdk(14), JDK_Version::jdk(15) },
{ "AllowRedefinitionToAddDeleteMethods", JDK_Version::jdk(13), JDK_Version::undefined(), JDK_Version::undefined() },
@@ -547,6 +546,7 @@
{ "SharedReadOnlySize", JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
{ "SharedMiscDataSize", JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
{ "SharedMiscCodeSize", JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
+ { "CompilationPolicyChoice", JDK_Version::jdk(13), JDK_Version::jdk(14), JDK_Version::jdk(15) },
{ "FailOverToOldVerifier", JDK_Version::undefined(), JDK_Version::jdk(14), JDK_Version::jdk(15) },
{ "BindGCTaskThreadsToCPUs", JDK_Version::undefined(), JDK_Version::jdk(14), JDK_Version::jdk(16) },
{ "UseGCTaskAffinity", JDK_Version::undefined(), JDK_Version::jdk(14), JDK_Version::jdk(16) },
--- a/src/hotspot/share/runtime/compilationPolicy.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/runtime/compilationPolicy.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -36,7 +36,6 @@
#include "runtime/compilationPolicy.hpp"
#include "runtime/frame.hpp"
#include "runtime/handles.inline.hpp"
-#include "runtime/rframe.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.hpp"
#include "runtime/tieredThresholdPolicy.hpp"
@@ -56,28 +55,16 @@
// Determine compilation policy based on command line argument
void compilationPolicy_init() {
- switch(CompilationPolicyChoice) {
- case 0:
+ #ifdef TIERED
+ if (TieredCompilation) {
+ CompilationPolicy::set_policy(new TieredThresholdPolicy());
+ } else {
CompilationPolicy::set_policy(new SimpleCompPolicy());
- break;
+ }
+ #else
+ CompilationPolicy::set_policy(new SimpleCompPolicy());
+ #endif
- case 1:
-#ifdef COMPILER2
- CompilationPolicy::set_policy(new StackWalkCompPolicy());
-#else
- Unimplemented();
-#endif
- break;
- case 2:
-#ifdef TIERED
- CompilationPolicy::set_policy(new TieredThresholdPolicy());
-#else
- Unimplemented();
-#endif
- break;
- default:
- fatal("CompilationPolicyChoice must be in the range: [0-2]");
- }
CompilationPolicy::policy()->initialize();
}
@@ -519,208 +506,3 @@
NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
}
}
-// StackWalkCompPolicy - walk up stack to find a suitable method to compile
-
-#ifdef COMPILER2
-const char* StackWalkCompPolicy::_msg = NULL;
-
-
-// Consider m for compilation
-void StackWalkCompPolicy::method_invocation_event(const methodHandle& m, JavaThread* thread) {
- const int comp_level = CompLevel_highest_tier;
- const int hot_count = m->invocation_count();
- reset_counter_for_invocation_event(m);
-
- if (is_compilation_enabled() && m->code() == NULL && can_be_compiled(m, comp_level)) {
- ResourceMark rm(thread);
- frame fr = thread->last_frame();
- assert(fr.is_interpreted_frame(), "must be interpreted");
- assert(fr.interpreter_frame_method() == m(), "bad method");
-
- RegisterMap reg_map(thread, false);
- javaVFrame* triggerVF = thread->last_java_vframe(®_map);
- // triggerVF is the frame that triggered its counter
- RFrame* first = new InterpretedRFrame(triggerVF->fr(), thread, m());
-
- if (first->top_method()->code() != NULL) {
- // called obsolete method/nmethod -- no need to recompile
- } else {
- GrowableArray<RFrame*>* stack = new GrowableArray<RFrame*>(50);
- stack->push(first);
- RFrame* top = findTopInlinableFrame(stack);
- assert(top != NULL, "findTopInlinableFrame returned null");
- CompileBroker::compile_method(top->top_method(), InvocationEntryBci, comp_level,
- m, hot_count, CompileTask::Reason_InvocationCount, thread);
- }
- }
-}
-
-void StackWalkCompPolicy::method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread) {
- const int comp_level = CompLevel_highest_tier;
- const int hot_count = m->backedge_count();
-
- if (is_compilation_enabled() && can_be_osr_compiled(m, comp_level)) {
- CompileBroker::compile_method(m, bci, comp_level, m, hot_count, CompileTask::Reason_BackedgeCount, thread);
- NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
- }
-}
-
-RFrame* StackWalkCompPolicy::findTopInlinableFrame(GrowableArray<RFrame*>* stack) {
- // go up the stack until finding a frame that (probably) won't be inlined
- // into its caller
- RFrame* current = stack->at(0); // current choice for stopping
- assert( current && !current->is_compiled(), "" );
- const char* msg = NULL;
-
- while (1) {
-
- // before going up the stack further, check if doing so would get us into
- // compiled code
- RFrame* next = senderOf(current, stack);
- if( !next ) // No next frame up the stack?
- break; // Then compile with current frame
-
- Method* m = current->top_method();
- Method* next_m = next->top_method();
-
- if( !Inline ) { // Inlining turned off
- msg = "Inlining turned off";
- break;
- }
- if (next_m->is_not_compilable()) { // Did fail to compile this before/
- msg = "caller not compilable";
- break;
- }
- if (next->num() > MaxRecompilationSearchLength) {
- // don't go up too high when searching for recompilees
- msg = "don't go up any further: > MaxRecompilationSearchLength";
- break;
- }
- if (next->distance() > MaxInterpretedSearchLength) {
- // don't go up too high when searching for recompilees
- msg = "don't go up any further: next > MaxInterpretedSearchLength";
- break;
- }
- // Compiled frame above already decided not to inline;
- // do not recompile him.
- if (next->is_compiled()) {
- msg = "not going up into optimized code";
- break;
- }
-
- // Interpreted frame above us was already compiled. Do not force
- // a recompile, although if the frame above us runs long enough an
- // OSR might still happen.
- if( current->is_interpreted() && next_m->has_compiled_code() ) {
- msg = "not going up -- already compiled caller";
- break;
- }
-
- // Compute how frequent this call site is. We have current method 'm'.
- // We know next method 'next_m' is interpreted. Find the call site and
- // check the various invocation counts.
- int invcnt = 0; // Caller counts
- if (ProfileInterpreter) {
- invcnt = next_m->interpreter_invocation_count();
- }
- int cnt = 0; // Call site counts
- if (ProfileInterpreter && next_m->method_data() != NULL) {
- ResourceMark rm;
- int bci = next->top_vframe()->bci();
- ProfileData* data = next_m->method_data()->bci_to_data(bci);
- if (data != NULL && data->is_CounterData())
- cnt = data->as_CounterData()->count();
- }
-
- // Caller counts / call-site counts; i.e. is this call site
- // a hot call site for method next_m?
- int freq = (invcnt) ? cnt/invcnt : cnt;
-
- // Check size and frequency limits
- if ((msg = shouldInline(m, freq, cnt)) != NULL) {
- break;
- }
- // Check inlining negative tests
- if ((msg = shouldNotInline(m)) != NULL) {
- break;
- }
-
-
- // If the caller method is too big or something then we do not want to
- // compile it just to inline a method
- if (!can_be_compiled(next_m, CompLevel_any)) {
- msg = "caller cannot be compiled";
- break;
- }
-
- if( next_m->name() == vmSymbols::class_initializer_name() ) {
- msg = "do not compile class initializer (OSR ok)";
- break;
- }
-
- current = next;
- }
-
- assert( !current || !current->is_compiled(), "" );
-
- return current;
-}
-
-RFrame* StackWalkCompPolicy::senderOf(RFrame* rf, GrowableArray<RFrame*>* stack) {
- RFrame* sender = rf->caller();
- if (sender && sender->num() == stack->length()) stack->push(sender);
- return sender;
-}
-
-
-const char* StackWalkCompPolicy::shouldInline(const methodHandle& m, float freq, int cnt) {
- // Allows targeted inlining
- // positive filter: should send be inlined? returns NULL (--> yes)
- // or rejection msg
- int max_size = MaxInlineSize;
- int cost = m->code_size();
-
- // Check for too many throws (and not too huge)
- if (m->interpreter_throwout_count() > InlineThrowCount && cost < InlineThrowMaxSize ) {
- return NULL;
- }
-
- // bump the max size if the call is frequent
- if ((freq >= InlineFrequencyRatio) || (cnt >= InlineFrequencyCount)) {
- if (TraceFrequencyInlining) {
- tty->print("(Inlined frequent method)\n");
- m->print();
- }
- max_size = FreqInlineSize;
- }
- if (cost > max_size) {
- return (_msg = "too big");
- }
- return NULL;
-}
-
-
-const char* StackWalkCompPolicy::shouldNotInline(const methodHandle& m) {
- // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg
- if (m->is_abstract()) return (_msg = "abstract method");
- // note: we allow ik->is_abstract()
- if (!m->method_holder()->is_initialized()) return (_msg = "method holder not initialized");
- if (m->is_native()) return (_msg = "native method");
- CompiledMethod* m_code = m->code();
- if (m_code != NULL && m_code->code_size() > InlineSmallCode)
- return (_msg = "already compiled into a big method");
-
- // use frequency-based objections only for non-trivial methods
- if (m->code_size() <= MaxTrivialSize) return NULL;
- if (UseInterpreter) { // don't use counts with -Xcomp
- if ((m->code() == NULL) && m->was_never_executed()) return (_msg = "never executed");
- if (!m->was_executed_more_than(MIN2(MinInliningThreshold, CompileThreshold >> 1))) return (_msg = "executed < MinInliningThreshold times");
- }
- if (Method::has_unloaded_classes_in_signature(m, JavaThread::current())) return (_msg = "unloaded signature classes");
-
- return NULL;
-}
-
-
-
-#endif // COMPILER2
--- a/src/hotspot/share/runtime/compilationPolicy.hpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/runtime/compilationPolicy.hpp Sun Sep 29 13:59:54 2019 +0200
@@ -36,7 +36,6 @@
// interpreted).
class CompileTask;
class CompileQueue;
-class RFrame;
class CompilationPolicy : public CHeapObj<mtCompiler> {
static CompilationPolicy* _policy;
@@ -116,28 +115,4 @@
virtual void method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread);
};
-// StackWalkCompPolicy - existing C2 policy
-
-#ifdef COMPILER2
-class StackWalkCompPolicy : public NonTieredCompPolicy {
- public:
- virtual void method_invocation_event(const methodHandle& m, JavaThread* thread);
- virtual void method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread);
-
- private:
- RFrame* findTopInlinableFrame(GrowableArray<RFrame*>* stack);
- RFrame* senderOf(RFrame* rf, GrowableArray<RFrame*>* stack);
-
- // the following variables hold values computed by the last inlining decision
- // they are used for performance debugging only (print better messages)
- static const char* _msg; // reason for not inlining
-
- static const char* shouldInline (const methodHandle& callee, float frequency, int cnt);
- // positive filter: should send be inlined? returns NULL (--> yes) or rejection msg
- static const char* shouldNotInline(const methodHandle& callee);
- // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg
-
-};
-#endif
-
#endif // SHARE_RUNTIME_COMPILATIONPOLICY_HPP
--- a/src/hotspot/share/runtime/globals.hpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/runtime/globals.hpp Sun Sep 29 13:59:54 2019 +0200
@@ -1017,10 +1017,6 @@
"Inject thread creation failures for " \
"UseDynamicNumberOfCompilerThreads") \
\
- product(intx, CompilationPolicyChoice, 0, \
- "which compilation policy (0-2)") \
- range(0, 2) \
- \
develop(bool, UseStackBanging, true, \
"use stack banging for stack overflow checks (required for " \
"proper StackOverflow handling; disable only to measure cost " \
@@ -2143,14 +2139,6 @@
"% of CompileThreshold) before profiling in the interpreter") \
range(0, 100) \
\
- develop(intx, MaxRecompilationSearchLength, 10, \
- "The maximum number of frames to inspect when searching for " \
- "recompilee") \
- \
- develop(intx, MaxInterpretedSearchLength, 3, \
- "The maximum number of interpreted frames to skip when searching "\
- "for recompilee") \
- \
develop(intx, DesiredMethodLimit, 8000, \
"The desired maximum method size (in bytecodes) after inlining") \
\
--- a/src/hotspot/share/runtime/mutexLocker.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/runtime/mutexLocker.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -191,148 +191,148 @@
#endif
#define def(var, type, pri, vm_block, safepoint_check_allowed ) { \
- var = new type(Mutex::pri, #var, vm_block, safepoint_check_allowed); \
+ var = new type(Mutex::pri, #var, vm_block, Mutex::safepoint_check_allowed); \
assert(_num_mutex < MAX_NUM_MUTEX, "increase MAX_NUM_MUTEX"); \
_mutex_array[_num_mutex++] = var; \
}
// Using Padded subclasses to prevent false sharing of these global monitors and mutexes.
void mutex_init() {
- def(tty_lock , PaddedMutex , tty, true, Monitor::_safepoint_check_never); // allow to lock in VM
+ def(tty_lock , PaddedMutex , tty, true, _safepoint_check_never); // allow to lock in VM
- def(CGC_lock , PaddedMonitor, special, true, Monitor::_safepoint_check_never); // coordinate between fore- and background GC
- def(STS_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_never);
+ def(CGC_lock , PaddedMonitor, special, true, _safepoint_check_never); // coordinate between fore- and background GC
+ def(STS_lock , PaddedMonitor, leaf, true, _safepoint_check_never);
- def(FullGCCount_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_never); // in support of ExplicitGCInvokesConcurrent
+ def(FullGCCount_lock , PaddedMonitor, leaf, true, _safepoint_check_never); // in support of ExplicitGCInvokesConcurrent
if (UseG1GC) {
- def(DirtyCardQ_CBL_mon , PaddedMonitor, access, true, Monitor::_safepoint_check_never);
- def(Shared_DirtyCardQ_lock , PaddedMutex , access + 1, true, Monitor::_safepoint_check_never);
+ def(DirtyCardQ_CBL_mon , PaddedMonitor, access, true, _safepoint_check_never);
+ def(Shared_DirtyCardQ_lock , PaddedMutex , access + 1, true, _safepoint_check_never);
- def(FreeList_lock , PaddedMutex , leaf , true, Monitor::_safepoint_check_never);
- def(OldSets_lock , PaddedMutex , leaf , true, Monitor::_safepoint_check_never);
- def(RootRegionScan_lock , PaddedMonitor, leaf , true, Monitor::_safepoint_check_never);
+ def(FreeList_lock , PaddedMutex , leaf , true, _safepoint_check_never);
+ def(OldSets_lock , PaddedMutex , leaf , true, _safepoint_check_never);
+ def(RootRegionScan_lock , PaddedMonitor, leaf , true, _safepoint_check_never);
- def(StringDedupQueue_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_never);
- def(StringDedupTable_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never);
+ def(StringDedupQueue_lock , PaddedMonitor, leaf, true, _safepoint_check_never);
+ def(StringDedupTable_lock , PaddedMutex , leaf, true, _safepoint_check_never);
- def(MarkStackFreeList_lock , PaddedMutex , leaf , true, Monitor::_safepoint_check_never);
- def(MarkStackChunkList_lock , PaddedMutex , leaf , true, Monitor::_safepoint_check_never);
+ def(MarkStackFreeList_lock , PaddedMutex , leaf , true, _safepoint_check_never);
+ def(MarkStackChunkList_lock , PaddedMutex , leaf , true, _safepoint_check_never);
- def(MonitoringSupport_lock , PaddedMutex , native , true, Monitor::_safepoint_check_never); // used for serviceability monitoring support
+ def(MonitoringSupport_lock , PaddedMutex , native , true, _safepoint_check_never); // used for serviceability monitoring support
}
if (UseShenandoahGC) {
- def(StringDedupQueue_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_never);
- def(StringDedupTable_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never);
+ def(StringDedupQueue_lock , PaddedMonitor, leaf, true, _safepoint_check_never);
+ def(StringDedupTable_lock , PaddedMutex , leaf, true, _safepoint_check_never);
}
- def(ParGCRareEvent_lock , PaddedMutex , leaf , true, Monitor::_safepoint_check_always);
- def(CGCPhaseManager_lock , PaddedMonitor, leaf, false, Monitor::_safepoint_check_always);
- def(CodeCache_lock , PaddedMonitor, special, true, Monitor::_safepoint_check_never);
- def(RawMonitor_lock , PaddedMutex , special, true, Monitor::_safepoint_check_never);
- def(OopMapCacheAlloc_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); // used for oop_map_cache allocation.
+ def(ParGCRareEvent_lock , PaddedMutex , leaf , true, _safepoint_check_always);
+ def(CGCPhaseManager_lock , PaddedMonitor, leaf, false, _safepoint_check_always);
+ def(CodeCache_lock , PaddedMonitor, special, true, _safepoint_check_never);
+ def(RawMonitor_lock , PaddedMutex , special, true, _safepoint_check_never);
+ def(OopMapCacheAlloc_lock , PaddedMutex , leaf, true, _safepoint_check_always); // used for oop_map_cache allocation.
- def(MetaspaceExpand_lock , PaddedMutex , leaf-1, true, Monitor::_safepoint_check_never);
- def(ClassLoaderDataGraph_lock , PaddedMutex , nonleaf, false, Monitor::_safepoint_check_always);
+ def(MetaspaceExpand_lock , PaddedMutex , leaf-1, true, _safepoint_check_never);
+ def(ClassLoaderDataGraph_lock , PaddedMutex , nonleaf, false, _safepoint_check_always);
- def(Patching_lock , PaddedMutex , special, true, Monitor::_safepoint_check_never); // used for safepointing and code patching.
- def(CompiledMethod_lock , PaddedMutex , special-1, true, Monitor::_safepoint_check_never);
- def(Service_lock , PaddedMonitor, special, true, Monitor::_safepoint_check_never); // used for service thread operations
- def(JmethodIdCreation_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); // used for creating jmethodIDs.
+ def(Patching_lock , PaddedMutex , special, true, _safepoint_check_never); // used for safepointing and code patching.
+ def(CompiledMethod_lock , PaddedMutex , special-1, true, _safepoint_check_never);
+ def(Service_lock , PaddedMonitor, special, true, _safepoint_check_never); // used for service thread operations
+ def(JmethodIdCreation_lock , PaddedMutex , leaf, true, _safepoint_check_always); // used for creating jmethodIDs.
- def(SystemDictionary_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_always);
- def(ProtectionDomainSet_lock , PaddedMutex , leaf-1, true, Monitor::_safepoint_check_never);
- def(SharedDictionary_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always);
- def(Module_lock , PaddedMutex , leaf+2, false, Monitor::_safepoint_check_always);
- def(InlineCacheBuffer_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never);
- def(VMStatistic_lock , PaddedMutex , leaf, false, Monitor::_safepoint_check_always);
- def(ExpandHeap_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); // Used during compilation by VM thread
- def(JNIHandleBlockFreeList_lock , PaddedMutex , leaf-1, true, Monitor::_safepoint_check_never); // handles are used by VM thread
- def(SignatureHandlerLibrary_lock , PaddedMutex , leaf, false, Monitor::_safepoint_check_always);
- def(SymbolArena_lock , PaddedMutex , leaf+2, true, Monitor::_safepoint_check_never);
- def(ProfilePrint_lock , PaddedMutex , leaf, false, Monitor::_safepoint_check_always); // serial profile printing
- def(ExceptionCache_lock , PaddedMutex , leaf, false, Monitor::_safepoint_check_always); // serial profile printing
- def(Debug1_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never);
+ def(SystemDictionary_lock , PaddedMonitor, leaf, true, _safepoint_check_always);
+ def(ProtectionDomainSet_lock , PaddedMutex , leaf-1, true, _safepoint_check_never);
+ def(SharedDictionary_lock , PaddedMutex , leaf, true, _safepoint_check_always);
+ def(Module_lock , PaddedMutex , leaf+2, false, _safepoint_check_always);
+ def(InlineCacheBuffer_lock , PaddedMutex , leaf, true, _safepoint_check_never);
+ def(VMStatistic_lock , PaddedMutex , leaf, false, _safepoint_check_always);
+ def(ExpandHeap_lock , PaddedMutex , leaf, true, _safepoint_check_always); // Used during compilation by VM thread
+ def(JNIHandleBlockFreeList_lock , PaddedMutex , leaf-1, true, _safepoint_check_never); // handles are used by VM thread
+ def(SignatureHandlerLibrary_lock , PaddedMutex , leaf, false, _safepoint_check_always);
+ def(SymbolArena_lock , PaddedMutex , leaf+2, true, _safepoint_check_never);
+ def(ProfilePrint_lock , PaddedMutex , leaf, false, _safepoint_check_always); // serial profile printing
+ def(ExceptionCache_lock , PaddedMutex , leaf, false, _safepoint_check_always); // serial profile printing
+ def(Debug1_lock , PaddedMutex , leaf, true, _safepoint_check_never);
#ifndef PRODUCT
- def(FullGCALot_lock , PaddedMutex , leaf, false, Monitor::_safepoint_check_always); // a lock to make FullGCALot MT safe
+ def(FullGCALot_lock , PaddedMutex , leaf, false, _safepoint_check_always); // a lock to make FullGCALot MT safe
#endif
- def(BeforeExit_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_always);
- def(PerfDataMemAlloc_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); // used for allocating PerfData memory for performance data
- def(PerfDataManager_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); // used for synchronized access to PerfDataManager resources
+ def(BeforeExit_lock , PaddedMonitor, leaf, true, _safepoint_check_always);
+ def(PerfDataMemAlloc_lock , PaddedMutex , leaf, true, _safepoint_check_always); // used for allocating PerfData memory for performance data
+ def(PerfDataManager_lock , PaddedMutex , leaf, true, _safepoint_check_always); // used for synchronized access to PerfDataManager resources
// CMS_modUnionTable_lock leaf
// CMS_bitMap_lock leaf 1
// CMS_freeList_lock leaf 2
- def(Threads_lock , PaddedMonitor, barrier, true, Monitor::_safepoint_check_always); // Used for safepoint protocol.
- def(NonJavaThreadsList_lock , PaddedMutex, leaf, true, Monitor::_safepoint_check_never);
- def(NonJavaThreadsListSync_lock , PaddedMutex, leaf, true, Monitor::_safepoint_check_never);
+ def(Threads_lock , PaddedMonitor, barrier, true, _safepoint_check_always); // Used for safepoint protocol.
+ def(NonJavaThreadsList_lock , PaddedMutex, leaf, true, _safepoint_check_never);
+ def(NonJavaThreadsListSync_lock , PaddedMutex, leaf, true, _safepoint_check_never);
- def(VMOperationQueue_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_never); // VM_thread allowed to block on these
- def(VMOperationRequest_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_always);
- def(RetData_lock , PaddedMutex , nonleaf, false, Monitor::_safepoint_check_always);
- def(Terminator_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_always);
- def(InitCompleted_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_never);
- def(VtableStubs_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_never);
- def(Notify_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_always);
- def(JNICritical_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_always); // used for JNI critical regions
- def(AdapterHandlerLibrary_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_always);
+ def(VMOperationQueue_lock , PaddedMonitor, nonleaf, true, _safepoint_check_never); // VM_thread allowed to block on these
+ def(VMOperationRequest_lock , PaddedMonitor, nonleaf, true, _safepoint_check_always);
+ def(RetData_lock , PaddedMutex , nonleaf, false, _safepoint_check_always);
+ def(Terminator_lock , PaddedMonitor, nonleaf, true, _safepoint_check_always);
+ def(InitCompleted_lock , PaddedMonitor, leaf, true, _safepoint_check_never);
+ def(VtableStubs_lock , PaddedMutex , nonleaf, true, _safepoint_check_never);
+ def(Notify_lock , PaddedMonitor, nonleaf, true, _safepoint_check_always);
+ def(JNICritical_lock , PaddedMonitor, nonleaf, true, _safepoint_check_always); // used for JNI critical regions
+ def(AdapterHandlerLibrary_lock , PaddedMutex , nonleaf, true, _safepoint_check_always);
- def(Heap_lock , PaddedMonitor, nonleaf+1, false, Monitor::_safepoint_check_sometimes); // Doesn't safepoint check during termination.
- def(JfieldIdCreation_lock , PaddedMutex , nonleaf+1, true, Monitor::_safepoint_check_always); // jfieldID, Used in VM_Operation
+ def(Heap_lock , PaddedMonitor, nonleaf+1, false, _safepoint_check_sometimes); // Doesn't safepoint check during termination.
+ def(JfieldIdCreation_lock , PaddedMutex , nonleaf+1, true, _safepoint_check_always); // jfieldID, Used in VM_Operation
- def(CompiledIC_lock , PaddedMutex , nonleaf+2, false, Monitor::_safepoint_check_never); // locks VtableStubs_lock, InlineCacheBuffer_lock
- def(CompileTaskAlloc_lock , PaddedMutex , nonleaf+2, true, Monitor::_safepoint_check_always);
- def(CompileStatistics_lock , PaddedMutex , nonleaf+2, false, Monitor::_safepoint_check_always);
- def(DirectivesStack_lock , PaddedMutex , special, true, Monitor::_safepoint_check_never);
- def(MultiArray_lock , PaddedMutex , nonleaf+2, false, Monitor::_safepoint_check_always);
+ def(CompiledIC_lock , PaddedMutex , nonleaf+2, false, _safepoint_check_never); // locks VtableStubs_lock, InlineCacheBuffer_lock
+ def(CompileTaskAlloc_lock , PaddedMutex , nonleaf+2, true, _safepoint_check_always);
+ def(CompileStatistics_lock , PaddedMutex , nonleaf+2, false, _safepoint_check_always);
+ def(DirectivesStack_lock , PaddedMutex , special, true, _safepoint_check_never);
+ def(MultiArray_lock , PaddedMutex , nonleaf+2, false, _safepoint_check_always);
- def(JvmtiThreadState_lock , PaddedMutex , nonleaf+2, false, Monitor::_safepoint_check_always); // Used by JvmtiThreadState/JvmtiEventController
- def(Management_lock , PaddedMutex , nonleaf+2, false, Monitor::_safepoint_check_always); // used for JVM management
+ def(JvmtiThreadState_lock , PaddedMutex , nonleaf+2, false, _safepoint_check_always); // Used by JvmtiThreadState/JvmtiEventController
+ def(Management_lock , PaddedMutex , nonleaf+2, false, _safepoint_check_always); // used for JVM management
- def(Compile_lock , PaddedMutex , nonleaf+3, true, Monitor::_safepoint_check_always);
- def(MethodData_lock , PaddedMutex , nonleaf+3, false, Monitor::_safepoint_check_always);
- def(TouchedMethodLog_lock , PaddedMutex , nonleaf+3, false, Monitor::_safepoint_check_always);
+ def(Compile_lock , PaddedMutex , nonleaf+3, true, _safepoint_check_always);
+ def(MethodData_lock , PaddedMutex , nonleaf+3, false, _safepoint_check_always);
+ def(TouchedMethodLog_lock , PaddedMutex , nonleaf+3, false, _safepoint_check_always);
- def(MethodCompileQueue_lock , PaddedMonitor, nonleaf+4, false, Monitor::_safepoint_check_always);
- def(Debug2_lock , PaddedMutex , nonleaf+4, true, Monitor::_safepoint_check_never);
- def(Debug3_lock , PaddedMutex , nonleaf+4, true, Monitor::_safepoint_check_never);
- def(CompileThread_lock , PaddedMonitor, nonleaf+5, false, Monitor::_safepoint_check_always);
- def(PeriodicTask_lock , PaddedMonitor, nonleaf+5, true, Monitor::_safepoint_check_always);
- def(RedefineClasses_lock , PaddedMonitor, nonleaf+5, true, Monitor::_safepoint_check_always);
+ def(MethodCompileQueue_lock , PaddedMonitor, nonleaf+4, false, _safepoint_check_always);
+ def(Debug2_lock , PaddedMutex , nonleaf+4, true, _safepoint_check_never);
+ def(Debug3_lock , PaddedMutex , nonleaf+4, true, _safepoint_check_never);
+ def(CompileThread_lock , PaddedMonitor, nonleaf+5, false, _safepoint_check_always);
+ def(PeriodicTask_lock , PaddedMonitor, nonleaf+5, true, _safepoint_check_always);
+ def(RedefineClasses_lock , PaddedMonitor, nonleaf+5, true, _safepoint_check_always);
if (WhiteBoxAPI) {
- def(Compilation_lock , PaddedMonitor, leaf, false, Monitor::_safepoint_check_never);
+ def(Compilation_lock , PaddedMonitor, leaf, false, _safepoint_check_never);
}
#if INCLUDE_JFR
- def(JfrMsg_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_always);
- def(JfrBuffer_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never);
- def(JfrStream_lock , PaddedMutex , leaf+1, true, Monitor::_safepoint_check_never); // ensure to rank lower than 'safepoint'
- def(JfrStacktrace_lock , PaddedMutex , special, true, Monitor::_safepoint_check_never);
- def(JfrThreadSampler_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_never);
+ def(JfrMsg_lock , PaddedMonitor, leaf, true, _safepoint_check_always);
+ def(JfrBuffer_lock , PaddedMutex , leaf, true, _safepoint_check_never);
+ def(JfrStream_lock , PaddedMutex , leaf+1, true, _safepoint_check_never); // ensure to rank lower than 'safepoint'
+ def(JfrStacktrace_lock , PaddedMutex , special, true, _safepoint_check_never);
+ def(JfrThreadSampler_lock , PaddedMonitor, leaf, true, _safepoint_check_never);
#endif
#ifndef SUPPORTS_NATIVE_CX8
- def(UnsafeJlong_lock , PaddedMutex , special, false, Monitor::_safepoint_check_never);
+ def(UnsafeJlong_lock , PaddedMutex , special, false, _safepoint_check_never);
#endif
- def(CodeHeapStateAnalytics_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never);
- def(NMethodSweeperStats_lock , PaddedMutex , special, true, Monitor::_safepoint_check_never);
- def(ThreadsSMRDelete_lock , PaddedMonitor, special, true, Monitor::_safepoint_check_never);
- def(ThreadIdTableCreate_lock , PaddedMutex , leaf, false, Monitor::_safepoint_check_always);
- def(SharedDecoder_lock , PaddedMutex , native, false, Monitor::_safepoint_check_never);
- def(DCmdFactory_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never);
+ def(CodeHeapStateAnalytics_lock , PaddedMutex , leaf, true, _safepoint_check_never);
+ def(NMethodSweeperStats_lock , PaddedMutex , special, true, _safepoint_check_never);
+ def(ThreadsSMRDelete_lock , PaddedMonitor, special, true, _safepoint_check_never);
+ def(ThreadIdTableCreate_lock , PaddedMutex , leaf, false, _safepoint_check_always);
+ def(SharedDecoder_lock , PaddedMutex , native, false, _safepoint_check_never);
+ def(DCmdFactory_lock , PaddedMutex , leaf, true, _safepoint_check_never);
#if INCLUDE_NMT
- def(NMTQuery_lock , PaddedMutex , max_nonleaf, false, Monitor::_safepoint_check_always);
+ def(NMTQuery_lock , PaddedMutex , max_nonleaf, false, _safepoint_check_always);
#endif
#if INCLUDE_CDS
#if INCLUDE_JVMTI
- def(CDSClassFileStream_lock , PaddedMutex , max_nonleaf, false, Monitor::_safepoint_check_always);
+ def(CDSClassFileStream_lock , PaddedMutex , max_nonleaf, false, _safepoint_check_always);
#endif
#if INCLUDE_JVMCI
- def(JVMCI_lock , PaddedMonitor, nonleaf+2, true, Monitor::_safepoint_check_always);
+ def(JVMCI_lock , PaddedMonitor, nonleaf+2, true, _safepoint_check_always);
#endif
- def(DumpTimeTable_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never);
+ def(DumpTimeTable_lock , PaddedMutex , leaf, true, _safepoint_check_never);
#endif // INCLUDE_CDS
}
--- a/src/hotspot/share/runtime/rframe.cpp Fri Sep 27 13:32:52 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "code/codeCache.hpp"
-#include "interpreter/interpreter.hpp"
-#include "oops/method.inline.hpp"
-#include "oops/oop.inline.hpp"
-#include "oops/symbol.hpp"
-#include "runtime/frame.inline.hpp"
-#include "runtime/rframe.hpp"
-#include "runtime/vframe.hpp"
-#include "runtime/vframe_hp.hpp"
-
-
-static RFrame*const noCaller = (RFrame*) 0x1; // no caller (i.e., initial frame)
-static RFrame*const noCallerYet = (RFrame*) 0x0; // caller not yet computed
-
-RFrame::RFrame(frame fr, JavaThread* thread, RFrame*const callee) :
- _fr(fr), _thread(thread), _callee(callee), _num(callee ? callee->num() + 1 : 0) {
- _caller = (RFrame*)noCallerYet;
- _invocations = 0;
- _distance = 0;
-}
-
-void RFrame::set_distance(int d) {
- assert(is_compiled() || d >= 0, "should be positive");
- _distance = d;
-}
-
-InterpretedRFrame::InterpretedRFrame(frame fr, JavaThread* thread, RFrame*const callee)
-: RFrame(fr, thread, callee) {
- RegisterMap map(thread, false);
- _vf = javaVFrame::cast(vframe::new_vframe(&_fr, &map, thread));
- _method = _vf->method();
- assert( _vf->is_interpreted_frame(), "must be interpreted");
- init();
-}
-
-InterpretedRFrame::InterpretedRFrame(frame fr, JavaThread* thread, Method* m)
-: RFrame(fr, thread, NULL) {
- RegisterMap map(thread, false);
- _vf = javaVFrame::cast(vframe::new_vframe(&_fr, &map, thread));
- _method = m;
-
- assert( _vf->is_interpreted_frame(), "must be interpreted");
- init();
-}
-
-CompiledRFrame::CompiledRFrame(frame fr, JavaThread* thread, RFrame*const callee)
-: RFrame(fr, thread, callee) {
- init();
-}
-
-CompiledRFrame::CompiledRFrame(frame fr, JavaThread* thread)
-: RFrame(fr, thread, NULL) {
- init();
-}
-
-DeoptimizedRFrame::DeoptimizedRFrame(frame fr, JavaThread* thread, RFrame*const callee)
-: InterpretedRFrame(fr, thread, callee) {}
-
-RFrame* RFrame::new_RFrame(frame fr, JavaThread* thread, RFrame*const callee) {
- RFrame* rf = NULL;
- int dist = callee ? callee->distance() : -1;
- if (fr.is_interpreted_frame()) {
- rf = new InterpretedRFrame(fr, thread, callee);
- dist++;
- } else if (fr.is_compiled_frame()) {
- // Even deopted frames look compiled because the deopt
- // is invisible until it happens.
- rf = new CompiledRFrame(fr, thread, callee);
- } else {
- assert(false, "Unhandled frame type");
- }
- if (rf != NULL) {
- rf->set_distance(dist);
- rf->init();
- }
- return rf;
-}
-
-RFrame* RFrame::caller() {
- if (_caller != noCallerYet) return (_caller == noCaller) ? NULL : _caller; // already computed caller
-
- // caller not yet computed; do it now
- if (_fr.is_first_java_frame()) {
- _caller = (RFrame*)noCaller;
- return NULL;
- }
-
- RegisterMap map(_thread, false);
- frame sender = _fr.real_sender(&map);
- if (sender.is_java_frame()) {
- _caller = new_RFrame(sender, thread(), this);
- return _caller;
- }
-
- // Real caller is not java related
- _caller = (RFrame*)noCaller;
- return NULL;
-}
-
-int InterpretedRFrame::cost() const {
- return _method->code_size(); // fix this
- //return _method->estimated_inline_cost(_receiverKlass);
-}
-
-int CompiledRFrame::cost() const {
- CompiledMethod* nm = top_method()->code();
- if (nm != NULL) {
- return nm->insts_size();
- } else {
- return top_method()->code_size();
- }
-}
-
-void CompiledRFrame::init() {
- RegisterMap map(thread(), false);
- vframe* vf = vframe::new_vframe(&_fr, &map, thread());
- assert(vf->is_compiled_frame(), "must be compiled");
- _nm = compiledVFrame::cast(vf)->code()->as_nmethod();
- vf = vf->top();
- _vf = javaVFrame::cast(vf);
- _method = CodeCache::find_nmethod(_fr.pc())->method();
- assert(_method, "should have found a method");
-#ifndef PRODUCT
- _invocations = _method->compiled_invocation_count();
-#endif
-}
-
-void InterpretedRFrame::init() {
- _invocations = _method->invocation_count() + _method->backedge_count();
-}
-
-void RFrame::print(const char* kind) {
-#ifndef PRODUCT
-#if COMPILER2_OR_JVMCI
- int cnt = top_method()->interpreter_invocation_count();
-#else
- int cnt = top_method()->invocation_count();
-#endif
- tty->print("%3d %s ", _num, is_interpreted() ? "I" : "C");
- top_method()->print_short_name(tty);
- tty->print_cr(": inv=%5d(%d) cst=%4d", _invocations, cnt, cost());
-#endif
-}
-
-void CompiledRFrame::print() {
- RFrame::print("comp");
-}
-
-void InterpretedRFrame::print() {
- RFrame::print("int.");
-}
-
-void DeoptimizedRFrame::print() {
- RFrame::print("deopt.");
-}
--- a/src/hotspot/share/runtime/rframe.hpp Fri Sep 27 13:32:52 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_RUNTIME_RFRAME_HPP
-#define SHARE_RUNTIME_RFRAME_HPP
-
-#include "memory/allocation.hpp"
-#include "runtime/frame.hpp"
-
-// rframes ("recompiler frames") decorate stack frames with some extra information
-// needed by the recompiler. The recompiler views the stack (at the time of recompilation)
-// as a list of rframes.
-
-class RFrame : public ResourceObj {
- protected:
- const frame _fr; // my frame
- JavaThread* const _thread; // thread where frame resides.
- RFrame* _caller; // caller / callee rframes (or NULL)
- RFrame*const _callee;
- const int _num; // stack frame number (0 = most recent)
- int _invocations; // current invocation estimate (for this frame)
- // (i.e., how often was this frame called)
- int _distance; // recompilation search "distance" (measured in # of interpreted frames)
-
- RFrame(frame fr, JavaThread* thread, RFrame*const callee);
- virtual void init() = 0; // compute invocations, loopDepth, etc.
- void print(const char* name);
-
- public:
-
- static RFrame* new_RFrame(frame fr, JavaThread* thread, RFrame*const callee);
-
- virtual bool is_interpreted() const { return false; }
- virtual bool is_compiled() const { return false; }
- int distance() const { return _distance; }
- void set_distance(int d);
- int invocations() const { return _invocations; }
- int num() const { return _num; }
- frame fr() const { return _fr; }
- JavaThread* thread() const { return _thread; }
- virtual int cost() const = 0; // estimated inlining cost (size)
- virtual Method* top_method() const = 0;
- virtual javaVFrame* top_vframe() const = 0;
- virtual nmethod* nm() const { ShouldNotCallThis(); return NULL; }
-
- RFrame* caller();
- RFrame* callee() const { return _callee; }
- RFrame* parent() const; // rframe containing lexical scope (if any)
- virtual void print() = 0;
-
- static int computeSends(Method* m);
- static int computeSends(nmethod* nm);
- static int computeCumulSends(Method* m);
- static int computeCumulSends(nmethod* nm);
-};
-
-class CompiledRFrame : public RFrame { // frame containing a compiled method
- protected:
- nmethod* _nm;
- javaVFrame* _vf; // top vframe; may be NULL (for most recent frame)
- Method* _method; // top method
-
- CompiledRFrame(frame fr, JavaThread* thread, RFrame*const callee);
- void init();
- friend class RFrame;
-
- public:
- CompiledRFrame(frame fr, JavaThread* thread); // for nmethod triggering its counter (callee == NULL)
- bool is_compiled() const { return true; }
- Method* top_method() const { return _method; }
- javaVFrame* top_vframe() const { return _vf; }
- nmethod* nm() const { return _nm; }
- int cost() const;
- void print();
-};
-
-class InterpretedRFrame : public RFrame { // interpreter frame
- protected:
- javaVFrame* _vf; // may be NULL (for most recent frame)
- Method* _method;
-
- InterpretedRFrame(frame fr, JavaThread* thread, RFrame*const callee);
- void init();
- friend class RFrame;
-
- public:
- InterpretedRFrame(frame fr, JavaThread* thread, Method* m); // constructor for method triggering its invocation counter
- bool is_interpreted() const { return true; }
- Method* top_method() const { return _method; }
- javaVFrame* top_vframe() const { return _vf; }
- int cost() const;
- void print();
-};
-
-// treat deoptimized frames as interpreted
-class DeoptimizedRFrame : public InterpretedRFrame {
- protected:
- DeoptimizedRFrame(frame fr, JavaThread* thread, RFrame*const callee);
- friend class RFrame;
- public:
- void print();
-};
-
-#endif // SHARE_RUNTIME_RFRAME_HPP
--- a/src/hotspot/share/runtime/sharedRuntime.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -1269,6 +1269,7 @@
// will be supported.
if (!callee_method->is_old() &&
(callee == NULL || (callee->is_in_use() && callee_method->code() == callee))) {
+ NoSafepointVerifier nsv;
#ifdef ASSERT
// We must not try to patch to jump to an already unloaded method.
if (dest_entry_point != 0) {
--- a/src/hotspot/share/services/management.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/services/management.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -2068,6 +2068,31 @@
}
#endif // INCLUDE_MANAGEMENT
+// Gets the amount of memory allocated on the Java heap for a single thread.
+// Returns -1 if the thread does not exist or has terminated.
+JVM_ENTRY(jlong, jmm_GetOneThreadAllocatedMemory(JNIEnv *env, jlong thread_id))
+ if (thread_id < 0) {
+ THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
+ "Invalid thread ID", -1);
+ }
+
+ if (thread_id == 0) {
+ // current thread
+ if (THREAD->is_Java_thread()) {
+ return ((JavaThread*)THREAD)->cooked_allocated_bytes();
+ }
+ return -1;
+ }
+
+ ThreadsListHandle tlh;
+ JavaThread* java_thread = tlh.list()->find_JavaThread_from_java_tid(thread_id);
+
+ if (java_thread != NULL) {
+ return java_thread->cooked_allocated_bytes();
+ }
+ return -1;
+JVM_END
+
// Gets an array containing the amount of memory allocated on the Java
// heap for a set of threads (in bytes). Each element of the array is
// the amount of memory allocated for the thread ID specified in the
@@ -2192,6 +2217,7 @@
jmm_GetMemoryManagers,
jmm_GetMemoryPoolUsage,
jmm_GetPeakMemoryPoolUsage,
+ jmm_GetOneThreadAllocatedMemory,
jmm_GetThreadAllocatedMemory,
jmm_GetMemoryUsage,
jmm_GetLongAttribute,
--- a/src/hotspot/share/services/memoryManager.cpp Fri Sep 27 13:32:52 2019 +0200
+++ b/src/hotspot/share/services/memoryManager.cpp Sun Sep 29 13:59:54 2019 +0200
@@ -178,7 +178,7 @@
_num_collections = 0;
_last_gc_stat = NULL;
_last_gc_lock = new Mutex(Mutex::leaf, "_last_gc_lock", true,
- Monitor::_safepoint_check_never);
+ Mutex::_safepoint_check_never);
_current_gc_stat = NULL;
_num_gc_threads = 1;
_notification_enabled = false;
--- a/src/java.base/share/classes/java/io/FilePermission.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/java.base/share/classes/java/io/FilePermission.java Sun Sep 29 13:59:54 2019 +0200
@@ -1196,7 +1196,7 @@
if ((effective & desired) == desired) {
return true;
}
- needed = (desired ^ effective);
+ needed = (desired & ~effective);
}
}
return false;
--- a/src/java.base/share/classes/java/net/SocketPermission.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/java.base/share/classes/java/net/SocketPermission.java Sun Sep 29 13:59:54 2019 +0200
@@ -1433,7 +1433,7 @@
if ((effective & desired) == desired) {
return true;
}
- needed = (desired ^ effective);
+ needed = (desired & ~effective);
}
}
return false;
--- a/src/java.base/share/classes/java/time/Ser.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/java.base/share/classes/java/time/Ser.java Sun Sep 29 13:59:54 2019 +0200
@@ -61,6 +61,7 @@
import java.io.InvalidClassException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.io.Serializable;
import java.io.StreamCorruptedException;
/**
@@ -112,7 +113,7 @@
/** The type being serialized. */
private byte type;
/** The object being serialized. */
- private Object object;
+ private Serializable object;
/**
* Constructor for deserialization.
@@ -126,7 +127,7 @@
* @param type the type
* @param object the object
*/
- Ser(byte type, Object object) {
+ Ser(byte type, Serializable object) {
this.type = type;
this.object = object;
}
@@ -224,20 +225,35 @@
* {@code Ser} object.
*
* <ul>
- * <li><a href="{@docRoot}/serialized-form.html#java.time.Duration">Duration</a> - {@code Duration.ofSeconds(seconds, nanos);}
- * <li><a href="{@docRoot}/serialized-form.html#java.time.Instant">Instant</a> - {@code Instant.ofEpochSecond(seconds, nanos);}
- * <li><a href="{@docRoot}/serialized-form.html#java.time.LocalDate">LocalDate</a> - {@code LocalDate.of(year, month, day);}
- * <li><a href="{@docRoot}/serialized-form.html#java.time.LocalDateTime">LocalDateTime</a> - {@code LocalDateTime.of(date, time);}
- * <li><a href="{@docRoot}/serialized-form.html#java.time.LocalTime">LocalTime</a> - {@code LocalTime.of(hour, minute, second, nano);}
- * <li><a href="{@docRoot}/serialized-form.html#java.time.MonthDay">MonthDay</a> - {@code MonthDay.of(month, day);}
- * <li><a href="{@docRoot}/serialized-form.html#java.time.OffsetTime">OffsetTime</a> - {@code OffsetTime.of(time, offset);}
- * <li><a href="{@docRoot}/serialized-form.html#java.time.OffsetDateTime">OffsetDateTime</a> - {@code OffsetDateTime.of(dateTime, offset);}
- * <li><a href="{@docRoot}/serialized-form.html#java.time.Period">Period</a> - {@code Period.of(years, months, days);}
- * <li><a href="{@docRoot}/serialized-form.html#java.time.Year">Year</a> - {@code Year.of(year);}
- * <li><a href="{@docRoot}/serialized-form.html#java.time.YearMonth">YearMonth</a> - {@code YearMonth.of(year, month);}
- * <li><a href="{@docRoot}/serialized-form.html#java.time.ZonedDateTime">ZonedDateTime</a> - {@code ZonedDateTime.ofLenient(dateTime, offset, zone);}
- * <li><a href="{@docRoot}/serialized-form.html#java.time.ZoneId">ZoneId</a> - {@code ZoneId.of(id);}
- * <li><a href="{@docRoot}/serialized-form.html#java.time.ZoneOffset">ZoneOffset</a> - {@code (offsetByte == 127 ? ZoneOffset.ofTotalSeconds(in.readInt()) : ZoneOffset.ofTotalSeconds(offsetByte * 900));}
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.Duration">Duration</a> -
+ * {@code Duration.ofSeconds(seconds, nanos);}
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.Instant">Instant</a> -
+ * {@code Instant.ofEpochSecond(seconds, nanos);}
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.LocalDate">LocalDate</a> -
+ * {@code LocalDate.of(year, month, day);}
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.LocalDateTime">LocalDateTime</a> -
+ * {@code LocalDateTime.of(date, time);}
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.LocalTime">LocalTime</a> -
+ * {@code LocalTime.of(hour, minute, second, nano);}
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.MonthDay">MonthDay</a> -
+ * {@code MonthDay.of(month, day);}
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.OffsetTime">OffsetTime</a> -
+ * {@code OffsetTime.of(time, offset);}
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.OffsetDateTime">OffsetDateTime</a> -
+ * {@code OffsetDateTime.of(dateTime, offset);}
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.Period">Period</a> -
+ * {@code Period.of(years, months, days);}
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.Year">Year</a> -
+ * {@code Year.of(year);}
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.YearMonth">YearMonth</a> -
+ * {@code YearMonth.of(year, month);}
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.ZonedDateTime">ZonedDateTime</a> -
+ * {@code ZonedDateTime.ofLenient(dateTime, offset, zone);}
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.ZoneId">ZoneId</a> -
+ * {@code ZoneId.of(id);}
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.ZoneOffset">ZoneOffset</a> -
+ * {@code (offsetByte == 127 ? ZoneOffset.ofTotalSeconds(in.readInt()) :
+ * ZoneOffset.ofTotalSeconds(offsetByte * 900));}
* </ul>
*
* @param in the data to read, not null
@@ -247,12 +263,13 @@
object = readInternal(type, in);
}
- static Object read(ObjectInput in) throws IOException, ClassNotFoundException {
+ static Serializable read(ObjectInput in) throws IOException, ClassNotFoundException {
byte type = in.readByte();
return readInternal(type, in);
}
- private static Object readInternal(byte type, ObjectInput in) throws IOException, ClassNotFoundException {
+ private static Serializable readInternal(byte type, ObjectInput in)
+ throws IOException, ClassNotFoundException {
switch (type) {
case DURATION_TYPE: return Duration.readExternal(in);
case INSTANT_TYPE: return Instant.readExternal(in);
--- a/src/java.base/share/classes/java/time/chrono/AbstractChronology.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/java.base/share/classes/java/time/chrono/AbstractChronology.java Sun Sep 29 13:59:54 2019 +0200
@@ -731,7 +731,7 @@
*/
@java.io.Serial
Object writeReplace() {
- return new Ser(Ser.CHRONO_TYPE, this);
+ return new Ser(Ser.CHRONO_TYPE, (Serializable)this);
}
/**
--- a/src/java.base/share/classes/java/time/chrono/Ser.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/java.base/share/classes/java/time/chrono/Ser.java Sun Sep 29 13:59:54 2019 +0200
@@ -61,6 +61,7 @@
import java.io.InvalidClassException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.io.Serializable;
import java.io.StreamCorruptedException;
import java.time.LocalDate;
import java.time.LocalDateTime;
@@ -110,7 +111,7 @@
/** The type being serialized. */
private byte type;
/** The object being serialized. */
- private Object object;
+ private Serializable object;
/**
* Constructor for deserialization.
@@ -124,7 +125,7 @@
* @param type the type
* @param object the object
*/
- Ser(byte type, Object object) {
+ Ser(byte type, Serializable object) {
this.type = type;
this.object = object;
}
@@ -203,18 +204,30 @@
* {@code Ser} object.
*
* <ul>
- * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.HijrahChronology">HijrahChronology</a> - Chronology.of(id)
- * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.IsoChronology">IsoChronology</a> - Chronology.of(id)
- * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.JapaneseChronology">JapaneseChronology</a> - Chronology.of(id)
- * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.MinguoChronology">MinguoChronology</a> - Chronology.of(id)
- * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.ThaiBuddhistChronology">ThaiBuddhistChronology</a> - Chronology.of(id)
- * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.ChronoLocalDateTimeImpl">ChronoLocalDateTime</a> - date.atTime(time)
- * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.ChronoZonedDateTimeImpl">ChronoZonedDateTime</a> - dateTime.atZone(offset).withZoneSameLocal(zone)
- * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.JapaneseDate">JapaneseDate</a> - JapaneseChronology.INSTANCE.date(year, month, dayOfMonth)
- * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.JapaneseEra">JapaneseEra</a> - JapaneseEra.of(eraValue)
- * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.HijrahDate">HijrahDate</a> - HijrahChronology chrono.date(year, month, dayOfMonth)
- * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.MinguoDate">MinguoDate</a> - MinguoChronology.INSTANCE.date(year, month, dayOfMonth)
- * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.ThaiBuddhistDate">ThaiBuddhistDate</a> - ThaiBuddhistChronology.INSTANCE.date(year, month, dayOfMonth)
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.HijrahChronology">HijrahChronology</a> -
+ * Chronology.of(id)
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.IsoChronology">IsoChronology</a> -
+ * Chronology.of(id)
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.JapaneseChronology">JapaneseChronology</a> -
+ * Chronology.of(id)
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.MinguoChronology">MinguoChronology</a> -
+ * Chronology.of(id)
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.ThaiBuddhistChronology">ThaiBuddhistChronology</a> -
+ * Chronology.of(id)
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.ChronoLocalDateTimeImpl">ChronoLocalDateTime</a> -
+ * date.atTime(time)
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.ChronoZonedDateTimeImpl">ChronoZonedDateTime</a> -
+ * dateTime.atZone(offset).withZoneSameLocal(zone)
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.JapaneseDate">JapaneseDate</a> -
+ * JapaneseChronology.INSTANCE.date(year, month, dayOfMonth)
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.JapaneseEra">JapaneseEra</a> -
+ * JapaneseEra.of(eraValue)
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.HijrahDate">HijrahDate</a> -
+ * HijrahChronology chrono.date(year, month, dayOfMonth)
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.MinguoDate">MinguoDate</a> -
+ * MinguoChronology.INSTANCE.date(year, month, dayOfMonth)
+ * <li><a href="{@docRoot}/serialized-form.html#java.time.chrono.ThaiBuddhistDate">ThaiBuddhistDate</a> -
+ * ThaiBuddhistChronology.INSTANCE.date(year, month, dayOfMonth)
* </ul>
*
* @param in the data stream to read from, not null
@@ -225,16 +238,17 @@
object = readInternal(type, in);
}
- static Object read(ObjectInput in) throws IOException, ClassNotFoundException {
+ static Serializable read(ObjectInput in) throws IOException, ClassNotFoundException {
byte type = in.readByte();
return readInternal(type, in);
}
- private static Object readInternal(byte type, ObjectInput in) throws IOException, ClassNotFoundException {
+ private static Serializable readInternal(byte type, ObjectInput in)
+ throws IOException, ClassNotFoundException {
switch (type) {
- case CHRONO_TYPE: return AbstractChronology.readExternal(in);
- case CHRONO_LOCAL_DATE_TIME_TYPE: return ChronoLocalDateTimeImpl.readExternal(in);
- case CHRONO_ZONE_DATE_TIME_TYPE: return ChronoZonedDateTimeImpl.readExternal(in);
+ case CHRONO_TYPE: return (Serializable)AbstractChronology.readExternal(in);
+ case CHRONO_LOCAL_DATE_TIME_TYPE: return (Serializable)ChronoLocalDateTimeImpl.readExternal(in);
+ case CHRONO_ZONE_DATE_TIME_TYPE: return (Serializable)ChronoZonedDateTimeImpl.readExternal(in);
case JAPANESE_DATE_TYPE: return JapaneseDate.readExternal(in);
case JAPANESE_ERA_TYPE: return JapaneseEra.readExternal(in);
case HIJRAH_DATE_TYPE: return HijrahDate.readExternal(in);
--- a/src/java.base/share/classes/java/time/zone/Ser.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/java.base/share/classes/java/time/zone/Ser.java Sun Sep 29 13:59:54 2019 +0200
@@ -68,6 +68,7 @@
import java.io.InvalidClassException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.io.Serializable;
import java.io.StreamCorruptedException;
import java.time.ZoneOffset;
@@ -97,7 +98,7 @@
/** The type being serialized. */
private byte type;
/** The object being serialized. */
- private Object object;
+ private Serializable object;
/**
* Constructor for deserialization.
@@ -111,7 +112,7 @@
* @param type the type
* @param object the object
*/
- Ser(byte type, Object object) {
+ Ser(byte type, Serializable object) {
this.type = type;
this.object = object;
}
@@ -183,12 +184,13 @@
object = readInternal(type, in);
}
- static Object read(DataInput in) throws IOException, ClassNotFoundException {
+ static Serializable read(DataInput in) throws IOException, ClassNotFoundException {
byte type = in.readByte();
return readInternal(type, in);
}
- private static Object readInternal(byte type, DataInput in) throws IOException, ClassNotFoundException {
+ private static Serializable readInternal(byte type, DataInput in)
+ throws IOException, ClassNotFoundException {
switch (type) {
case ZRULES:
return ZoneRules.readExternal(in);
--- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Sun Sep 29 13:59:54 2019 +0200
@@ -130,7 +130,7 @@
}
public final boolean block() {
- while (!isReleasable()) LockSupport.park(this);
+ while (!isReleasable()) LockSupport.park();
return true;
}
}
--- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Sun Sep 29 13:59:54 2019 +0200
@@ -502,7 +502,7 @@
}
public final boolean block() {
- while (!isReleasable()) LockSupport.park(this);
+ while (!isReleasable()) LockSupport.park();
return true;
}
}
--- a/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c Fri Sep 27 13:32:52 2019 +0200
+++ b/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c Sun Sep 29 13:59:54 2019 +0200
@@ -166,6 +166,10 @@
int id = -1;
VisualID defaultVisual = XVisualIDFromVisual(DefaultVisual(awt_display, vinfo->screen));
defaultConfig = ZALLOC(_AwtGraphicsConfigData);
+ if (defaultConfig == NULL) {
+ XFree(visualList);
+ return NULL;
+ }
for (i = 0; i < visualsMatched; i++) {
memcpy(&defaultConfig->awt_visInfo, &visualList[i], sizeof(XVisualInfo));
defaultConfig->awt_depth = visualList[i].depth;
@@ -447,8 +451,12 @@
} else {
ind = nConfig++;
}
- graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
- graphicsConfigs [ind]->awt_depth = pVITrue [i].depth;
+ graphicsConfigs[ind] = ZALLOC (_AwtGraphicsConfigData);
+ if (graphicsConfigs[ind] == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "allocation in getAllConfigs failed");
+ goto cleanup;
+ }
+ graphicsConfigs[ind]->awt_depth = pVITrue [i].depth;
memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVITrue [i],
sizeof (XVisualInfo));
if (xrenderFindVisualFormat != NULL) {
@@ -482,8 +490,12 @@
} else {
ind = nConfig++;
}
- graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
- graphicsConfigs [ind]->awt_depth = pVI8p [i].depth;
+ graphicsConfigs[ind] = ZALLOC (_AwtGraphicsConfigData);
+ if (graphicsConfigs[ind] == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "allocation in getAllConfigs failed");
+ goto cleanup;
+ }
+ graphicsConfigs[ind]->awt_depth = pVI8p [i].depth;
memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8p [i],
sizeof (XVisualInfo));
}
@@ -495,8 +507,12 @@
} else {
ind = nConfig++;
}
- graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
- graphicsConfigs [ind]->awt_depth = pVI12p [i].depth;
+ graphicsConfigs[ind] = ZALLOC (_AwtGraphicsConfigData);
+ if (graphicsConfigs[ind] == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "allocation in getAllConfigs failed");
+ goto cleanup;
+ }
+ graphicsConfigs[ind]->awt_depth = pVI12p [i].depth;
memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI12p [i],
sizeof (XVisualInfo));
}
@@ -508,8 +524,12 @@
} else {
ind = nConfig++;
}
- graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
- graphicsConfigs [ind]->awt_depth = pVI8s [i].depth;
+ graphicsConfigs[ind] = ZALLOC (_AwtGraphicsConfigData);
+ if (graphicsConfigs[ind] == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "allocation in getAllConfigs failed");
+ goto cleanup;
+ }
+ graphicsConfigs[ind]->awt_depth = pVI8s [i].depth;
memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8s [i],
sizeof (XVisualInfo));
}
@@ -521,8 +541,12 @@
} else {
ind = nConfig++;
}
- graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
- graphicsConfigs [ind]->awt_depth = pVI8gs [i].depth;
+ graphicsConfigs[ind] = ZALLOC (_AwtGraphicsConfigData);
+ if (graphicsConfigs[ind] == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "allocation in getAllConfigs failed");
+ goto cleanup;
+ }
+ graphicsConfigs[ind]->awt_depth = pVI8gs [i].depth;
memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8gs [i],
sizeof (XVisualInfo));
}
@@ -534,8 +558,12 @@
} else {
ind = nConfig++;
}
- graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
- graphicsConfigs [ind]->awt_depth = pVI8sg [i].depth;
+ graphicsConfigs[ind] = ZALLOC (_AwtGraphicsConfigData);
+ if (graphicsConfigs[ind] == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "allocation in getAllConfigs failed");
+ goto cleanup;
+ }
+ graphicsConfigs[ind]->awt_depth = pVI8sg [i].depth;
memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI8sg [i],
sizeof (XVisualInfo));
}
@@ -547,12 +575,20 @@
} else {
ind = nConfig++;
}
- graphicsConfigs [ind] = ZALLOC (_AwtGraphicsConfigData);
- graphicsConfigs [ind]->awt_depth = pVI1sg [i].depth;
+ graphicsConfigs[ind] = ZALLOC (_AwtGraphicsConfigData);
+ if (graphicsConfigs[ind] == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "allocation in getAllConfigs failed");
+ goto cleanup;
+ }
+ graphicsConfigs[ind]->awt_depth = pVI1sg [i].depth;
memcpy (&graphicsConfigs [ind]->awt_visInfo, &pVI1sg [i],
sizeof (XVisualInfo));
}
+ screenDataPtr->numConfigs = nConfig;
+ screenDataPtr->configs = graphicsConfigs;
+
+cleanup:
if (n8p != 0)
XFree (pVI8p);
if (n12p != 0)
@@ -566,9 +602,6 @@
if (n1sg != 0)
XFree (pVI1sg);
- screenDataPtr->numConfigs = nConfig;
- screenDataPtr->configs = graphicsConfigs;
-
AWT_UNLOCK ();
}
--- a/src/java.management/share/classes/java/lang/management/ThreadMXBean.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/java.management/share/classes/java/lang/management/ThreadMXBean.java Sun Sep 29 13:59:54 2019 +0200
@@ -160,7 +160,7 @@
*
* @return an array of {@code long}, each is a thread ID.
*
- * @throws java.lang.SecurityException if a security manager
+ * @throws SecurityException if a security manager
* exists and the caller does not have
* ManagementPermission("monitor").
*/
@@ -199,7 +199,7 @@
* it does not exist.
*
* @throws IllegalArgumentException if {@code id <= 0}.
- * @throws java.lang.SecurityException if a security manager
+ * @throws SecurityException if a security manager
* exists and the caller does not have
* ManagementPermission("monitor").
*/
@@ -237,7 +237,7 @@
*
* @throws IllegalArgumentException if any element in the input array
* {@code ids} is {@code <= 0}.
- * @throws java.lang.SecurityException if a security manager
+ * @throws SecurityException if a security manager
* exists and the caller does not have
* ManagementPermission("monitor").
*/
@@ -284,7 +284,7 @@
*
* @throws IllegalArgumentException if {@code id <= 0}.
* @throws IllegalArgumentException if {@code maxDepth is negative}.
- * @throws java.lang.SecurityException if a security manager
+ * @throws SecurityException if a security manager
* exists and the caller does not have
* ManagementPermission("monitor").
*
@@ -337,7 +337,7 @@
* @throws IllegalArgumentException if {@code maxDepth is negative}.
* @throws IllegalArgumentException if any element in the input array
* {@code ids} is {@code <= 0}.
- * @throws java.lang.SecurityException if a security manager
+ * @throws SecurityException if a security manager
* exists and the caller does not have
* ManagementPermission("monitor").
*
@@ -360,7 +360,7 @@
* @return {@code true} if thread contention monitoring is enabled;
* {@code false} otherwise.
*
- * @throws java.lang.UnsupportedOperationException if the Java virtual
+ * @throws UnsupportedOperationException if the Java virtual
* machine does not support thread contention monitoring.
*
* @see #isThreadContentionMonitoringSupported
@@ -374,10 +374,10 @@
* @param enable {@code true} to enable;
* {@code false} to disable.
*
- * @throws java.lang.UnsupportedOperationException if the Java
+ * @throws UnsupportedOperationException if the Java
* virtual machine does not support thread contention monitoring.
*
- * @throws java.lang.SecurityException if a security manager
+ * @throws SecurityException if a security manager
* exists and the caller does not have
* ManagementPermission("control").
*
@@ -394,7 +394,7 @@
* the current thread has executed in user mode or system mode.
*
* <p>
- * This is a convenient method for local management use and is
+ * This is a convenience method for local management use and is
* equivalent to calling:
* <blockquote><pre>
* {@link #getThreadCpuTime getThreadCpuTime}(Thread.currentThread().getId());
@@ -403,7 +403,7 @@
* @return the total CPU time for the current thread if CPU time
* measurement is enabled; {@code -1} otherwise.
*
- * @throws java.lang.UnsupportedOperationException if the Java
+ * @throws UnsupportedOperationException if the Java
* virtual machine does not support CPU time measurement for
* the current thread.
*
@@ -421,7 +421,7 @@
* not necessarily nanoseconds accuracy.
*
* <p>
- * This is a convenient method for local management use and is
+ * This is a convenience method for local management use and is
* equivalent to calling:
* <blockquote><pre>
* {@link #getThreadUserTime getThreadUserTime}(Thread.currentThread().getId());
@@ -430,7 +430,7 @@
* @return the user-level CPU time for the current thread if CPU time
* measurement is enabled; {@code -1} otherwise.
*
- * @throws java.lang.UnsupportedOperationException if the Java
+ * @throws UnsupportedOperationException if the Java
* virtual machine does not support CPU time measurement for
* the current thread.
*
@@ -467,7 +467,7 @@
* {@code -1} otherwise.
*
* @throws IllegalArgumentException if {@code id <= 0}.
- * @throws java.lang.UnsupportedOperationException if the Java
+ * @throws UnsupportedOperationException if the Java
* virtual machine does not support CPU time measurement for
* other threads.
*
@@ -502,7 +502,7 @@
* {@code -1} otherwise.
*
* @throws IllegalArgumentException if {@code id <= 0}.
- * @throws java.lang.UnsupportedOperationException if the Java
+ * @throws UnsupportedOperationException if the Java
* virtual machine does not support CPU time measurement for
* other threads.
*
@@ -548,7 +548,7 @@
* @return {@code true} if thread CPU time measurement is enabled;
* {@code false} otherwise.
*
- * @throws java.lang.UnsupportedOperationException if the Java virtual
+ * @throws UnsupportedOperationException if the Java virtual
* machine does not support CPU time measurement for other threads
* nor for the current thread.
*
@@ -564,11 +564,11 @@
* @param enable {@code true} to enable;
* {@code false} to disable.
*
- * @throws java.lang.UnsupportedOperationException if the Java
+ * @throws UnsupportedOperationException if the Java
* virtual machine does not support CPU time measurement for
* any threads nor for the current thread.
*
- * @throws java.lang.SecurityException if a security manager
+ * @throws SecurityException if a security manager
* exists and the caller does not have
* ManagementPermission("control").
*
@@ -604,7 +604,7 @@
* @return an array of IDs of the threads that are monitor
* deadlocked, if any; {@code null} otherwise.
*
- * @throws java.lang.SecurityException if a security manager
+ * @throws SecurityException if a security manager
* exists and the caller does not have
* ManagementPermission("monitor").
*
@@ -616,7 +616,7 @@
* Resets the peak thread count to the current number of
* live threads.
*
- * @throws java.lang.SecurityException if a security manager
+ * @throws SecurityException if a security manager
* exists and the caller does not have
* ManagementPermission("control").
*
@@ -642,10 +642,10 @@
* deadlocked waiting for object monitors or ownable synchronizers, if any;
* {@code null} otherwise.
*
- * @throws java.lang.SecurityException if a security manager
+ * @throws SecurityException if a security manager
* exists and the caller does not have
* ManagementPermission("monitor").
- * @throws java.lang.UnsupportedOperationException if the Java virtual
+ * @throws UnsupportedOperationException if the Java virtual
* machine does not support monitoring of ownable synchronizer usage.
*
* @see #isSynchronizerUsageSupported
@@ -704,10 +704,10 @@
* information about a thread whose ID is in the corresponding
* element of the input array of IDs.
*
- * @throws java.lang.SecurityException if a security manager
+ * @throws SecurityException if a security manager
* exists and the caller does not have
* ManagementPermission("monitor").
- * @throws java.lang.UnsupportedOperationException
+ * @throws UnsupportedOperationException
* <ul>
* <li>if {@code lockedMonitors} is {@code true} but
* the Java virtual machine does not support monitoring
@@ -794,10 +794,10 @@
* element of the input array of IDs.
*
* @throws IllegalArgumentException if {@code maxDepth} is negative.
- * @throws java.lang.SecurityException if a security manager
+ * @throws SecurityException if a security manager
* exists and the caller does not have
* ManagementPermission("monitor").
- * @throws java.lang.UnsupportedOperationException
+ * @throws UnsupportedOperationException
* <ul>
* <li>if {@code lockedMonitors} is {@code true} but
* the Java virtual machine does not support monitoring
@@ -835,10 +835,10 @@
*
* @return an array of {@link ThreadInfo} for all live threads.
*
- * @throws java.lang.SecurityException if a security manager
+ * @throws SecurityException if a security manager
* exists and the caller does not have
* ManagementPermission("monitor").
- * @throws java.lang.UnsupportedOperationException
+ * @throws UnsupportedOperationException
* <ul>
* <li>if {@code lockedMonitors} is {@code true} but
* the Java virtual machine does not support monitoring
@@ -884,10 +884,10 @@
* @return an array of {@link ThreadInfo} for all live threads.
*
* @throws IllegalArgumentException if {@code maxDepth} is negative.
- * @throws java.lang.SecurityException if a security manager
+ * @throws SecurityException if a security manager
* exists and the caller does not have
* ManagementPermission("monitor").
- * @throws java.lang.UnsupportedOperationException
+ * @throws UnsupportedOperationException
* <ul>
* <li>if {@code lockedMonitors} is {@code true} but
* the Java virtual machine does not support monitoring
--- a/src/java.management/share/classes/sun/management/ThreadImpl.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/java.management/share/classes/sun/management/ThreadImpl.java Sun Sep 29 13:59:54 2019 +0200
@@ -29,6 +29,7 @@
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import javax.management.ObjectName;
+import java.util.Objects;
/**
* Implementation for java.lang.management.ThreadMXBean as well as providing the
@@ -112,11 +113,15 @@
return cpuTimeEnabled;
}
- protected boolean isThreadAllocatedMemoryEnabled() {
+ private void ensureThreadAllocatedMemorySupported() {
if (!isThreadAllocatedMemorySupported()) {
throw new UnsupportedOperationException(
- "Thread allocated memory measurement is not supported");
+ "Thread allocated memory measurement is not supported.");
}
+ }
+
+ protected boolean isThreadAllocatedMemoryEnabled() {
+ ensureThreadAllocatedMemorySupported();
return allocatedMemoryEnabled;
}
@@ -155,16 +160,18 @@
return getThreadInfo(ids, 0);
}
+ private void verifyThreadId(long id) {
+ if (id <= 0) {
+ throw new IllegalArgumentException(
+ "Invalid thread ID parameter: " + id);
+ }
+ }
+
private void verifyThreadIds(long[] ids) {
- if (ids == null) {
- throw new NullPointerException("Null ids parameter.");
- }
+ Objects.requireNonNull(ids);
for (int i = 0; i < ids.length; i++) {
- if (ids[i] <= 0) {
- throw new IllegalArgumentException(
- "Invalid thread ID parameter: " + ids[i]);
- }
+ verifyThreadId(ids[i]);
}
}
@@ -342,26 +349,41 @@
}
}
+ protected long getCurrentThreadAllocatedBytes() {
+ if (isThreadAllocatedMemoryEnabled()) {
+ return getThreadAllocatedMemory0(0);
+ }
+ return -1;
+ }
+
+ private boolean verifyThreadAllocatedMemory(long id) {
+ verifyThreadId(id);
+ return isThreadAllocatedMemoryEnabled();
+ }
+
protected long getThreadAllocatedBytes(long id) {
- long[] ids = new long[1];
- ids[0] = id;
- final long[] sizes = getThreadAllocatedBytes(ids);
- return sizes[0];
+ boolean verified = verifyThreadAllocatedMemory(id);
+
+ if (verified) {
+ return getThreadAllocatedMemory0(
+ Thread.currentThread().getId() == id ? 0 : id);
+ }
+ return -1;
}
private boolean verifyThreadAllocatedMemory(long[] ids) {
verifyThreadIds(ids);
-
- // check if Thread allocated memory measurement is supported.
- if (!isThreadAllocatedMemorySupported()) {
- throw new UnsupportedOperationException(
- "Thread allocated memory measurement is not supported.");
- }
-
return isThreadAllocatedMemoryEnabled();
}
protected long[] getThreadAllocatedBytes(long[] ids) {
+ Objects.requireNonNull(ids);
+
+ if (ids.length == 1) {
+ long size = getThreadAllocatedBytes(ids[0]);
+ return new long[] { size };
+ }
+
boolean verified = verifyThreadAllocatedMemory(ids);
long[] sizes = new long[ids.length];
@@ -374,10 +396,7 @@
}
protected void setThreadAllocatedMemoryEnabled(boolean enable) {
- if (!isThreadAllocatedMemorySupported()) {
- throw new UnsupportedOperationException(
- "Thread allocated memory measurement is not supported.");
- }
+ ensureThreadAllocatedMemorySupported();
Util.checkControlAccess();
synchronized (this) {
@@ -511,6 +530,7 @@
private static native void getThreadTotalCpuTime1(long[] ids, long[] result);
private static native long getThreadUserCpuTime0(long id);
private static native void getThreadUserCpuTime1(long[] ids, long[] result);
+ private static native long getThreadAllocatedMemory0(long id);
private static native void getThreadAllocatedMemory1(long[] ids, long[] result);
private static native void setThreadCpuTimeEnabled0(boolean enable);
private static native void setThreadAllocatedMemoryEnabled0(boolean enable);
--- a/src/java.management/share/native/libmanagement/ThreadImpl.c Fri Sep 27 13:32:52 2019 +0200
+++ b/src/java.management/share/native/libmanagement/ThreadImpl.c Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -94,6 +94,13 @@
JNI_FALSE /* user */);
}
+JNIEXPORT jlong JNICALL
+Java_sun_management_ThreadImpl_getThreadAllocatedMemory0
+ (JNIEnv *env, jclass cls, jlong tid)
+{
+ return jmm_interface->GetOneThreadAllocatedMemory(env, tid);
+}
+
JNIEXPORT void JNICALL
Java_sun_management_ThreadImpl_getThreadAllocatedMemory1
(JNIEnv *env, jclass cls, jlongArray ids, jlongArray sizeArray)
--- a/src/java.prefs/share/classes/java/util/prefs/NodeChangeEvent.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/java.prefs/share/classes/java/util/prefs/NodeChangeEvent.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -49,7 +49,7 @@
*
* @serial
*/
- private Preferences child;
+ private transient Preferences child;
/**
* Constructs a new {@code NodeChangeEvent} instance.
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSupport.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSupport.java Sun Sep 29 13:59:54 2019 +0200
@@ -59,7 +59,7 @@
try {
String name = path.toAbsolutePath().toString();
name = name.replace('\\', '/');
- return new URI("jar:file:///" + name + "!/");
+ return new URI("jar:file", null, "///" + name + "!/", null);
} catch (URISyntaxException e) {
throw new InternalError(e);
}
--- a/src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java Sun Sep 29 13:59:54 2019 +0200
@@ -112,7 +112,7 @@
}
final String code;
- final Object[] args;
+ final transient Object[] args;
}
/**
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Sun Sep 29 13:59:54 2019 +0200
@@ -2345,14 +2345,14 @@
public static class CompletionFailure extends RuntimeException {
private static final long serialVersionUID = 0;
- public final DeferredCompletionFailureHandler dcfh;
- public Symbol sym;
+ public final transient DeferredCompletionFailureHandler dcfh;
+ public transient Symbol sym;
/** A diagnostic object describing the failure
*/
- private JCDiagnostic diag;
+ private transient JCDiagnostic diag;
- private Supplier<JCDiagnostic> diagSupplier;
+ private transient Supplier<JCDiagnostic> diagSupplier;
public CompletionFailure(Symbol sym, Supplier<JCDiagnostic> diagSupplier, DeferredCompletionFailureHandler dcfh) {
this.dcfh = dcfh;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Sun Sep 29 13:59:54 2019 +0200
@@ -639,7 +639,7 @@
public static class FunctionDescriptorLookupError extends RuntimeException {
private static final long serialVersionUID = 0;
- JCDiagnostic diagnostic;
+ transient JCDiagnostic diagnostic;
FunctionDescriptorLookupError() {
this.diagnostic = null;
@@ -5002,7 +5002,7 @@
public static class InvalidSignatureException extends RuntimeException {
private static final long serialVersionUID = 0;
- private final Type type;
+ private final transient Type type;
InvalidSignatureException(Type type) {
this.type = type;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Sun Sep 29 13:59:54 2019 +0200
@@ -443,7 +443,7 @@
private static class BreakAttr extends RuntimeException {
static final long serialVersionUID = -6924771130405446405L;
- private Env<AttrContext> env;
+ private transient Env<AttrContext> env;
private BreakAttr(Env<AttrContext> env) {
this.env = env;
}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/CompileStates.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/CompileStates.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -77,7 +77,7 @@
private static final long serialVersionUID = 1812267524140424433L;
- protected Context context;
+ protected transient Context context;
public CompileStates(Context context) {
this.context = context;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java Sun Sep 29 13:59:54 2019 +0200
@@ -137,7 +137,7 @@
public static class InferenceException extends InapplicableMethodException {
private static final long serialVersionUID = 0;
- List<JCDiagnostic> messages = List.nil();
+ transient List<JCDiagnostic> messages = List.nil();
InferenceException() {
super(null);
@@ -1321,7 +1321,7 @@
public static class NodeNotFoundException extends RuntimeException {
private static final long serialVersionUID = 0;
- InferenceGraph graph;
+ transient InferenceGraph graph;
public NodeNotFoundException(InferenceGraph graph) {
this.graph = graph;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1387,7 +1387,7 @@
public static class InapplicableMethodException extends RuntimeException {
private static final long serialVersionUID = 0;
- JCDiagnostic diagnostic;
+ transient JCDiagnostic diagnostic;
InapplicableMethodException(JCDiagnostic diag) {
this.diagnostic = diag;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Sun Sep 29 13:59:54 2019 +0200
@@ -280,7 +280,7 @@
private static final long serialVersionUID = 0;
private boolean expandJarClassPaths = false;
- private final Set<Path> canonicalValues = new HashSet<>();
+ private final transient Set<Path> canonicalValues = new HashSet<>();
public SearchPath expandJarClassPaths(boolean x) {
expandJarClassPaths = x;
@@ -290,7 +290,7 @@
/**
* What to use when path element is the empty string
*/
- private Path emptyPathDefault = null;
+ private transient Path emptyPathDefault = null;
public SearchPath emptyPathDefault(Path x) {
emptyPathDefault = x;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Sun Sep 29 13:59:54 2019 +0200
@@ -264,7 +264,9 @@
module_prefix + "java.lang.annotation.Native",
module_prefix + "java.lang.annotation.Repeatable",
module_prefix + "java.lang.annotation.Retention",
- module_prefix + "java.lang.annotation.Target");
+ module_prefix + "java.lang.annotation.Target",
+
+ module_prefix + "java.io.Serial");
}
private void initProcessorLoader() {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/JMap.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/JMap.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -182,9 +182,8 @@
hgw.write(fileName);
System.out.println("heap written to " + fileName);
return true;
- } catch (IOException | RuntimeException exp) {
- System.err.println(exp.getMessage());
- return false;
+ } catch (IOException exp) {
+ throw new RuntimeException(exp);
}
}
@@ -199,8 +198,7 @@
System.out.println("heap written to " + fileName);
return true;
} catch (IOException exp) {
- System.err.println(exp.getMessage());
- return false;
+ throw new RuntimeException(exp);
}
}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/Tool.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/Tool.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -116,6 +116,8 @@
try {
returnStatus = start(args);
+ } catch (Throwable t) {
+ t.printStackTrace(System.err);
} finally {
stop();
}
--- a/src/jdk.management/share/classes/com/sun/management/ThreadMXBean.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/jdk.management/share/classes/com/sun/management/ThreadMXBean.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -61,7 +61,7 @@
* @throws NullPointerException if {@code ids} is {@code null}
* @throws IllegalArgumentException if any element in the input array
* {@code ids} is {@code <=} {@code 0}.
- * @throws java.lang.UnsupportedOperationException if the Java
+ * @throws UnsupportedOperationException if the Java
* virtual machine implementation does not support CPU time
* measurement.
*
@@ -95,7 +95,7 @@
* @throws NullPointerException if {@code ids} is {@code null}
* @throws IllegalArgumentException if any element in the input array
* {@code ids} is {@code <=} {@code 0}.
- * @throws java.lang.UnsupportedOperationException if the Java
+ * @throws UnsupportedOperationException if the Java
* virtual machine implementation does not support CPU time
* measurement.
*
@@ -109,13 +109,50 @@
/**
* Returns an approximation of the total amount of memory, in bytes,
- * allocated in heap memory for the thread of the specified ID.
+ * allocated in heap memory for the current thread.
+ * The returned value is an approximation because some Java virtual machine
+ * implementations may use object allocation mechanisms that result in a
+ * delay between the time an object is allocated and the time its size is
+ * recorded.
+ *
+ * <p>
+ * This is a convenience method for local management use and is
+ * equivalent to calling:
+ * <blockquote><pre>
+ * {@link #getThreadAllocatedBytes getThreadAllocatedBytes}(Thread.currentThread().getId());
+ * </pre></blockquote>
+ *
+ * @implSpec The default implementation throws
+ * {@code UnsupportedOperationException}.
+ *
+ * @return an approximation of the total memory allocated, in bytes, in
+ * heap memory for the current thread
+ * if thread memory allocation measurement is enabled;
+ * {@code -1} otherwise.
+ *
+ * @throws UnsupportedOperationException if the Java virtual
+ * machine implementation does not support thread memory allocation
+ * measurement.
+ *
+ * @see #isThreadAllocatedMemorySupported
+ * @see #isThreadAllocatedMemoryEnabled
+ * @see #setThreadAllocatedMemoryEnabled
+ *
+ * @since 14
+ */
+ public default long getCurrentThreadAllocatedBytes() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns an approximation of the total amount of memory, in bytes,
+ * allocated in heap memory for the thread with the specified ID.
* The returned value is an approximation because some Java virtual machine
* implementations may use object allocation mechanisms that result in a
* delay between the time an object is allocated and the time its size is
* recorded.
* <p>
- * If the thread of the specified ID is not alive or does not exist,
+ * If the thread with the specified ID is not alive or does not exist,
* this method returns {@code -1}. If thread memory allocation measurement
* is disabled, this method returns {@code -1}.
* A thread is alive if it has been started and has not yet died.
@@ -127,13 +164,13 @@
*
* @param id the thread ID of a thread
* @return an approximation of the total memory allocated, in bytes, in
- * heap memory for a thread of the specified ID
- * if the thread of the specified ID exists, the thread is alive,
+ * heap memory for the thread with the specified ID
+ * if the thread with the specified ID exists, the thread is alive,
* and thread memory allocation measurement is enabled;
* {@code -1} otherwise.
*
* @throws IllegalArgumentException if {@code id} {@code <=} {@code 0}.
- * @throws java.lang.UnsupportedOperationException if the Java virtual
+ * @throws UnsupportedOperationException if the Java virtual
* machine implementation does not support thread memory allocation
* measurement.
*
@@ -165,7 +202,7 @@
* @throws NullPointerException if {@code ids} is {@code null}
* @throws IllegalArgumentException if any element in the input array
* {@code ids} is {@code <=} {@code 0}.
- * @throws java.lang.UnsupportedOperationException if the Java virtual
+ * @throws UnsupportedOperationException if the Java virtual
* machine implementation does not support thread memory allocation
* measurement.
*
@@ -194,7 +231,7 @@
* @return {@code true} if thread memory allocation measurement is enabled;
* {@code false} otherwise.
*
- * @throws java.lang.UnsupportedOperationException if the Java virtual
+ * @throws UnsupportedOperationException if the Java virtual
* machine does not support thread memory allocation measurement.
*
* @see #isThreadAllocatedMemorySupported
@@ -208,10 +245,10 @@
* @param enable {@code true} to enable;
* {@code false} to disable.
*
- * @throws java.lang.UnsupportedOperationException if the Java virtual
+ * @throws UnsupportedOperationException if the Java virtual
* machine does not support thread memory allocation measurement.
*
- * @throws java.lang.SecurityException if a security manager
+ * @throws SecurityException if a security manager
* exists and the caller does not have
* ManagementPermission("control").
*
--- a/src/jdk.management/share/classes/com/sun/management/internal/HotSpotThreadImpl.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/jdk.management/share/classes/com/sun/management/internal/HotSpotThreadImpl.java Sun Sep 29 13:59:54 2019 +0200
@@ -58,6 +58,11 @@
}
@Override
+ public long getCurrentThreadAllocatedBytes() {
+ return super.getCurrentThreadAllocatedBytes();
+ }
+
+ @Override
public long getThreadAllocatedBytes(long id) {
return super.getThreadAllocatedBytes(id);
}
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Property.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Property.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -103,6 +103,7 @@
public static final int IS_ACCESSOR_PROPERTY = 1 << 12;
/** Property key. */
+ @SuppressWarnings("serial") // Not statically typed as Serializable
private final Object key;
/** Property flags. */
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -118,11 +118,13 @@
* Opaque object representing parser state at the end of the function. Used when reparsing outer function
* to help with skipping parsing inner functions.
*/
+ @SuppressWarnings("serial") // Not statically typed as Serializable
private final Object endParserState;
/** Code installer used for all further recompilation/specialization of this ScriptFunction */
private transient CodeInstaller installer;
+ @SuppressWarnings("serial") // Not statically typed as Serializable
private final Map<Integer, RecompilableScriptFunctionData> nestedFunctions;
/** Id to parent function if one exists */
@@ -135,8 +137,10 @@
private transient DebugLogger log;
+ @SuppressWarnings("serial") // Not statically typed as Serializable
private final Map<String, Integer> externalScopeDepths;
+ @SuppressWarnings("serial") // Not statically typed as Serializable
private final Set<String> internalSymbols;
private static final int GET_SET_PREFIX_LENGTH = "*et ".length();
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SharedPropertyMap.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SharedPropertyMap.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,6 +40,7 @@
*/
public final class SharedPropertyMap extends PropertyMap {
+ @SuppressWarnings("serial") // Not statically typed as Serializable
private SwitchPoint switchPoint;
private static final long serialVersionUID = 2166297719721778876L;
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/StoredScript.java Fri Sep 27 13:32:52 2019 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/StoredScript.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,12 +42,15 @@
private final String mainClassName;
/** Map of class names to class bytes. */
+ @SuppressWarnings("serial") // Not statically typed as Serializable
private final Map<String, byte[]> classBytes;
/** Constants array. */
+ @SuppressWarnings("serial") // Not statically typed as Serializable
private final Object[] constants;
/** Function initializers */
+ @SuppressWarnings("serial") // Not statically typed as Serializable
private final Map<Integer, FunctionInitializer> initializers;
private static final long serialVersionUID = 2958227232195298340L;
--- a/test/hotspot/jtreg/ProblemList.txt Fri Sep 27 13:32:52 2019 +0200
+++ b/test/hotspot/jtreg/ProblemList.txt Sun Sep 29 13:59:54 2019 +0200
@@ -206,16 +206,4 @@
vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn001/forceEarlyReturn001.java 7199837 generic-all
-vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/SynchronizerLockingThreads/SynchronizerLockingThreads001/TestDescription.java 8231032 generic-all
-vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/SynchronizerLockingThreads/SynchronizerLockingThreads002/TestDescription.java 8231032 generic-all
-vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/SynchronizerLockingThreads/SynchronizerLockingThreads003/TestDescription.java 8231032 generic-all
-vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/SynchronizerLockingThreads/SynchronizerLockingThreads004/TestDescription.java 8231032 generic-all
-vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/SynchronizerLockingThreads/SynchronizerLockingThreads005/TestDescription.java 8231032 generic-all
-
-vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi001/Multi001.java 8231032 generic-all
-vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi002/TestDescription.java 8231032 generic-all
-vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi003/TestDescription.java 8231032 generic-all
-vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi004/TestDescription.java 8231032 generic-all
-vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi005/TestDescription.java 8231032 generic-all
-
#############################################################################
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/escapeAnalysis/TestEliminateLocksOffCrash.java Sun Sep 29 13:59:54 2019 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8227384
+ * @summary C2 compilation fails with "graph should be schedulable" when running with -XX:-EliminateLocks
+ *
+ * @run main/othervm -XX:-EliminateLocks TestEliminateLocksOffCrash
+ */
+
+public class TestEliminateLocksOffCrash {
+ public static void main(String[] args) {
+ for (int i = 0; i < 20_000; i++) {
+ try {
+ test();
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ private static void test() throws Exception {
+ Object obj = new Object();
+ synchronized (obj) {
+ throw new Exception();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/loopopts/LoopUnrollBadNodeBudget.java Sun Sep 29 13:59:54 2019 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8229499
+ * @summary Node estimate for loop unrolling is not correct/sufficient:
+ * assert(delta <= 2 * required) failed: Bad node estimate ...
+ *
+ * @requires !vm.graal.enabled
+ *
+ * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation
+ * LoopUnrollBadNodeBudget
+ *
+ */
+
+public class LoopUnrollBadNodeBudget {
+
+ int a;
+ long b;
+ int c;
+ int d(long e, short f, int g) {
+ int h, j = 2, k, l[][] = new int[a][];
+ for (h = 8; h < 58; ++h)
+ for (k = 1; 7 > k; ++k)
+ switch (h % 9 * 5 + 43) {
+ case 70:
+ case 65:
+ case 86:
+ case 81:
+ case 62:
+ case 69:
+ case 74:
+ g = j;
+ }
+ long m = u(l);
+ return (int)m;
+ }
+ void n(int p, int o) { d(b, (short)0, p); }
+ void r(String[] q) {
+ int i = 4;
+ n(i, c);
+ }
+ long u(int[][] a) {
+ long sum = 0;
+ return sum;
+ }
+ public static void main(String[] t) {
+ try {
+ LoopUnrollBadNodeBudget s = new LoopUnrollBadNodeBudget();
+ for (int i = 5000; i > 0; i--)
+ s.r(t);
+ } catch (Exception ex) {
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/loopopts/TestCMovWithOpaque.java Sun Sep 29 13:59:54 2019 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8231223
+ * @summary Test conditional move optimization encountering an Opaque4Node.
+ * @run main/othervm -Xbatch -XX:-TieredCompilation
+ * -XX:CompileCommand=inline,compiler.loopopts.TestCMovWithOpaque::test
+ * compiler.loopopts.TestCMovWithOpaque
+ */
+
+package compiler.loopopts;
+
+public class TestCMovWithOpaque {
+
+ public static void test(int array[]) {
+ for (int i = 1; i < 8; i += 3) {
+ for (int j = 0; j < 4; ++j) {
+ switch (i % 4) {
+ case 0:
+ break;
+ case 1:
+ break;
+ case 2:
+ break;
+ case 3:
+ array[j] += 42;
+ break;
+ }
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ int[] array = new int[4];
+ for (int i = 0; i < 20_000; ++i) {
+ test(array);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/shenandoah/compiler/CallMultipleCatchProjs.java Sun Sep 29 13:59:54 2019 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8231405
+ * @summary barrier expansion breaks if barrier is right after call to rethrow stub
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -XX:CompileOnly=CallMultipleCatchProjs::test -Xcomp -Xverify:none -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC CallMultipleCatchProjs
+ *
+ */
+
+public class CallMultipleCatchProjs {
+ private static A field = new A();
+
+ public static void main(String[] args) throws Exception {
+ Exception3 exception3 = new Exception3();
+ test(new Exception2());
+ }
+
+ static int test(Exception exception) throws Exception {
+ try {
+ throw exception;
+ } catch (Exception1 e1) {
+ return 1;
+ } catch (Exception2 e2) {
+ return field.i + 2;
+ } catch (Exception3 e3) {
+ return field.i + 3;
+ }
+ }
+
+ private static class Exception1 extends Exception {
+ }
+
+ private static class Exception2 extends Exception {
+ }
+
+ private static class Exception3 extends Exception {
+ }
+
+ private static class A {
+ public int i;
+ }
+}
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbCDSCore.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbCDSCore.java Sun Sep 29 13:59:54 2019 +0200
@@ -34,26 +34,30 @@
* @run main/othervm/timeout=2400 -Xmx1g ClhsdbCDSCore
*/
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.HashMap;
-import jdk.test.lib.process.ProcessTools;
-import jdk.test.lib.Platform;
-import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.cds.CDSTestUtils;
-import jdk.test.lib.cds.CDSOptions;
+import java.io.File;
import java.io.IOException;
-import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-import jdk.test.lib.Asserts;
-import java.util.regex.Pattern;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
import jdk.internal.misc.Unsafe;
-import java.util.Scanner;
+
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Platform;
+import jdk.test.lib.cds.CDSOptions;
+import jdk.test.lib.cds.CDSTestUtils;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.SA.SATestUtils;
+
import jtreg.SkippedException;
class CrashApp {
@@ -102,6 +106,7 @@
System.out.println(crashOut.getOutput());
String crashOutputString = crashOut.getOutput();
+ SATestUtils.unzipCores(new File("."));
String coreFileLocation = getCoreFileLocation(crashOutputString);
if (coreFileLocation == null) {
if (Platform.isOSX()) {
--- a/test/hotspot/jtreg/serviceability/sa/TestJmapCore.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/hotspot/jtreg/serviceability/sa/TestJmapCore.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,19 +29,20 @@
* @run driver/timeout=240 TestJmapCore run heap
*/
+import java.io.File;
+
import jdk.test.lib.Asserts;
import jdk.test.lib.JDKToolFinder;
import jdk.test.lib.JDKToolLauncher;
import jdk.test.lib.Platform;
+import jdk.test.lib.Utils;
import jdk.test.lib.classloader.GeneratingClassLoader;
import jdk.test.lib.hprof.HprofParser;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.Utils;
+import jdk.test.lib.SA.SATestUtils;
import jtreg.SkippedException;
-import java.io.File;
-
public class TestJmapCore {
static final String pidSeparator = ":KILLED_PID";
@@ -97,9 +98,11 @@
? ProcessTools.executeProcess(pb)
: ProcessTools.executeProcess("sh", "-c", "ulimit -c unlimited && "
+ ProcessTools.getCommandLine(pb));
+ File pwd = new File(".");
+ SATestUtils.unzipCores(pwd);
File core;
String pattern = Platform.isWindows() ? ".*\\.mdmp" : "core(\\.\\d+)?";
- File[] cores = new File(".").listFiles((dir, name) -> name.matches(pattern));
+ File[] cores = pwd.listFiles((dir, name) -> name.matches(pattern));
if (cores.length == 0) {
// /cores/core.$pid might be generated on macosx by default
String pid = output.firstMatch("^(\\d+)" + pidSeparator, 1);
@@ -110,7 +113,7 @@
} else {
Asserts.assertTrue(cores.length == 1,
"There are unexpected files containing core "
- + ": " + String.join(",", new File(".").list()) + ".");
+ + ": " + String.join(",", pwd.list()) + ".");
core = cores[0];
}
System.out.println("Found corefile: " + core.getAbsolutePath());
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted002/TestDescription.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted002/TestDescription.java Sun Sep 29 13:59:54 2019 +0200
@@ -40,8 +40,8 @@
* @run driver jdk.test.lib.FileInstaller . .
* @run main/othervm/native
* -agentlib:resexhausted=-waittime=5
- * -Xms8m
- * -Xmx8m
+ * -Xms128m
+ * -Xmx128m
* -XX:-UseGCOverheadLimit
* nsk.jvmti.ResourceExhausted.resexhausted002
*/
--- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/ThreadMXBean/GetThreadAllocatedBytes/BaseBehaviorTest.README Fri Sep 27 13:32:52 2019 +0200
+++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/ThreadMXBean/GetThreadAllocatedBytes/BaseBehaviorTest.README Sun Sep 29 13:59:54 2019 +0200
@@ -1,4 +1,4 @@
-Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -21,7 +21,8 @@
DESCRIPTION
- Tests getThreadAllocatedBytes(long id) and getThreadAllocatedBytes(long[] ids),
+ Tests getCurrentThreadAllocatedBytes(), getThreadAllocatedBytes(long id),
+ and getThreadAllocatedBytes(long[] ids),
functions of com.sun.management.ThreadMXBean
All methods should
--- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/ThreadMXBean/GetThreadAllocatedBytes/BaseBehaviorTest.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/ThreadMXBean/GetThreadAllocatedBytes/BaseBehaviorTest.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,8 @@
import nsk.monitoring.ThreadMXBean.*;
/**
- * Tests getThreadAllocatedBytes(long id) and getThreadAllocatedBytes(long[] ids),
+ * Tests getCurrentThreadAllocatedBytes(), getThreadAllocatedBytes(long id).
+ * and getThreadAllocatedBytes(long[] ids),
* functions of com.sun.management.ThreadMXBean
* <p>
* All methods should
@@ -49,11 +50,31 @@
public void run() {
if (threadMXBean == null)
return;
+
+ // Expect -1 if thread allocated memory is disabled
+ threadMXBean.setThreadAllocatedMemoryEnabled(false);
+ long result = threadMXBean.getCurrentThreadAllocatedBytes();
+ if (result != -1)
+ throw new TestFailure("Failure! getCurrentThreadAllocatedBytes() should "
+ + "return -1 if ThreadAllocatedMemoryEnabled is set to false. "
+ + "Received : " + result);
+ threadMXBean.setThreadAllocatedMemoryEnabled(true);
+ // Expect >= 0 value for current thread
+ result = threadMXBean.getCurrentThreadAllocatedBytes();
+ if (result < 0)
+ throw new TestFailure("Failure! getCurrentThreadAllocatedBytes() should "
+ + "return >= 0 value for current thread. Received : " + result);
+ // Expect >= 0 value for current thread from getThreadAllocatedBytes(id)
+ result = threadMXBean.getThreadAllocatedBytes(Thread.currentThread().getId());
+ if (result < 0)
+ throw new TestFailure("Failure! getThreadAllocatedBytes(id) should "
+ + "return >= 0 value for current thread. Received : " + result);
+
MXBeanTestThread thread = new MXBeanTestThread();
long id = thread.getId();
long[] idArr = new long[] { id };
- long result;
long[] resultArr;
+
// Expect -1 for not started threads
result = threadMXBean.getThreadAllocatedBytes(id);
if (result != -1)
@@ -80,7 +101,7 @@
+ "Recieved : " + resultArr[0]);
threadMXBean.setThreadAllocatedMemoryEnabled(true);
- // Expect > 0 value for running threads
+ // Expect >= 0 value for running threads
result = threadMXBean.getThreadAllocatedBytes(id);
if (result < 0)
throw new TestFailure("Failure! getThreadAllocatedBytes(long id) should "
--- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/share/server/ServerThreadMXBeanNew.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/share/server/ServerThreadMXBeanNew.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -59,6 +59,10 @@
new String[] { long.class.getName() });
}
+ public long getCurrentThreadAllocatedBytes() {
+ return getLongAttribute("CurrentThreadAllocatedBytes");
+ }
+
public void setThreadAllocatedMemoryEnabled(boolean enabled) {
setBooleanAttribute("ThreadAllocatedMemoryEnabled", enabled);
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/share/thread/SynchronizerLockingThreads.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/share/thread/SynchronizerLockingThreads.java Sun Sep 29 13:59:54 2019 +0200
@@ -243,7 +243,7 @@
protected boolean isStackTraceElementExpected(StackTraceElement element) {
return super.isStackTraceElementExpected(element) ||
checkStackTraceElement(element, expectedMethodsThread2) ||
- element.getClassName().startsWith("java.util.concurrent.locks.") ||
+ element.getClassName().startsWith("java.util.concurrent.") ||
element.getClassName().startsWith("jdk.internal.misc.");
}
}
--- a/test/jdk/ProblemList.txt Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/ProblemList.txt Sun Sep 29 13:59:54 2019 +0200
@@ -564,8 +564,6 @@
javax/management/monitor/DerivedGaugeMonitorTest.java 8042211 generic-all
javax/management/remote/mandatory/connection/MultiThreadDeadLockTest.java 8042215 generic-all
-java/lang/management/ThreadMXBean/LockedSynchronizers.java 8231032 generic-all
-
############################################################################
# jdk_io
--- a/test/jdk/com/sun/management/ThreadMXBean/ThreadAllocatedMemory.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/com/sun/management/ThreadMXBean/ThreadAllocatedMemory.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6173675
+ * @bug 6173675 8231209
* @summary Basic test of ThreadMXBean.getThreadAllocatedBytes
* @author Paul Hohensee
*/
@@ -33,9 +33,8 @@
public class ThreadAllocatedMemory {
private static com.sun.management.ThreadMXBean mbean =
(com.sun.management.ThreadMXBean)ManagementFactory.getThreadMXBean();
- private static boolean testFailed = false;
- private static boolean done = false;
- private static boolean done1 = false;
+ private static volatile boolean done = false;
+ private static volatile boolean done1 = false;
private static Object obj = new Object();
private static final int NUM_THREADS = 10;
private static Thread[] threads = new Thread[NUM_THREADS];
@@ -44,6 +43,22 @@
public static void main(String[] argv)
throws Exception {
+ testSupportEnableDisable();
+
+ // Test current thread two ways
+ testGetCurrentThreadAllocatedBytes();
+ testCurrentThreadGetThreadAllocatedBytes();
+
+ // Test a single thread that is not this one
+ testGetThreadAllocatedBytes();
+
+ // Test many threads that are not this one
+ testGetThreadsAllocatedBytes();
+
+ System.out.println("Test passed");
+ }
+
+ private static void testSupportEnableDisable() {
if (!mbean.isThreadAllocatedMemorySupported()) {
return;
}
@@ -58,10 +73,7 @@
"ThreadAllocatedMemory is expected to be disabled");
}
- Thread curThread = Thread.currentThread();
- long id = curThread.getId();
-
- long s = mbean.getThreadAllocatedBytes(id);
+ long s = mbean.getCurrentThreadAllocatedBytes();
if (s != -1) {
throw new RuntimeException(
"Invalid ThreadAllocatedBytes returned = " +
@@ -77,63 +89,106 @@
throw new RuntimeException(
"ThreadAllocatedMemory is expected to be enabled");
}
+ }
+
+ private static void testGetCurrentThreadAllocatedBytes() {
+ long size = mbean.getCurrentThreadAllocatedBytes();
+ ensureValidSize(size);
+
+ // do some more allocation
+ doit();
+
+ checkResult(Thread.currentThread(), size,
+ mbean.getCurrentThreadAllocatedBytes());
+ }
+
+ private static void testCurrentThreadGetThreadAllocatedBytes() {
+ Thread curThread = Thread.currentThread();
+ long id = curThread.getId();
long size = mbean.getThreadAllocatedBytes(id);
- // implementation could have started measurement when
- // measurement was enabled, in which case size can be 0
- if (size < 0) {
- throw new RuntimeException(
- "Invalid allocated bytes returned = " + size);
- }
+ ensureValidSize(size);
+ // do some more allocation
doit();
- // Expected to be size1 >= size
- long size1 = mbean.getThreadAllocatedBytes(id);
- if (size1 < size) {
- throw new RuntimeException("Allocated bytes " + size1 +
- " expected >= " + size);
+ checkResult(curThread, size, mbean.getThreadAllocatedBytes(id));
+ }
+
+ private static void testGetThreadAllocatedBytes()
+ throws Exception {
+
+ // start a thread
+ done = false; done1 = false;
+ Thread curThread = new MyThread("MyThread");
+ curThread.start();
+ long id = curThread.getId();
+
+ // wait for thread to block after doing some allocation
+ waitUntilThreadBlocked(curThread);
+
+ long size = mbean.getThreadAllocatedBytes(id);
+ ensureValidSize(size);
+
+ // let thread go to do some more allocation
+ synchronized (obj) {
+ done = true;
+ obj.notifyAll();
}
- System.out.println(curThread.getName() +
- " Current thread allocated bytes = " + size +
- " allocated bytes = " + size1);
+
+ // wait for thread to get going again. we don't care if we
+ // catch it in mid-execution or if it hasn't
+ // restarted after we're done sleeping.
+ goSleep(400);
+
+ checkResult(curThread, size, mbean.getThreadAllocatedBytes(id));
+
+ // let thread exit
+ synchronized (obj) {
+ done1 = true;
+ obj.notifyAll();
+ }
+ try {
+ curThread.join();
+ } catch (InterruptedException e) {
+ System.out.println("Unexpected exception is thrown.");
+ e.printStackTrace(System.out);
+ }
+ }
- // start threads, wait for them to block
+ private static void testGetThreadsAllocatedBytes()
+ throws Exception {
+
+ // start threads
+ done = false; done1 = false;
for (int i = 0; i < NUM_THREADS; i++) {
threads[i] = new MyThread("MyThread-" + i);
threads[i].start();
}
- // threads block after doing some allocation
- waitUntilThreadBlocked();
+ // wait for threads to block after doing some allocation
+ waitUntilThreadsBlocked();
for (int i = 0; i < NUM_THREADS; i++) {
sizes[i] = mbean.getThreadAllocatedBytes(threads[i].getId());
+ ensureValidSize(sizes[i]);
}
- // let threads go and do some more allocation
+ // let threads go to do some more allocation
synchronized (obj) {
done = true;
obj.notifyAll();
}
- // wait for threads to get going again. we don't care if we
+ // wait for threads to get going again. we don't care if we
// catch them in mid-execution or if some of them haven't
// restarted after we're done sleeping.
goSleep(400);
for (int i = 0; i < NUM_THREADS; i++) {
- long newSize = mbean.getThreadAllocatedBytes(threads[i].getId());
- if (sizes[i] > newSize) {
- throw new RuntimeException("TEST FAILED: " +
- threads[i].getName() +
- " previous allocated bytes = " + sizes[i] +
- " > current allocated bytes = " + newSize);
- }
- System.out.println(threads[i].getName() +
- " Previous allocated bytes = " + sizes[i] +
- " Current allocated bytes = " + newSize);
+ checkResult(threads[i], sizes[i],
+ mbean.getThreadAllocatedBytes(threads[i].getId()));
}
// let threads exit
@@ -148,17 +203,30 @@
} catch (InterruptedException e) {
System.out.println("Unexpected exception is thrown.");
e.printStackTrace(System.out);
- testFailed = true;
break;
}
}
- if (testFailed) {
- throw new RuntimeException("TEST FAILED");
+ }
+
+ private static void ensureValidSize(long size) {
+ // implementation could have started measurement when
+ // measurement was enabled, in which case size can be 0
+ if (size < 0) {
+ throw new RuntimeException(
+ "Invalid allocated bytes returned = " + size);
}
-
- System.out.println("Test passed");
}
+ private static void checkResult(Thread curThread,
+ long prev_size, long curr_size) {
+ if (curr_size < prev_size) {
+ throw new RuntimeException("Allocated bytes " + curr_size +
+ " expected >= " + prev_size);
+ }
+ System.out.println(curThread.getName() +
+ " Previous allocated bytes = " + prev_size +
+ " Current allocated bytes = " + curr_size);
+ }
private static void goSleep(long ms) throws Exception {
try {
@@ -169,7 +237,18 @@
}
}
- private static void waitUntilThreadBlocked()
+ private static void waitUntilThreadBlocked(Thread thread)
+ throws Exception {
+ while (true) {
+ goSleep(100);
+ ThreadInfo info = mbean.getThreadInfo(thread.getId());
+ if (info.getThreadState() == Thread.State.WAITING) {
+ break;
+ }
+ }
+ }
+
+ private static void waitUntilThreadsBlocked()
throws Exception {
int count = 0;
while (count != NUM_THREADS) {
@@ -210,7 +289,6 @@
} catch (InterruptedException e) {
System.out.println("Unexpected exception is thrown.");
e.printStackTrace(System.out);
- testFailed = true;
break;
}
}
@@ -225,7 +303,7 @@
" ThreadAllocatedBytes = " + size2);
if (size1 > size2) {
- throw new RuntimeException("TEST FAILED: " + getName() +
+ throw new RuntimeException(getName() +
" ThreadAllocatedBytes = " + size1 +
" > ThreadAllocatedBytes = " + size2);
}
@@ -237,7 +315,6 @@
} catch (InterruptedException e) {
System.out.println("Unexpected exception is thrown.");
e.printStackTrace(System.out);
- testFailed = true;
break;
}
}
--- a/test/jdk/java/net/CookieHandler/LocalHostCookie.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/net/CookieHandler/LocalHostCookie.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
import java.net.*;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.Executors;
+import static java.net.Proxy.NO_PROXY;
/*
* @test
@@ -52,7 +52,7 @@
s = new Server();
s.startServer();
URL url = new URL("http","localhost", s.getPort(), "/");
- HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
+ HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection(NO_PROXY);
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();
--- a/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTest.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTest.java Sun Sep 29 13:59:54 2019 +0200
@@ -40,6 +40,7 @@
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import jdk.test.lib.net.SimpleSSLContext;
+import static java.net.Proxy.NO_PROXY;
/*
* @test
@@ -296,7 +297,7 @@
HttpURLConnection conn = (HttpURLConnection)
(authType == HttpAuthType.PROXY
? url.openConnection(proxy)
- : url.openConnection());
+ : url.openConnection(NO_PROXY));
return conn;
}
}
--- a/test/jdk/java/net/InetAddress/ptr/Lookup.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/net/InetAddress/ptr/Lookup.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,6 +42,8 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;
+import java.util.stream.Stream;
+import java.util.stream.Collectors;
import jdk.test.lib.JDKToolFinder;
import jdk.test.lib.process.OutputAnalyzer;
@@ -55,40 +57,80 @@
public static void main(String args[]) throws IOException {
String addr = null;
String ipv4Name = null;
+ String ipv4Reversed = null;
+
if (args.length == 0) {
- // First check that host resolves to IPv4 address
+ // called from lookupWithIPv4Prefer
+ // obtain an IPv4 address from the hostname.
try {
InetAddress ia = InetAddress.getByName(HOST);
addr = ia.getHostAddress();
+ ia = InetAddress.getByName(addr);
+ System.out.print(addr + ":" + ia.getHostName());
+ return;
+ } catch (UnknownHostException e) {
+ System.out.print(SKIP);
+ return;
+ }
+ } else if (args.length == 2 && args[0].equals("reverse")) {
+ // called from reverseWithIPv4Prefer
+ // Check that IPv4 address can be resolved to host
+ // with -Djava.net.preferIPv4Stack=true
+ try {
+ InetAddress ia = InetAddress.getByName(args[1]);
+ addr = ia.getHostAddress();
+ ipv4Reversed = ia.getHostName();
+ System.out.print(addr + ":" + ipv4Reversed);
+ return;
} catch (UnknownHostException e) {
System.out.print(SKIP);
return;
}
- } else {
- String tmp = lookupWithIPv4Prefer();
- System.out.println("IPv4 lookup results: [" + tmp + "]");
- if (SKIP.equals(tmp)) {
- System.out.println(HOST + " can't be resolved - test skipped.");
- return;
- }
+ } else if (args.length != 1 || !args[0].equals("root")) {
+ throw new IllegalArgumentException(Stream.of(args).collect(Collectors.joining(" ")));
+ }
- String[] strs = tmp.split(":");
- addr = strs[0];
- ipv4Name = strs[1];
+ // spawn a subprocess to obtain the IPv4 address
+ String tmp = lookupWithIPv4Prefer();
+ System.out.println("IPv4 lookup results: [" + tmp + "]");
+ if (SKIP.equals(tmp)) {
+ System.out.println(HOST + " can't be resolved - test skipped.");
+ return;
}
- // reverse lookup
+ String[] strs = tmp.split(":");
+ addr = strs[0];
+ ipv4Name = strs[1];
+
+ // check that the a reverse lookup of the IPv4 address
+ // will succeed with the IPv4 only stack
+ tmp = reverseWithIPv4Prefer(addr);
+ System.out.println("IPv4 reverse lookup results: [" + tmp + "]");
+ if (SKIP.equals(tmp)) {
+ System.out.println(addr + " can't be resolved with preferIPv4 - test skipped.");
+ return;
+ }
+
+ strs = tmp.split(":");
+ ipv4Reversed = strs[1];
+
+ // Now check that a reverse lookup will succeed with the dual stack.
InetAddress ia = InetAddress.getByName(addr);
String name = ia.getHostName();
- if (args.length == 0) {
- System.out.print(addr + ":" + name);
- return;
- } else {
- System.out.println("(default) " + addr + "--> " + name);
- if (!ipv4Name.equals(name)) {
- throw new RuntimeException("Mismatch between default"
- + " and java.net.preferIPv4Stack=true results");
+
+ System.out.println("(default) " + addr + "--> " + name
+ + " (reversed IPv4: " + ipv4Reversed + ")");
+ if (!ipv4Name.equals(name)) {
+ // adding some diagnosting
+ System.err.println("name=" + name + " doesn't match expected=" + ipv4Name);
+ System.err.println("Listing all adresses:");
+ for (InetAddress any : InetAddress.getAllByName(HOST)) {
+ System.err.println("\t[" + any + "] address=" + any.getHostAddress()
+ + ", host=" + any.getHostName());
}
+ // make the test fail...
+ throw new RuntimeException("Mismatch between default"
+ + " and java.net.preferIPv4Stack=true results");
}
}
@@ -100,5 +142,13 @@
System.out.println("Executing: " + cmd);
return new OutputAnalyzer(new ProcessBuilder(cmd).start()).getOutput();
}
+
+ static String reverseWithIPv4Prefer(String addr) throws IOException {
+ String java = JDKToolFinder.getTestJDKTool("java");
+ String testClz = Lookup.class.getName();
+ List<String> cmd = List.of(java, "-Djava.net.preferIPv4Stack=true",
+ "-cp", CLASS_PATH, testClz, "reverse", addr);
+ System.out.println("Executing: " + cmd);
+ return new OutputAnalyzer(new ProcessBuilder(cmd).start()).getOutput();
+ }
}
-
--- a/test/jdk/java/net/ProxySelector/NullSelector.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/net/ProxySelector/NullSelector.java Sun Sep 29 13:59:54 2019 +0200
@@ -25,6 +25,7 @@
* @bug 6215885
* @library /test/lib
* @summary URLConnection.openConnection NPE if ProxySelector.setDefault is set to null
+ * @run main/othervm NullSelector
*/
import java.net.*;
--- a/test/jdk/java/net/ResponseCache/B6181108.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/net/ResponseCache/B6181108.java Sun Sep 29 13:59:54 2019 +0200
@@ -33,6 +33,7 @@
import java.util.*;
import java.io.*;
import jdk.test.lib.net.URIBuilder;
+import static java.net.Proxy.NO_PROXY;
public class B6181108 implements Runnable {
ServerSocket ss;
@@ -105,7 +106,7 @@
.toString();
urlWithSpace = base + "/space%20test/page1.html";
URL url = new URL(urlWithSpace);
- URLConnection urlc = url.openConnection();
+ URLConnection urlc = url.openConnection(NO_PROXY);
int i = ((HttpURLConnection)(urlc)).getResponseCode();
System.out.println("response code = " + i);
ResponseCache.setDefault(null);
--- a/test/jdk/java/net/ResponseCache/ResponseCacheTest.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/net/ResponseCache/ResponseCacheTest.java Sun Sep 29 13:59:54 2019 +0200
@@ -33,6 +33,7 @@
import java.io.*;
import javax.net.ssl.*;
import jdk.test.lib.net.URIBuilder;
+import static java.net.Proxy.NO_PROXY;
/**
* Request should get serviced by the cache handler. Response get
@@ -137,7 +138,7 @@
.port(ss.getLocalPort())
.path("/file2.1")
.toURL();
- http = (HttpURLConnection)url2.openConnection();
+ http = (HttpURLConnection)url2.openConnection(NO_PROXY);
System.out.println("responsecode2 is :"+http.getResponseCode());
Map<String,List<String>> headers2 = http.getHeaderFields();
--- a/test/jdk/java/net/ResponseCache/getResponseCode.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/net/ResponseCache/getResponseCode.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
import java.net.*;
import java.util.*;
import java.io.*;
+import static java.net.Proxy.NO_PROXY;
/**
@@ -43,7 +44,7 @@
getResponseCode() throws Exception {
url = new URL("http://localhost/file1.cache");
- HttpURLConnection http = (HttpURLConnection)url.openConnection();
+ HttpURLConnection http = (HttpURLConnection)url.openConnection(NO_PROXY);
int respCode = http.getResponseCode();
http.disconnect();
--- a/test/jdk/java/net/URLConnection/B5052093.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/net/URLConnection/B5052093.java Sun Sep 29 13:59:54 2019 +0200
@@ -33,6 +33,7 @@
import java.net.*;
import java.io.*;
import sun.net.www.protocol.file.FileURLConnection;
+import static java.net.Proxy.NO_PROXY;
public class B5052093 implements HttpCallback {
private static TestHttpServer server;
@@ -68,7 +69,7 @@
server = new TestHttpServer(new B5052093(), 1, 10, loopback, 0);
try {
URL url = new URL("http://" + server.getAuthority() + "/foo");
- URLConnection conn = url.openConnection();
+ URLConnection conn = url.openConnection(NO_PROXY);
int i = conn.getContentLength();
long l = conn.getContentLengthLong();
if (i != -1 || l != testSize) {
--- a/test/jdk/java/net/URLConnection/DisconnectAfterEOF.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/net/URLConnection/DisconnectAfterEOF.java Sun Sep 29 13:59:54 2019 +0200
@@ -33,8 +33,7 @@
import java.io.*;
import java.util.*;
import jdk.test.lib.net.URIBuilder;
-
-
+import static java.net.Proxy.NO_PROXY;
public class DisconnectAfterEOF {
@@ -217,7 +216,7 @@
}
static URLConnection doRequest(String uri) throws IOException {
- URLConnection uc = (new URL(uri)).openConnection();
+ URLConnection uc = (new URL(uri)).openConnection(NO_PROXY);
uc.setDoOutput(true);
OutputStream out = uc.getOutputStream();
out.write(new byte[16000]);
--- a/test/jdk/java/net/URLConnection/HttpContinueStackOverflow.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/net/URLConnection/HttpContinueStackOverflow.java Sun Sep 29 13:59:54 2019 +0200
@@ -38,8 +38,8 @@
import java.net.Socket;
import java.net.URL;
import java.net.HttpURLConnection;
-
import jdk.test.lib.net.URIBuilder;
+import static java.net.Proxy.NO_PROXY;
public class HttpContinueStackOverflow {
@@ -93,7 +93,7 @@
.path("/anything.html")
.toURL();
- HttpURLConnection conn = (HttpURLConnection)url.openConnection();
+ HttpURLConnection conn = (HttpURLConnection)url.openConnection(NO_PROXY);
conn.getResponseCode();
System.out.println("TEST PASSED");
}
--- a/test/jdk/java/net/URLConnection/Redirect307Test.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/net/URLConnection/Redirect307Test.java Sun Sep 29 13:59:54 2019 +0200
@@ -29,8 +29,8 @@
*/
import java.io.*;
import java.net.*;
-
import jdk.test.lib.net.URIBuilder;
+import static java.net.Proxy.NO_PROXY;
class RedirServer extends Thread {
@@ -113,7 +113,7 @@
.loopback()
.port(port)
.toURL();
- URLConnection conURL = url.openConnection();
+ URLConnection conURL = url.openConnection(NO_PROXY);
conURL.setDoInput(true);
conURL.setAllowUserInteraction(false);
conURL.setUseCaches(false);
--- a/test/jdk/java/net/URLConnection/Responses.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/net/URLConnection/Responses.java Sun Sep 29 13:59:54 2019 +0200
@@ -29,6 +29,7 @@
*/
import java.net.*;
import java.io.*;
+import static java.net.Proxy.NO_PROXY;
public class Responses {
@@ -149,7 +150,7 @@
System.out.println("Test with response: >" + tests[i][0] + "<");
URL url = new URL("http://" + authority + "/" + i);
- HttpURLConnection http = (HttpURLConnection)url.openConnection();
+ HttpURLConnection http = (HttpURLConnection)url.openConnection(NO_PROXY);
try {
--- a/test/jdk/java/net/URLConnection/URLConnectionHeaders.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/net/URLConnection/URLConnectionHeaders.java Sun Sep 29 13:59:54 2019 +0200
@@ -35,6 +35,7 @@
import java.util.*;
import java.io.*;
import jdk.test.lib.net.URIBuilder;
+import static java.net.Proxy.NO_PROXY;
public class URLConnectionHeaders {
@@ -94,7 +95,7 @@
.port(port)
.path("/index.html")
.toURL();
- URLConnection uc = url.openConnection();
+ URLConnection uc = url.openConnection(NO_PROXY);
// add request properties
uc.addRequestProperty("Cookie", "cookie1");
--- a/test/jdk/java/net/URLConnection/contentHandler/UserContentHandler.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/net/URLConnection/contentHandler/UserContentHandler.java Sun Sep 29 13:59:54 2019 +0200
@@ -40,6 +40,7 @@
import java.io.*;
import java.util.*;
import jdk.test.lib.net.URIBuilder;
+import static java.net.Proxy.NO_PROXY;
public class UserContentHandler implements Runnable {
@@ -98,7 +99,7 @@
.path("/anything.txt")
.toURL();
- if (!(u.openConnection().getContent() instanceof String)) {
+ if (!(u.openConnection(NO_PROXY).getContent() instanceof String)) {
throw new RuntimeException("Load user defined content handler failed.");
} else {
System.err.println("Load user defined content handler succeed!");
--- a/test/jdk/java/net/URLPermission/OpenURL.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/net/URLPermission/OpenURL.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
import java.net.*;
import java.io.*;
import jdk.test.lib.net.URIBuilder;
+import static java.net.Proxy.NO_PROXY;
public class OpenURL {
@@ -46,7 +47,7 @@
.path("/a/b")
.toURL();
System.out.println("URL: " + url);
- HttpURLConnection urlc = (HttpURLConnection)url.openConnection();
+ HttpURLConnection urlc = (HttpURLConnection)url.openConnection(NO_PROXY);
InputStream is = urlc.getInputStream();
// error will throw exception other than SecurityException
} catch (SecurityException e) {
--- a/test/jdk/java/net/httpclient/ManyRequestsLegacy.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/net/httpclient/ManyRequestsLegacy.java Sun Sep 29 13:59:54 2019 +0200
@@ -74,6 +74,7 @@
import java.util.logging.Logger;
import java.util.logging.Level;
import jdk.test.lib.net.SimpleSSLContext;
+import static java.net.Proxy.NO_PROXY;
public class ManyRequestsLegacy {
@@ -159,7 +160,7 @@
long start = System.nanoTime();
try {
CompletableFuture<LegacyHttpResponse> cf = new CompletableFuture<>();
- URLConnection urlc = r.uri().toURL().openConnection();
+ URLConnection urlc = r.uri().toURL().openConnection(NO_PROXY);
HttpURLConnection httpc = (HttpURLConnection)urlc;
httpc.setRequestMethod(r.method());
for (String s : r.headers().map().keySet()) {
--- a/test/jdk/java/net/httpclient/PlainProxyConnectionTest.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/net/httpclient/PlainProxyConnectionTest.java Sun Sep 29 13:59:54 2019 +0200
@@ -44,6 +44,7 @@
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.stream.Collectors;
+import static java.net.Proxy.NO_PROXY;
/**
* @test
@@ -139,7 +140,7 @@
throws IOException {
connections.clear();
System.out.println("Verifying communication with server");
- try (InputStream is = uri.toURL().openConnection().getInputStream()) {
+ try (InputStream is = uri.toURL().openConnection(NO_PROXY).getInputStream()) {
String resp = new String(is.readAllBytes(), StandardCharsets.UTF_8);
System.out.println(resp);
if (!RESPONSE.equals(resp)) {
--- a/test/jdk/java/net/httpclient/ProxyTest.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/net/httpclient/ProxyTest.java Sun Sep 29 13:59:54 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -57,6 +57,7 @@
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import jdk.test.lib.net.SimpleSSLContext;
+import static java.net.Proxy.NO_PROXY;
/**
* @test
@@ -167,7 +168,7 @@
System.out.println("Verifying communication with server");
URI uri = new URI("https://localhost:"
+ server.getAddress().getPort() + PATH + "x");
- try (InputStream is = uri.toURL().openConnection().getInputStream()) {
+ try (InputStream is = uri.toURL().openConnection(NO_PROXY).getInputStream()) {
String resp = new String(is.readAllBytes(), StandardCharsets.UTF_8);
System.out.println(resp);
if (!RESPONSE.equals(resp)) {
--- a/test/jdk/java/util/concurrent/tck/JSR166TestCase.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/util/concurrent/tck/JSR166TestCase.java Sun Sep 29 13:59:54 2019 +0200
@@ -76,6 +76,7 @@
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.management.ManagementFactory;
+import java.lang.management.LockInfo;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.lang.reflect.Constructor;
@@ -270,6 +271,9 @@
}
}
+ private static final ThreadMXBean THREAD_MXBEAN
+ = ManagementFactory.getThreadMXBean();
+
/**
* The scaling factor to apply to standard delays used in tests.
* May be initialized from any of:
@@ -1157,9 +1161,8 @@
}
}
- ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
System.err.println("------ stacktrace dump start ------");
- for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true))
+ for (ThreadInfo info : THREAD_MXBEAN.dumpAllThreads(true, true))
if (threadOfInterest(info))
System.err.print(info);
System.err.println("------ stacktrace dump end ------");
@@ -1188,6 +1191,17 @@
}
/**
+ * Returns the thread's blocker's class name, if any, else null.
+ */
+ String blockerClassName(Thread thread) {
+ ThreadInfo threadInfo; LockInfo lockInfo;
+ if ((threadInfo = THREAD_MXBEAN.getThreadInfo(thread.getId(), 0)) != null
+ && (lockInfo = threadInfo.getLockInfo()) != null)
+ return lockInfo.getClassName();
+ return null;
+ }
+
+ /**
* Checks that future.get times out, with the default timeout of
* {@code timeoutMillis()}.
*/
@@ -1486,6 +1500,14 @@
}
/**
+ * Returns a new started daemon Thread running the given action,
+ * wrapped in a CheckedRunnable.
+ */
+ Thread newStartedThread(Action action) {
+ return newStartedThread(checkedRunnable(action));
+ }
+
+ /**
* Waits for the specified time (in milliseconds) for the thread
* to terminate (using {@link Thread#join(long)}), else interrupts
* the thread (in the hope that it may terminate later) and fails.
@@ -1532,6 +1554,13 @@
}
}
+ Runnable checkedRunnable(Action action) {
+ return new CheckedRunnable() {
+ public void realRun() throws Throwable {
+ action.run();
+ }};
+ }
+
public abstract class ThreadShouldThrow extends Thread {
protected abstract void realRun() throws Throwable;
--- a/test/jdk/java/util/concurrent/tck/ReentrantLockTest.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/util/concurrent/tck/ReentrantLockTest.java Sun Sep 29 13:59:54 2019 +0200
@@ -39,10 +39,13 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
+import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import junit.framework.Test;
@@ -1222,4 +1225,65 @@
assertFalse(thread.isAlive());
}
}
+
+ /**
+ * ThreadMXBean reports the blockers that we expect.
+ */
+ public void testBlockers() {
+ if (!testImplementationDetails) return;
+ final boolean fair = randomBoolean();
+ final boolean timedAcquire = randomBoolean();
+ final boolean timedAwait = randomBoolean();
+ final String syncClassName = fair
+ ? "ReentrantLock$FairSync"
+ : "ReentrantLock$NonfairSync";
+ final String conditionClassName
+ = "AbstractQueuedSynchronizer$ConditionObject";
+ final Thread.State expectedAcquireState = timedAcquire
+ ? Thread.State.TIMED_WAITING
+ : Thread.State.WAITING;
+ final Thread.State expectedAwaitState = timedAwait
+ ? Thread.State.TIMED_WAITING
+ : Thread.State.WAITING;
+ final Lock lock = new ReentrantLock(fair);
+ final Condition condition = lock.newCondition();
+ final AtomicBoolean conditionSatisfied = new AtomicBoolean(false);
+ lock.lock();
+ final Thread thread = newStartedThread((Action) () -> {
+ if (timedAcquire)
+ lock.tryLock(LONGER_DELAY_MS, MILLISECONDS);
+ else
+ lock.lock();
+ while (!conditionSatisfied.get())
+ if (timedAwait)
+ condition.await(LONGER_DELAY_MS, MILLISECONDS);
+ else
+ condition.await();
+ });
+ Callable<Boolean> waitingForLock = () -> {
+ String className;
+ return thread.getState() == expectedAcquireState
+ && (className = blockerClassName(thread)) != null
+ && className.endsWith(syncClassName);
+ };
+ waitForThreadToEnterWaitState(thread, waitingForLock);
+
+ lock.unlock();
+ Callable<Boolean> waitingForCondition = () -> {
+ String className;
+ return thread.getState() == expectedAwaitState
+ && (className = blockerClassName(thread)) != null
+ && className.endsWith(conditionClassName);
+ };
+ waitForThreadToEnterWaitState(thread, waitingForCondition);
+
+ // politely release the waiter
+ conditionSatisfied.set(true);
+ lock.lock();
+ try {
+ condition.signal();
+ } finally { lock.unlock(); }
+
+ awaitTermination(thread);
+ }
}
--- a/test/jdk/java/util/concurrent/tck/ReentrantReadWriteLockTest.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/util/concurrent/tck/ReentrantReadWriteLockTest.java Sun Sep 29 13:59:54 2019 +0200
@@ -38,6 +38,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
+import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Condition;
@@ -1707,4 +1708,64 @@
assertTrue(lock.writeLock().toString().contains("Unlocked"));
}
+ /**
+ * ThreadMXBean reports the blockers that we expect.
+ */
+ public void testBlockers() {
+ if (!testImplementationDetails) return;
+ final boolean fair = randomBoolean();
+ final boolean timedAcquire = randomBoolean();
+ final boolean timedAwait = randomBoolean();
+ final String syncClassName = fair
+ ? "ReentrantReadWriteLock$FairSync"
+ : "ReentrantReadWriteLock$NonfairSync";
+ final String conditionClassName
+ = "AbstractQueuedSynchronizer$ConditionObject";
+ final Thread.State expectedAcquireState = timedAcquire
+ ? Thread.State.TIMED_WAITING
+ : Thread.State.WAITING;
+ final Thread.State expectedAwaitState = timedAwait
+ ? Thread.State.TIMED_WAITING
+ : Thread.State.WAITING;
+ final Lock lock = new ReentrantReadWriteLock(fair).writeLock();
+ final Condition condition = lock.newCondition();
+ final AtomicBoolean conditionSatisfied = new AtomicBoolean(false);
+ lock.lock();
+ final Thread thread = newStartedThread((Action) () -> {
+ if (timedAcquire)
+ lock.tryLock(LONGER_DELAY_MS, MILLISECONDS);
+ else
+ lock.lock();
+ while (!conditionSatisfied.get())
+ if (timedAwait)
+ condition.await(LONGER_DELAY_MS, MILLISECONDS);
+ else
+ condition.await();
+ });
+ Callable<Boolean> waitingForLock = () -> {
+ String className;
+ return thread.getState() == expectedAcquireState
+ && (className = blockerClassName(thread)) != null
+ && className.endsWith(syncClassName);
+ };
+ waitForThreadToEnterWaitState(thread, waitingForLock);
+
+ lock.unlock();
+ Callable<Boolean> waitingForCondition = () -> {
+ String className;
+ return thread.getState() == expectedAwaitState
+ && (className = blockerClassName(thread)) != null
+ && className.endsWith(conditionClassName);
+ };
+ waitForThreadToEnterWaitState(thread, waitingForCondition);
+
+ // politely release the waiter
+ conditionSatisfied.set(true);
+ lock.lock();
+ try {
+ condition.signal();
+ } finally { lock.unlock(); }
+
+ awaitTermination(thread);
+ }
}
--- a/test/jdk/java/util/concurrent/tck/tck.policy Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/java/util/concurrent/tck/tck.policy Sun Sep 29 13:59:54 2019 +0200
@@ -12,4 +12,6 @@
permission java.lang.RuntimePermission "accessDeclaredMembers";
permission java.io.FilePermission "<<ALL FILES>>", "read";
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
+ // Allows test methods to inspect test thread state
+ permission java.lang.management.ManagementPermission "monitor";
};
--- a/test/jdk/sun/net/www/http/KeepAliveCache/KeepAliveTimerThread.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/sun/net/www/http/KeepAliveCache/KeepAliveTimerThread.java Sun Sep 29 13:59:54 2019 +0200
@@ -33,6 +33,7 @@
import java.net.*;
import java.io.*;
import jdk.test.lib.net.URIBuilder;
+import static java.net.Proxy.NO_PROXY;
public class KeepAliveTimerThread {
static class Fetcher implements Runnable {
@@ -44,7 +45,7 @@
public void run() {
try {
- InputStream in = url.openConnection().getInputStream();
+ InputStream in = url.openConnection(NO_PROXY).getInputStream();
byte b[] = new byte[128];
int n;
do {
--- a/test/jdk/sun/net/www/protocol/http/UserAuth.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/sun/net/www/protocol/http/UserAuth.java Sun Sep 29 13:59:54 2019 +0200
@@ -35,7 +35,7 @@
import java.io.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
-
+import static java.net.Proxy.NO_PROXY;
public class UserAuth
{
@@ -61,7 +61,7 @@
// GET Request
URL url = new URL("http://" + address.getHostName() + ":" + address.getPort() + "/redirect/");
- HttpURLConnection uc = (HttpURLConnection)url.openConnection();
+ HttpURLConnection uc = (HttpURLConnection)url.openConnection(NO_PROXY);
uc.setRequestProperty("Authorization", "testString:ValueDoesNotMatter");
int resp = uc.getResponseCode();
--- a/test/jdk/sun/net/www/protocol/http/UserCookie.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/sun/net/www/protocol/http/UserCookie.java Sun Sep 29 13:59:54 2019 +0200
@@ -33,6 +33,7 @@
import com.sun.net.httpserver.*;
import java.util.*;
import java.io.*;
+import static java.net.Proxy.NO_PROXY;
public class UserCookie
{
@@ -59,7 +60,7 @@
InetSocketAddress address = httpServer.getAddress();
URL url = new URL("http://" + address.getHostName() + ":" + address.getPort() + "/test/");
- HttpURLConnection uc = (HttpURLConnection)url.openConnection();
+ HttpURLConnection uc = (HttpURLConnection)url.openConnection(NO_PROXY);
uc.setRequestProperty("Cookie", "value=ValueDoesNotMatter");
int resp = uc.getResponseCode();
--- a/test/jdk/sun/tools/jhsdb/JShellHeapDumpTest.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/jdk/sun/tools/jhsdb/JShellHeapDumpTest.java Sun Sep 29 13:59:54 2019 +0200
@@ -39,6 +39,7 @@
import java.util.Map;
import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.JDKToolFinder;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.hprof.parser.HprofReader;
@@ -47,40 +48,42 @@
public class JShellHeapDumpTest {
- protected static Process process;
-
- private static long pid;
+ protected static Process jShellProcess;
public static void launch(String expectedMessage, List<String> toolArgs)
throws IOException {
try {
launchJshell();
+ long jShellPID = jShellProcess.pid();
- System.out.println("Starting " + toolArgs.get(0) + " against " + pid);
+ System.out.println("Starting " + toolArgs.get(0) + " against " + jShellPID);
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
for (String cmd : toolArgs) {
launcher.addToolArg(cmd);
}
- launcher.addToolArg("--pid=" + Long.toString(pid));
+ launcher.addToolArg("--pid=" + Long.toString(jShellPID));
ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand());
- processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
- System.out.println("stdout:");
+ System.out.println("jhsdb jmap stdout:");
System.out.println(output.getStdout());
- System.out.println("stderr:");
+ System.out.println("jhsdb jmap stderr:");
System.out.println(output.getStderr());
- output.shouldNotContain("null");
+ System.out.println("###### End of all output:");
output.shouldHaveExitValue(0);
} catch (Exception ex) {
throw new RuntimeException("Test ERROR " + ex, ex);
} finally {
- if (process.isAlive()) {
- process.destroy();
- }
+ if (jShellProcess.isAlive()) {
+ System.out.println("Destroying jshell");
+ jShellProcess.destroy();
+ System.out.println("Jshell destroyed");
+ } else {
+ System.out.println("Jshell not alive");
+ }
}
}
@@ -102,38 +105,45 @@
}
public static void testHeapDump() throws IOException {
- File dump = new File("jhsdb.jmap.heap." +
+ File hprofFile = new File("jhsdb.jmap.heap." +
System.currentTimeMillis() + ".hprof");
- if (dump.exists()) {
- dump.delete();
+ if (hprofFile.exists()) {
+ hprofFile.delete();
}
launch("heap written to", "jmap",
- "--binaryheap", "--dumpfile=" + dump.getAbsolutePath());
+ "--binaryheap", "--dumpfile=" + hprofFile.getAbsolutePath());
+
+ assertTrue(hprofFile.exists() && hprofFile.isFile(),
+ "Could not create dump file " + hprofFile.getAbsolutePath());
- assertTrue(dump.exists() && dump.isFile(),
- "Could not create dump file " + dump.getAbsolutePath());
+ printStackTraces(hprofFile.getAbsolutePath());
- printStackTraces(dump.getAbsolutePath());
-
- dump.delete();
+ System.out.println("hprof file size: " + hprofFile.length());
+ hprofFile.delete();
}
public static void launchJshell() throws IOException {
System.out.println("Starting Jshell");
- String jdkPath = System.getProperty("test.jdk");
- if (jdkPath == null) {
- // we are not under jtreg, try env
- Map<String, String> env = System.getenv();
- jdkPath = env.get("TESTJAVA");
+ long startTime = System.currentTimeMillis();
+ try {
+ ProcessBuilder pb = new ProcessBuilder(JDKToolFinder.getTestJDKTool("jshell"));
+ jShellProcess = ProcessTools.startProcess("JShell", pb,
+ s -> { // warm-up predicate
+ return s.contains("Welcome to JShell");
+ });
+ } catch (Exception ex) {
+ throw new RuntimeException("Test ERROR " + ex, ex);
}
- if (jdkPath == null) {
- throw new RuntimeException("Can't determine jdk path neither test.jdk property no TESTJAVA env are set");
+
+ long elapsedTime = System.currentTimeMillis() - startTime;
+ System.out.println("Jshell Started in " + elapsedTime + "ms");
+
+ // Give jshell a chance to fully start up. This makes SA more stable for the jmap dump.
+ try {
+ Thread.sleep(2000);
+ } catch (Exception e) {
}
- String osname = System.getProperty("os.name");
- String jshell = jdkPath + ((osname.startsWith("window")) ? "/bin/jshell.exe" : "/bin/jshell");
- process = Runtime.getRuntime().exec(jshell);
- pid = process.pid();
}
public static void main(String[] args) throws Exception {
--- a/test/lib/jdk/test/lib/SA/SATestUtils.java Fri Sep 27 13:32:52 2019 +0200
+++ b/test/lib/jdk/test/lib/SA/SATestUtils.java Sun Sep 29 13:59:54 2019 +0200
@@ -22,12 +22,18 @@
*/
package jdk.test.lib.SA;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
-import java.util.ArrayList;
+import java.util.concurrent.TimeUnit;
+import java.util.zip.GZIPInputStream;
+
import jdk.test.lib.Asserts;
import jdk.test.lib.Platform;
-import java.util.concurrent.TimeUnit;
+import jtreg.SkippedException;
public class SATestUtils {
@@ -77,4 +83,22 @@
outStringList.addAll(cmdStringList);
return outStringList;
}
+
+ public static void unzipCores(File dir) {
+ File[] gzCores = dir.listFiles((directory, name) -> name.matches("core(\\.\\d+)?\\.gz"));
+ for (File gzCore : gzCores) {
+ String coreFileName = gzCore.getName().replace(".gz", "");
+ System.out.println("Unzipping core into " + coreFileName);
+ try (GZIPInputStream gzis = new GZIPInputStream(new FileInputStream(gzCore));
+ FileOutputStream fos = new FileOutputStream(coreFileName)) {
+ byte[] buffer = new byte[1024];
+ int length;
+ while ((length = gzis.read(buffer)) > 0) {
+ fos.write(buffer, 0, length);
+ }
+ } catch (IOException e) {
+ throw new SkippedException("Not able to unzip file: " + gzCore.getAbsolutePath(), e);
+ }
+ }
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/StackWalkBench.java Sun Sep 29 13:59:54 2019 +0200
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import java.lang.StackWalker.StackFrame;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+/**
+ * Benchmarks for java.lang.StackWalker
+ */
+@State(value=Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class StackWalkBench {
+ private static final StackWalker WALKER_DEFAULT = StackWalker.getInstance();
+
+ private static final StackWalker WALKER_CLASS =
+ StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
+
+ // TestStack will add this number of calls to the call stack
+ @Param({"4", "100", "1000"})
+ // For more thorough testing, consider:
+ // @Param({"4", "10", "100", "256", "1000"})
+ public int depth;
+
+ // Only used by swFilterCallerClass, to specify (roughly) how far back the
+ // call stack the target class will be found. Not needed by other
+ // benchmarks, so not a @Param by default.
+ // @Param({"4"})
+ public int mark = 4;
+
+ /** Build a call stack of a given size, then run trigger code in it.
+ * (Does not account for existing frames higher up in the JMH machinery).
+ */
+ public static class TestStack {
+ final long fence;
+ long current;
+ final Runnable trigger;
+
+ public TestStack(long max, Runnable trigger) {
+ this.fence = max;
+ this.current = 0;
+ this.trigger = trigger;
+ }
+
+ public void start() {
+ one();
+ }
+
+ public void one() {
+ if (check()) {
+ two();
+ }
+ }
+
+ void two() {
+ if (check()) {
+ three();
+ }
+ }
+
+ private void three() {
+ if (check()) {
+ one();
+ }
+ }
+
+ boolean check() {
+ if (++current == fence) {
+ trigger.run();
+ return false;
+ } else {
+ return true;
+ }
+ }
+ }
+
+ /* Class to look for when testing filtering */
+ static class TestMarker {
+ public void call(MarkedTestStack test) {
+ test.marked();
+ }
+ }
+
+ /** Call stack to test filtering.
+ * TestMarker will make a call on the stack.
+ */
+ static class MarkedTestStack extends TestStack {
+ long mark;
+
+ /**
+ * @param mark How far back the stack should the TestMarker be found?
+ */
+ public MarkedTestStack(long max, long mark, Runnable trigger) {
+ super(max, trigger);
+ if (mark > max) {
+ throw new IllegalArgumentException("mark must be <= max");
+ }
+ this.mark = max - mark; // Count backwards from the completed call stack
+ }
+ @Override
+ public void start() {
+ if (mark == 0) {
+ mark();
+ } else {
+ super.one();
+ }
+ }
+ @Override
+ boolean check() {
+ if (++current == mark) {
+ mark();
+ return false;
+ } else if (current == fence) {
+ trigger.run();
+ return false;
+ } else {
+ return true;
+ }
+ }
+ void mark() {
+ new TestMarker().call(this);
+ }
+ public void marked() {
+ if (current < fence) {
+ if (check()) {
+ one();
+ }
+ } else {
+ trigger.run();
+ }
+ }
+ }
+
+ /**
+ * StackWalker.forEach() with default options
+ */
+ @Benchmark
+ public void forEach_DefaultOpts(Blackhole bh) {
+ final Blackhole localBH = bh;
+ final boolean[] done = {false};
+ new TestStack(depth, new Runnable() {
+ public void run() {
+ WALKER_DEFAULT.forEach(localBH::consume);
+ done[0] = true;
+ }
+ }).start();
+ if (!done[0]) {
+ throw new RuntimeException();
+ }
+ }
+
+ /**
+ * Use Stackwalker.walk() to fetch class names
+ */
+ @Benchmark
+ public void walk_ClassNames(Blackhole bh) {
+ final Blackhole localBH = bh;
+ final boolean[] done = {false};
+ new TestStack(depth, new Runnable() {
+ public void run() {
+ WALKER_DEFAULT.walk(s -> {
+ s.map(StackFrame::getClassName).forEach(localBH::consume);
+ return null;
+ });
+ done[0] = true;
+ }
+ }).start();
+ if (!done[0]) {
+ throw new RuntimeException();
+ }
+ }
+
+ /**
+ * Use Stackwalker.walk() to fetch method names
+ */
+ @Benchmark
+ public void walk_MethodNames(Blackhole bh) {
+ final Blackhole localBH = bh;
+ final boolean[] done = {false};
+ new TestStack(depth, new Runnable() {
+ public void run() {
+ WALKER_DEFAULT.walk( s -> {
+ s.map(StackFrame::getMethodName).forEach(localBH::consume);
+ return null;
+ });
+ done[0] = true;
+ }
+ }).start();
+ if (!done[0]) {
+ throw new RuntimeException();
+ }
+ }
+
+ /**
+ * Use Stackwalker.walk() to fetch declaring class instances
+ */
+ @Benchmark
+ public void walk_DeclaringClass(Blackhole bh) {
+ final Blackhole localBH = bh;
+ final boolean[] done = {false};
+ new TestStack(depth, new Runnable() {
+ public void run() {
+ WALKER_CLASS.walk(s -> {
+ s.map(StackFrame::getDeclaringClass).forEach(localBH::consume);
+ return null;
+ });
+ done[0] = true;
+ }
+ }).start();
+ if (!done[0]) {
+ throw new RuntimeException();
+ }
+ }
+
+ /**
+ * Use StackWalker.walk() to fetch StackTraceElements
+ */
+ @Benchmark
+ public void walk_StackTraceElements(Blackhole bh) {
+ final Blackhole localBH = bh;
+ final boolean[] done = {false};
+ new TestStack(depth, new Runnable() {
+ public void run() {
+ WALKER_DEFAULT.walk(s -> {
+ s.map(StackFrame::toStackTraceElement).forEach(localBH::consume);
+ return null;
+ });
+ done[0] = true;
+ }
+ }).start();
+ if (!done[0]) {
+ throw new RuntimeException();
+ }
+ }
+
+ /**
+ * StackWalker.getCallerClass()
+ */
+ @Benchmark
+ public void getCallerClass(Blackhole bh) {
+ final Blackhole localBH = bh;
+ final boolean[] done = {false};
+ new TestStack(depth, new Runnable() {
+ public void run() {
+ localBH.consume(WALKER_CLASS.getCallerClass());
+ done[0] = true;
+ }
+ }).start();
+ if (!done[0]) {
+ throw new RuntimeException();
+ }
+ }
+
+ /**
+ * Use StackWalker.walk() to filter the StackFrames, looking for the
+ * TestMarker class, which will be (approximately) 'mark' calls back up the
+ * call stack.
+ */
+ @Benchmark
+ public void walk_filterCallerClass(Blackhole bh) {
+ final Blackhole localBH = bh;
+ final boolean[] done = {false};
+
+ new MarkedTestStack(depth, mark, new Runnable() {
+ public void run() {
+ // To be comparable with Reflection.getCallerClass(), return the Class object
+ WALKER_CLASS.walk(s -> {
+ localBH.consume(s.filter(f -> TestMarker.class.equals(f.getDeclaringClass())).findFirst().get().getDeclaringClass());
+ return null;
+ });
+ done[0] = true;
+ }
+ }).start();
+
+ if (!done[0]) {
+ throw new RuntimeException();
+ }
+ }
+
+ /**
+ * Use StackWalker.walk() to filter the StackFrames, looking for the
+ * TestMarker class, which will be (approximately) depth/2 calls back up the
+ * call stack.
+ */
+ @Benchmark
+ public void walk_filterCallerClassHalfStack(Blackhole bh) {
+ final Blackhole localBH = bh;
+ final boolean[] done = {false};
+
+ new MarkedTestStack(depth, depth / 2, new Runnable() {
+ public void run() {
+ // To be comparable with Reflection.getCallerClass(), return the Class object
+ WALKER_CLASS.walk(s -> {
+ localBH.consume(s.filter((f) -> TestMarker.class.equals(f.getDeclaringClass())).findFirst().get().getDeclaringClass());
+ return null;
+ });
+ done[0] = true;
+ }
+ }).start();
+
+ if (!done[0]) {
+ throw new RuntimeException();
+ }
+ }
+
+ // TODO: add swConsumeFramesWithReflection
+ // TODO: add swFilterOutStreamClasses
+
+// // This benchmark is for collecting performance counter data
+// static PerfCounter streamTime = PerfCounter.newPerfCounter("jdk.stackwalk.testStreamsElapsedTime");
+// static PerfCounter numStream = PerfCounter.newPerfCounter("jdk.stackwalk.numTestStreams");
+// // @Benchmark
+// public void swStkFrmsTimed(Blackhole bh) {
+// final Blackhole localBH = bh;
+// final boolean[] done = {false};
+// new TestStack(depth, new Runnable() {
+// public void run() {
+// long t0 = System.nanoTime();
+// WALKER_DEFAULT.forEach(localBH::consume);
+// streamTime.addElapsedTimeFrom(t0);
+// numStream.increment();
+// done[0] = true;
+// }
+// }).start();
+// if (!done[0]) {
+// throw new RuntimeException();
+// }
+// }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/logging/LoggingRuntimeMicros.java Sun Sep 29 13:59:54 2019 +0200
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.util.logging;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.LogRecord;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+@State(value = Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class LoggingRuntimeMicros {
+
+ // TestStack will add this number of calls to the call stack
+ @Param({"4", "100", "1000"})
+ // For more thorough testing, consider:
+ // @Param({"4", "10", "100", "256", "1000"})
+ public int depth;
+
+ /** Logging handler for testing logging calls. */
+ @State(value = Scope.Thread) // create a separate one for each worker thread
+ public static class TestHandler extends java.util.logging.Handler {
+ private final static AtomicInteger serialNum = new AtomicInteger(0);
+
+ private final java.util.logging.Logger logger;
+ private volatile LogRecord record;
+
+ public TestHandler() {
+ // Each instance uses its own logger
+ logger = java.util.logging.Logger.getLogger("StackWalkBench" + serialNum.incrementAndGet());
+ logger.setUseParentHandlers(false);
+ logger.addHandler(this);
+ }
+
+ @Override
+ public void publish(LogRecord record) {
+ record.getSourceMethodName();
+ this.record = record;
+ }
+
+ private LogRecord reset() {
+ LogRecord record = this.record;
+ this.record = null;
+ return record;
+ }
+
+ public final LogRecord testInferCaller(String msg) {
+ logger.info(msg);
+ LogRecord rec = this.reset();
+ if (!"testInferCaller".equals(rec.getSourceMethodName())) {
+ throw new RuntimeException("bad caller: "
+ + rec.getSourceClassName() + "."
+ + rec.getSourceMethodName());
+ }
+ return rec;
+ }
+
+ public final LogRecord testLogp(String msg) {
+ logger.logp(java.util.logging.Level.INFO, "foo", "bar", msg);
+ LogRecord rec = this.reset();
+ if (!"bar".equals(rec.getSourceMethodName())) {
+ throw new RuntimeException("bad caller: "
+ + rec.getSourceClassName() + "."
+ + rec.getSourceMethodName());
+ }
+ return rec;
+ }
+ @Override public void flush() {}
+ @Override public void close() throws SecurityException {}
+ }
+
+ /** Build a call stack of a given size, then run trigger code in it.
+ * (Does not account for existing frames higher up in the JMH machinery).
+ */
+ static class TestStack {
+ final long fence;
+ long current;
+ final Runnable trigger;
+
+ TestStack(long max, Runnable trigger) {
+ this.fence = max;
+ this.current = 0;
+ this.trigger = trigger;
+ }
+
+ public void start() {
+ one();
+ }
+
+ public void one() {
+ if (check()) {
+ two();
+ }
+ }
+
+ void two() {
+ if (check()) {
+ three();
+ }
+ }
+
+ private void three() {
+ if (check()) {
+ one();
+ }
+ }
+
+ boolean check() {
+ if (++current == fence) {
+ trigger.run();
+ return false;
+ } else {
+ return true;
+ }
+ }
+ }
+
+ @Benchmark
+ public void testLoggingInferCaller(TestHandler handler, Blackhole bh) {
+ final Blackhole localBH = bh;
+ final boolean[] done = {false};
+ new TestStack(depth, new Runnable() {
+ public void run() {
+ localBH.consume(handler.testInferCaller("test"));
+ done[0] = true;
+ }
+ }).start();
+ if (!done[0]) {
+ throw new RuntimeException();
+ }
+ }
+
+ @Benchmark
+ public void testLoggingLogp(TestHandler handler, Blackhole bh) {
+ final Blackhole localBH = bh;
+ final boolean[] done = {false};
+ new TestStack(depth, new Runnable() {
+ public void run() {
+ localBH.consume(handler.testLogp("test"));
+ done[0] = true;
+ }
+ }).start();
+ if (!done[0]) {
+ throw new RuntimeException();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lang/ThrowableRuntimeMicros.java Sun Sep 29 13:59:54 2019 +0200
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.vm.lang;
+
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+@State(value = Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ThrowableRuntimeMicros {
+
+ // TestStack will add this number of calls to the call stack
+ @Param({"4", "100", "1000"})
+ // For more thorough testing, consider:
+ // @Param({"4", "10", "100", "256", "1000"})
+ public int depth;
+
+ /** Build a call stack of a given size, then run trigger code in it.
+ * (Does not account for existing frames higher up in the JMH machinery).
+ */
+ static class TestStack {
+ final long fence;
+ long current;
+ final Runnable trigger;
+
+ TestStack(long max, Runnable trigger) {
+ this.fence = max;
+ this.current = 0;
+ this.trigger = trigger;
+ }
+
+ public void start() {
+ one();
+ }
+
+ public void one() {
+ if (check()) {
+ two();
+ }
+ }
+
+ void two() {
+ if (check()) {
+ three();
+ }
+ }
+
+ private void three() {
+ if (check()) {
+ one();
+ }
+ }
+
+ boolean check() {
+ if (++current == fence) {
+ trigger.run();
+ return false;
+ } else {
+ return true;
+ }
+ }
+ }
+
+ @Benchmark
+ public void testThrowableInit(Blackhole bh) {
+ final Blackhole localBH = bh;
+ final boolean[] done = {false};
+ new TestStack(depth, new Runnable() {
+ public void run() {
+ localBH.consume(new Throwable());
+ done[0] = true;
+ }
+ }).start();
+ if (!done[0]) {
+ throw new RuntimeException();
+ }
+ }
+
+ @Benchmark
+ public void testThrowableGetStackTrace(Blackhole bh) {
+ final Blackhole localBH = bh;
+ final boolean[] done = {false};
+ new TestStack(depth, new Runnable() {
+ public void run() {
+ localBH.consume(new Throwable().getStackTrace());
+ done[0] = true;
+ }
+ }).start();
+ if (!done[0]) {
+ throw new RuntimeException();
+ }
+ }
+
+ @Benchmark
+ public void testThrowableSTEtoString(Blackhole bh) {
+ final Blackhole localBH = bh;
+ final boolean[] done = {false};
+ new TestStack(depth, new Runnable() {
+ public void run() {
+ Throwable t = new Throwable();
+ for (StackTraceElement ste : t.getStackTrace()) {
+ localBH.consume(ste.toString());
+ }
+ done[0] = true;
+ }
+ }).start();
+ if (!done[0]) {
+ throw new RuntimeException();
+ }
+ }
+}