From 01f09f57824ac2b0b818e36cdd917e756aa26c3b Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Mon, 7 Nov 2016 10:12:14 +0100 Subject: [PATCH 001/235] 8169255: Link gtestLauncher statically if libjvm is configured for static linking Reviewed-by: tbell, dholmes --- hotspot/make/lib/CompileGtest.gmk | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/make/lib/CompileGtest.gmk b/hotspot/make/lib/CompileGtest.gmk index 9c69a2f175a..a4c2c0cb34f 100644 --- a/hotspot/make/lib/CompileGtest.gmk +++ b/hotspot/make/lib/CompileGtest.gmk @@ -107,6 +107,7 @@ $(eval $(call SetupNativeCompilation, BUILD_GTEST_LAUNCHER, \ LDFLAGS := $(LDFLAGS_JDKEXE), \ LDFLAGS_unix := -L$(JVM_OUTPUTDIR)/gtest $(call SET_SHARED_LIBRARY_ORIGIN), \ LDFLAGS_solaris := -library=stlport4, \ + LIBS_linux := $(LIBCXX), \ LIBS_unix := -ljvm, \ LIBS_windows := $(JVM_OUTPUTDIR)/gtest/objs/jvm.lib, \ COPY_DEBUG_SYMBOLS := $(GTEST_COPY_DEBUG_SYMBOLS), \ From afd17cbfc44ad0aaa684d2ecd871b0fb86fd490b Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 31 Oct 2016 11:36:45 +0100 Subject: [PATCH 002/235] 8166837: [TESTBUG] Fix tests on Linux/s390x Reviewed-by: kvn, simonis --- .../sun/jvm/hotspot/CommandProcessor.java | 2 +- hotspot/test/compiler/ciReplay/SABase.java | 7 ++- .../intrinsics/sha/cli/SHAOptionsBase.java | 6 +-- .../testcases/GenericTestCaseForOtherCPU.java | 9 ++-- .../sha/predicate/IntrinsicPredicates.java | 50 ++++++++++--------- hotspot/test/test_env.sh | 7 ++- ...stMutuallyExclusivePlatformPredicates.java | 2 +- 7 files changed, 48 insertions(+), 35 deletions(-) diff --git a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java index 916cb445387..ec8b0ac70a9 100644 --- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java @@ -1957,7 +1957,7 @@ public class CommandProcessor { if (doit == null) { out.println("Unrecognized command. Try help..."); } else if (!debugger.isAttached() && !doit.okIfDisconnected) { - out.println("Command not valid until the attached to a VM"); + out.println("Command not valid until attached to a VM"); } else { try { doit.doit(args); diff --git a/hotspot/test/compiler/ciReplay/SABase.java b/hotspot/test/compiler/ciReplay/SABase.java index 731e25634d3..0354835b8f9 100644 --- a/hotspot/test/compiler/ciReplay/SABase.java +++ b/hotspot/test/compiler/ciReplay/SABase.java @@ -39,7 +39,12 @@ import jdk.test.lib.process.ProcessTools; public class SABase extends CiReplayBase { private static final String REPLAY_FILE_COPY = "replay_vm.txt"; - public static void main(String args[]) { + public static void main(String args[]) throws Exception { + if (!Platform.shouldSAAttach()) { + System.out.println("SA attach not expected to work - test skipped."); + return; + } + checkSetLimits(); new SABase(args).runTest(/* needCoreDump = */ true, args); } diff --git a/hotspot/test/compiler/intrinsics/sha/cli/SHAOptionsBase.java b/hotspot/test/compiler/intrinsics/sha/cli/SHAOptionsBase.java index 7dd21546d46..120f1029a9a 100644 --- a/hotspot/test/compiler/intrinsics/sha/cli/SHAOptionsBase.java +++ b/hotspot/test/compiler/intrinsics/sha/cli/SHAOptionsBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, 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 @@ -74,7 +74,7 @@ public class SHAOptionsBase extends CommandLineOptionTest { * instructions required by the option are not supported. */ public static String getWarningForUnsupportedCPU(String optionName) { - if (Platform.isSparc() || Platform.isAArch64() || + if (Platform.isAArch64() || Platform.isS390x() || Platform.isSparc() || Platform.isX64() || Platform.isX86()) { switch (optionName) { case SHAOptionsBase.USE_SHA_OPTION: @@ -89,7 +89,7 @@ public class SHAOptionsBase extends CommandLineOptionTest { throw new Error("Unexpected option " + optionName); } } else { - throw new Error("Support for CPUs different fromn X86, SPARC, and AARCH64 " + throw new Error("Support for CPUs different fromn AARCH64, S390x, SPARC, and X86 " + "is not implemented"); } } diff --git a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java index 9d894947cdc..698afa06de0 100644 --- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java +++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java @@ -37,11 +37,12 @@ import jdk.test.lib.cli.predicate.OrPredicate; public class GenericTestCaseForOtherCPU extends SHAOptionsBase.TestCase { public GenericTestCaseForOtherCPU(String optionName) { - // Execute the test case on any CPU except SPARC and X86 + // Execute the test case on any CPU except AArch64, S390x, SPARC and X86. super(optionName, new NotPredicate( - new OrPredicate( - new OrPredicate(Platform::isSparc, Platform::isAArch64), - new OrPredicate(Platform::isX64, Platform::isX86)))); + new OrPredicate(Platform::isAArch64, + new OrPredicate(Platform::isS390x, + new OrPredicate(Platform::isSparc, + new OrPredicate(Platform::isX64, Platform::isX86)))))); } @Override diff --git a/hotspot/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java b/hotspot/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java index 11792d73a1e..98612cdde42 100644 --- a/hotspot/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java +++ b/hotspot/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, 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,33 +59,35 @@ public class IntrinsicPredicates { }; public static final BooleanSupplier SHA1_INSTRUCTION_AVAILABLE - = new OrPredicate(new CPUSpecificPredicate("x86.*", new String[] { "sha" },null), - new OrPredicate(new CPUSpecificPredicate("amd64.*", new String[] { "sha" },null), - new OrPredicate(new CPUSpecificPredicate("i386.*", new String[] { "sha" },null), - new OrPredicate( - new CPUSpecificPredicate("sparc.*", new String[] { "sha1" },null), - new CPUSpecificPredicate("aarch64.*", new String[] { "sha1" },null))))); + = new OrPredicate(new CPUSpecificPredicate("aarch64.*", new String[] { "sha1" }, null), + new OrPredicate(new CPUSpecificPredicate("s390.*", new String[] { "sha1" }, null), + new OrPredicate(new CPUSpecificPredicate("sparc.*", new String[] { "sha1" }, null), + // x86 variants + new OrPredicate(new CPUSpecificPredicate("amd64.*", new String[] { "sha" }, null), + new OrPredicate(new CPUSpecificPredicate("i386.*", new String[] { "sha" }, null), + new CPUSpecificPredicate("x86.*", new String[] { "sha" }, null)))))); public static final BooleanSupplier SHA256_INSTRUCTION_AVAILABLE - = new OrPredicate(new CPUSpecificPredicate("x86.*", new String[] { "sha" },null), - new OrPredicate(new CPUSpecificPredicate("amd64.*", new String[] { "sha" },null), - new OrPredicate(new CPUSpecificPredicate("i386.*", new String[] { -"sha" },null), - new OrPredicate(new CPUSpecificPredicate("x86_64", new String[] { "avx2", "bmi2" }, null), - new OrPredicate(new CPUSpecificPredicate("amd64.*", new String[] { "avx2", "bmi2" }, null), - new OrPredicate( - new CPUSpecificPredicate("sparc.*", new String[] { "sha256" },null), - new CPUSpecificPredicate("aarch64.*", new String[] { "sha256" },null))))))); + = new OrPredicate(new CPUSpecificPredicate("aarch64.*", new String[] { "sha256" }, null), + new OrPredicate(new CPUSpecificPredicate("s390.*", new String[] { "sha256" }, null), + new OrPredicate(new CPUSpecificPredicate("sparc.*", new String[] { "sha256" }, null), + // x86 variants + new OrPredicate(new CPUSpecificPredicate("amd64.*", new String[] { "sha" }, null), + new OrPredicate(new CPUSpecificPredicate("i386.*", new String[] { "sha" }, null), + new OrPredicate(new CPUSpecificPredicate("x86.*", new String[] { "sha" }, null), + new OrPredicate(new CPUSpecificPredicate("amd64.*", new String[] { "avx2", "bmi2" }, null), + new CPUSpecificPredicate("x86_64", new String[] { "avx2", "bmi2" }, null)))))))); public static final BooleanSupplier SHA512_INSTRUCTION_AVAILABLE - = new OrPredicate(new CPUSpecificPredicate("x86.*", new String[] { "sha" },null), - new OrPredicate(new CPUSpecificPredicate("amd64.*", new String[] { "sha" },null), - new OrPredicate(new CPUSpecificPredicate("i386.*", new String[] { "sha" },null), - new OrPredicate(new CPUSpecificPredicate("x86_64", new String[] { "avx2", "bmi2" }, null), - new OrPredicate(new CPUSpecificPredicate("amd64.*", new String[] { "avx2", "bmi2" }, null), - new OrPredicate( - new CPUSpecificPredicate("sparc.*", new String[] { "sha512" },null), - new CPUSpecificPredicate("aarch64.*", new String[] { "sha512" },null))))))); + = new OrPredicate(new CPUSpecificPredicate("aarch64.*", new String[] { "sha512" }, null), + new OrPredicate(new CPUSpecificPredicate("s390.*", new String[] { "sha512" }, null), + new OrPredicate(new CPUSpecificPredicate("sparc.*", new String[] { "sha512" }, null), + // x86 variants + new OrPredicate(new CPUSpecificPredicate("amd64.*", new String[] { "sha" }, null), + new OrPredicate(new CPUSpecificPredicate("i386.*", new String[] { "sha" }, null), + new OrPredicate(new CPUSpecificPredicate("x86.*", new String[] { "sha" }, null), + new OrPredicate(new CPUSpecificPredicate("amd64.*", new String[] { "avx2", "bmi2" }, null), + new CPUSpecificPredicate("x86_64", new String[] { "avx2", "bmi2" }, null)))))))); public static final BooleanSupplier ANY_SHA_INSTRUCTION_AVAILABLE = new OrPredicate(IntrinsicPredicates.SHA1_INSTRUCTION_AVAILABLE, diff --git a/hotspot/test/test_env.sh b/hotspot/test/test_env.sh index 4814471b879..43d1a76ed92 100644 --- a/hotspot/test/test_env.sh +++ b/hotspot/test/test_env.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 2016, 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 @@ -204,6 +204,11 @@ if [ $? = 0 ] then VM_CPU="ia64" fi +grep "s390x" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_CPU="s390x" +fi grep "aarch64" vm_version.out > ${NULL} if [ $? = 0 ] then diff --git a/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java b/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java index 0d38e160684..43c9715a95e 100644 --- a/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java +++ b/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java @@ -45,7 +45,7 @@ import java.util.Set; */ public class TestMutuallyExclusivePlatformPredicates { private static enum MethodGroup { - ARCH("isARM", "isPPC", "isSparc", "isX86", "isX64", "isAArch64"), + ARCH("isAArch64", "isARM", "isPPC", "isS390x", "isSparc", "isX64", "isX86"), BITNESS("is32bit", "is64bit"), OS("isAix", "isLinux", "isOSX", "isSolaris", "isWindows"), VM_TYPE("isClient", "isServer", "isGraal", "isMinimal", "isZero", "isEmbedded"), From 902650f05865150d4b14d78005bc8737dfc9f4b4 Mon Sep 17 00:00:00 2001 From: Nils Eliasson Date: Tue, 1 Nov 2016 14:22:38 +0100 Subject: [PATCH 003/235] 8160543: C1: Crash in java.lang.String.indexOf in some java.sql tests C1 must use unverified entry point for unloaded methods. Reviewed-by: vlivanov, goetz --- hotspot/src/share/vm/c1/c1_GraphBuilder.cpp | 40 ++++++-------- hotspot/src/share/vm/c1/c1_LIRGenerator.cpp | 7 ++- hotspot/src/share/vm/code/compiledIC.cpp | 58 ++++++++------------- 3 files changed, 40 insertions(+), 65 deletions(-) diff --git a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp index b71a0b5ed10..9e63b641765 100644 --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp @@ -1813,14 +1813,10 @@ void GraphBuilder::invoke(Bytecodes::Code code) { ciKlass* holder = stream()->get_declared_method_holder(); const Bytecodes::Code bc_raw = stream()->cur_bc_raw(); assert(declared_signature != NULL, "cannot be null"); + assert(will_link == target->is_loaded(), ""); ciInstanceKlass* klass = target->holder(); - - // Make sure there are no evident problems with linking the instruction. - bool is_resolved = true; - if (klass->is_loaded() && !target->is_loaded()) { - is_resolved = false; // method not found - } + assert(!target->is_loaded() || klass->is_loaded(), "loaded target must imply loaded klass"); // check if CHA possible: if so, change the code to invoke_special ciInstanceKlass* calling_klass = method()->holder(); @@ -1868,7 +1864,7 @@ void GraphBuilder::invoke(Bytecodes::Code code) { ciMethod* cha_monomorphic_target = NULL; ciMethod* exact_target = NULL; Value better_receiver = NULL; - if (UseCHA && DeoptC1 && klass->is_loaded() && target->is_loaded() && + if (UseCHA && DeoptC1 && target->is_loaded() && !(// %%% FIXME: Are both of these relevant? target->is_method_handle_intrinsic() || target->is_compiled_lambda_form()) && @@ -1988,8 +1984,7 @@ void GraphBuilder::invoke(Bytecodes::Code code) { } // check if we could do inlining - if (!PatchALot && Inline && is_resolved && - klass->is_loaded() && target->is_loaded() && + if (!PatchALot && Inline && target->is_loaded() && (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized()) && !patch_for_appendix) { // callee is known => check if we have static binding @@ -2032,7 +2027,6 @@ void GraphBuilder::invoke(Bytecodes::Code code) { CHECK_BAILOUT(); // inlining not successful => standard invoke - bool is_loaded = target->is_loaded(); ValueType* result_type = as_ValueType(declared_signature->return_type()); ValueStack* state_before = copy_state_exhandling(); @@ -2049,7 +2043,7 @@ void GraphBuilder::invoke(Bytecodes::Code code) { // Currently only supported on Sparc. // The UseInlineCaches only controls dispatch to invokevirtuals for // loaded classes which we weren't able to statically bind. - if (!UseInlineCaches && is_resolved && is_loaded && code == Bytecodes::_invokevirtual + if (!UseInlineCaches && target->is_loaded() && code == Bytecodes::_invokevirtual && !target->can_be_statically_bound()) { // Find a vtable index if one is available // For arrays, callee_holder is Object. Resolving the call with @@ -2062,18 +2056,17 @@ void GraphBuilder::invoke(Bytecodes::Code code) { } #endif - if (is_resolved) { - // invokespecial always needs a NULL check. invokevirtual where the target is - // final or where it's not known whether the target is final requires a NULL check. - // Otherwise normal invokevirtual will perform the null check during the lookup - // logic or the unverified entry point. Profiling of calls requires that - // the null check is performed in all cases. - bool do_null_check = (recv != NULL) && - (code == Bytecodes::_invokespecial || !is_loaded || target->is_final() || (is_profiling() && profile_calls())); + // invokespecial always needs a NULL check. invokevirtual where the target is + // final or where it's not known whether the target is final requires a NULL check. + // Otherwise normal invokevirtual will perform the null check during the lookup + // logic or the unverified entry point. Profiling of calls requires that + // the null check is performed in all cases. - if (do_null_check) { - null_check(recv); - } + bool do_null_check = (recv != NULL) && + (code == Bytecodes::_invokespecial || (target->is_loaded() && (target->is_final() || (is_profiling() && profile_calls())))); + + if (do_null_check) { + null_check(recv); if (is_profiling()) { // Note that we'd collect profile data in this method if we wanted it. @@ -2090,9 +2083,6 @@ void GraphBuilder::invoke(Bytecodes::Code code) { profile_call(target, recv, target_klass, collect_args_for_profiling(args, NULL, false), false); } } - } else { - // No need in null check or profiling: linkage error will be thrown at runtime - // during resolution. } Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before); diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp index dd21475d30b..0c10e864e3f 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp @@ -2976,7 +2976,6 @@ void LIRGenerator::do_Invoke(Invoke* x) { } // emit invoke code - bool optimized = x->target_is_loaded() && x->target_is_final(); assert(receiver->is_illegal() || receiver->is_equal(LIR_Assembler::receiverOpr()), "must match"); // JSR 292 @@ -3001,9 +3000,9 @@ void LIRGenerator::do_Invoke(Invoke* x) { case Bytecodes::_invokespecial: case Bytecodes::_invokevirtual: case Bytecodes::_invokeinterface: - // for final target we still produce an inline cache, in order - // to be able to call mixed mode - if (x->code() == Bytecodes::_invokespecial || optimized) { + // for loaded and final (method or class) target we still produce an inline cache, + // in order to be able to call mixed mode + if (x->code() == Bytecodes::_invokespecial || x->target_is_final()) { __ call_opt_virtual(target, receiver, result_register, SharedRuntime::get_resolve_opt_virtual_call_stub(), arg_list, info); diff --git a/hotspot/src/share/vm/code/compiledIC.cpp b/hotspot/src/share/vm/code/compiledIC.cpp index 748589ef0a3..63e73ec23ec 100644 --- a/hotspot/src/share/vm/code/compiledIC.cpp +++ b/hotspot/src/share/vm/code/compiledIC.cpp @@ -460,9 +460,11 @@ void CompiledIC::set_to_monomorphic(CompiledICInfo& info) { } -// is_optimized: Compiler has generated an optimized call (i.e., no inline -// cache) static_bound: The call can be static bound (i.e, no need to use -// inline cache) +// is_optimized: Compiler has generated an optimized call (i.e. fixed, no inline cache) +// static_bound: The call can be static bound. If it isn't also optimized, the property +// wasn't provable at time of compilation. An optimized call will have any necessary +// null check, while a static_bound won't. A static_bound (but not optimized) must +// therefore use the unverified entry point. void CompiledIC::compute_monomorphic_entry(const methodHandle& method, KlassHandle receiver_klass, bool is_optimized, @@ -475,7 +477,23 @@ void CompiledIC::compute_monomorphic_entry(const methodHandle& method, if (method_code != NULL && method_code->is_in_use()) { assert(method_code->is_compiled(), "must be compiled"); // Call to compiled code - if (static_bound || is_optimized) { + // + // Note: the following problem exists with Compiler1: + // - at compile time we may or may not know if the destination is final + // - if we know that the destination is final (is_optimized), we will emit + // an optimized virtual call (no inline cache), and need a Method* to make + // a call to the interpreter + // - if we don't know if the destination is final, we emit a standard + // virtual call, and use CompiledICHolder to call interpreted code + // (no static call stub has been generated) + // - In the case that we here notice the call is static bound we + // convert the call into what looks to be an optimized virtual call, + // but we must use the unverified entry point (since there will be no + // null check on a call when the target isn't loaded). + // This causes problems when verifying the IC because + // it looks vanilla but is optimized. Code in is_call_to_interpreted + // is aware of this and weakens its asserts. + if (is_optimized) { entry = method_code->verified_entry_point(); } else { entry = method_code->entry_point(); @@ -485,38 +503,6 @@ void CompiledIC::compute_monomorphic_entry(const methodHandle& method, // Call to compiled code info.set_compiled_entry(entry, (static_bound || is_optimized) ? NULL : receiver_klass(), is_optimized); } else { - // Note: the following problem exists with Compiler1: - // - at compile time we may or may not know if the destination is final - // - if we know that the destination is final, we will emit an optimized - // virtual call (no inline cache), and need a Method* to make a call - // to the interpreter - // - if we do not know if the destination is final, we emit a standard - // virtual call, and use CompiledICHolder to call interpreted code - // (no static call stub has been generated) - // However in that case we will now notice it is static_bound - // and convert the call into what looks to be an optimized - // virtual call. This causes problems in verifying the IC because - // it look vanilla but is optimized. Code in is_call_to_interpreted - // is aware of this and weakens its asserts. - - // static_bound should imply is_optimized -- otherwise we have a - // performance bug (statically-bindable method is called via - // dynamically-dispatched call note: the reverse implication isn't - // necessarily true -- the call may have been optimized based on compiler - // analysis (static_bound is only based on "final" etc.) -#ifdef COMPILER2 -#ifdef TIERED -#if defined(ASSERT) - // can't check the assert because we don't have the CompiledIC with which to - // find the address if the call instruction. - // - // CodeBlob* cb = find_blob_unsafe(instruction_address()); - // assert(cb->is_compiled_by_c1() || !static_bound || is_optimized, "static_bound should imply is_optimized"); -#endif // ASSERT -#else - assert(!static_bound || is_optimized, "static_bound should imply is_optimized"); -#endif // TIERED -#endif // COMPILER2 if (is_optimized) { // Use stub entry info.set_interpreter_entry(method()->get_c2i_entry(), method()); From db9932fb371ab051916b8d3c2107e58cb945fd48 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Fri, 28 Oct 2016 15:50:09 +0200 Subject: [PATCH 004/235] 8168904: Initialize and reset G1 phase times to zero Reviewed-by: sjohanss, jprovino --- hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp | 40 +++++++++++++++++-- hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp | 1 + 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp index 194cd8f5f7c..963fe804c09 100644 --- a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp +++ b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp @@ -36,7 +36,9 @@ static const char* Indents[5] = {"", " ", " ", " ", " "}; G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) : - _max_gc_threads(max_gc_threads) + _max_gc_threads(max_gc_threads), + _gc_start_counter(0), + _gc_pause_time_ms(0.0) { assert(max_gc_threads > 0, "Must have some GC threads"); @@ -95,13 +97,40 @@ G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) : _gc_par_phases[NonYoungFreeCSet] = new WorkerDataArray(max_gc_threads, "Non-Young Free Collection Set (ms):"); _gc_par_phases[PreserveCMReferents] = new WorkerDataArray(max_gc_threads, "Parallel Preserve CM Refs (ms):"); + + reset(); } -void G1GCPhaseTimes::note_gc_start() { - _gc_start_counter = os::elapsed_counter(); +void G1GCPhaseTimes::reset() { + _cur_collection_par_time_ms = 0.0; + _cur_collection_code_root_fixup_time_ms = 0.0; + _cur_strong_code_root_purge_time_ms = 0.0; + _cur_evac_fail_recalc_used = 0.0; + _cur_evac_fail_restore_remsets = 0.0; + _cur_evac_fail_remove_self_forwards = 0.0; + _cur_string_dedup_fixup_time_ms = 0.0; + _cur_clear_ct_time_ms = 0.0; _cur_expand_heap_time_ms = 0.0; + _cur_ref_proc_time_ms = 0.0; + _cur_ref_enq_time_ms = 0.0; + _cur_collection_start_sec = 0.0; + _root_region_scan_wait_time_ms = 0.0; _external_accounted_time_ms = 0.0; _recorded_clear_claimed_marks_time_ms = 0.0; + _recorded_young_cset_choice_time_ms = 0.0; + _recorded_non_young_cset_choice_time_ms = 0.0; + _recorded_redirty_logged_cards_time_ms = 0.0; + _recorded_preserve_cm_referents_time_ms = 0.0; + _recorded_merge_pss_time_ms = 0.0; + _recorded_total_free_cset_time_ms = 0.0; + _recorded_serial_free_cset_time_ms = 0.0; + _cur_fast_reclaim_humongous_time_ms = 0.0; + _cur_fast_reclaim_humongous_register_time_ms = 0.0; + _cur_fast_reclaim_humongous_total = 0; + _cur_fast_reclaim_humongous_candidates = 0; + _cur_fast_reclaim_humongous_reclaimed = 0; + _cur_verify_before_time_ms = 0.0; + _cur_verify_after_time_ms = 0.0; for (int i = 0; i < GCParPhasesSentinel; i++) { if (_gc_par_phases[i] != NULL) { @@ -110,6 +139,11 @@ void G1GCPhaseTimes::note_gc_start() { } } +void G1GCPhaseTimes::note_gc_start() { + _gc_start_counter = os::elapsed_counter(); + reset(); +} + #define ASSERT_PHASE_UNINITIALIZED(phase) \ assert(_gc_par_phases[phase]->get(i) == uninitialized, "Phase " #phase " reported for thread that was not started"); diff --git a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp index 841756e3f66..9ee8e66a640 100644 --- a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp +++ b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp @@ -129,6 +129,7 @@ class G1GCPhaseTimes : public CHeapObj { double worker_time(GCParPhases phase, uint worker); void note_gc_end(); + void reset(); template void details(T* phase, const char* indent); From 1bab9425ed1a75fdc7b0b027e71dee701db53772 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Mon, 7 Nov 2016 17:02:46 +0100 Subject: [PATCH 005/235] 8169331: [JVMCI] incomplete API to MethodParameters attribute Reviewed-by: kvn --- .../HotSpotResolvedJavaMethodImpl.java | 3 +- .../jdk/vm/ci/meta/ResolvedJavaMethod.java | 33 ++++++++++++++++--- .../runtime/test/TestResolvedJavaMethod.java | 2 +- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java index eaace1b2331..e275b2ecaa5 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java @@ -472,7 +472,8 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp Parameter[] res = new Parameter[javaParameters.length]; for (int i = 0; i < res.length; i++) { java.lang.reflect.Parameter src = javaParameters[i]; - res[i] = new Parameter(src.getName(), src.getModifiers(), this, i); + String paramName = src.isNamePresent() ? src.getName() : null; + res[i] = new Parameter(paramName, src.getModifiers(), this, i); } return res; } diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java index 545b44bda75..6d13d911398 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java @@ -177,7 +177,7 @@ public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersP /** * A {@code Parameter} provides information about method parameters. */ - public static class Parameter implements AnnotatedElement { + class Parameter implements AnnotatedElement { private final String name; private final ResolvedJavaMethod method; private final int modifiers; @@ -186,7 +186,9 @@ public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersP /** * Constructor for {@code Parameter}. * - * @param name the name of the parameter + * @param name the name of the parameter or {@code null} if there is no + * {@literal MethodParameters} class file attribute providing a non-empty name + * for the parameter * @param modifiers the modifier flags for the parameter * @param method the method which defines this parameter * @param index the index of the parameter @@ -195,6 +197,7 @@ public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersP int modifiers, ResolvedJavaMethod method, int index) { + assert name == null || !name.isEmpty(); this.name = name; this.modifiers = modifiers; this.method = method; @@ -202,10 +205,20 @@ public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersP } /** - * Gets the name of the parameter. + * Gets the name of the parameter. If the parameter's name is {@linkplain #isNamePresent() + * present}, then this method returns the name provided by the class file. Otherwise, this + * method synthesizes a name of the form argN, where N is the index of the parameter in the + * descriptor of the method which declares the parameter. + * + * @return the name of the parameter, either provided by the class file or synthesized if + * the class file does not provide a name */ public String getName() { - return name; + if (name == null) { + return "arg" + index; + } else { + return name; + } } /** @@ -216,7 +229,7 @@ public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersP } /** - * Get the modifier flags for the parameter + * Get the modifier flags for the parameter. */ public int getModifiers() { return modifiers; @@ -243,6 +256,16 @@ public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersP return method.getSignature().getParameterType(index, method.getDeclaringClass()); } + /** + * Determines if the parameter has a name according to a {@literal MethodParameters} class + * file attribute. + * + * @return true if and only if the parameter has a name according to the class file. + */ + public boolean isNamePresent() { + return name != null; + } + /** * Determines if the parameter represents a variable argument list. */ diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java index e5dfb856580..0be4d5522fb 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java @@ -278,7 +278,7 @@ public class TestResolvedJavaMethod extends MethodUniverse { java.lang.reflect.Parameter exp = expected[i]; Parameter act = actual[i]; assertEquals(exp.getName(), act.getName()); - assertEquals(exp.getModifiers(), act.getModifiers()); + assertEquals(exp.isNamePresent(), act.isNamePresent()); assertEquals(exp.getModifiers(), act.getModifiers()); assertArrayEquals(exp.getAnnotations(), act.getAnnotations()); assertEquals(exp.getType().getName(), act.getType().toClassName()); From 2c79bd5892f13f30ee6c5dfdffa98958a9b3e366 Mon Sep 17 00:00:00 2001 From: Jini George Date: Wed, 9 Nov 2016 09:30:27 +0300 Subject: [PATCH 006/235] 7107018: sun.jvm.hotspot.utilities.soql.JSJavaHeap.forEachClass incorrect test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Correction for incorrect double checking of ‘k’ not being null. Reviewed-by: dsamersoff, rehn --- .../jvm/hotspot/utilities/soql/JSJavaHeap.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaHeap.java b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaHeap.java index 52e0412adf3..87e6688889f 100644 --- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaHeap.java +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaHeap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2016, 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 @@ -177,14 +177,14 @@ public class JSJavaHeap extends DefaultScriptObject { JSJavaObject k = jk.getJSJavaClass(); JSJavaObject l = factory.newJSJavaObject(loader); if (k != null) { - if (k != null) { - try { - finalFunc.call(new Object[] { k, l }); - } catch (ScriptException exp) { - throw new RuntimeException(exp); + if (l != null) { + try { + finalFunc.call(new Object[] { k, l }); + } catch (ScriptException exp) { + throw new RuntimeException(exp); + } + } } - } - } } }); From 3eedbd0f7338646ddb31c5e7f9beec559d606008 Mon Sep 17 00:00:00 2001 From: Jini George Date: Wed, 9 Nov 2016 10:56:32 +0300 Subject: [PATCH 007/235] 8169344: Potential open file descriptor in exists() of hotspot/agent/src/os/bsd/ps_core.c Use access() instead of open() to check for the existence of a file Reviewed-by: dsamersoff, dholmes --- .../macosx/native/libsaproc/ps_core.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/hotspot/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c b/hotspot/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c index 6e4c65ed4d2..b4dacf6e6ac 100644 --- a/hotspot/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c +++ b/hotspot/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -697,14 +697,8 @@ err: } /**local function **/ -bool exists(const char *fname) -{ - int fd; - if ((fd = open(fname, O_RDONLY)) > 0) { - close(fd); - return true; - } - return false; +bool exists(const char *fname) { + return access(fname, F_OK) == 0; } // we check: 1. lib From 9afb326e44bbc4659f0a8bb7b5f1ff0b4a1e4fa1 Mon Sep 17 00:00:00 2001 From: Sharath Ballal Date: Wed, 9 Nov 2016 13:38:52 +0530 Subject: [PATCH 008/235] 7107014: sun.jvm.hotspot.HSDB.FindObjectByTypeCleanupThunk.showConsole.attach infinite loop Avoid infinite loop in sun.jvm.hotspot.HSDB.FindObjectByTypeCleanupThunk.showConsole.attach Reviewed-by: rehn, dsamersoff --- .../jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java index 6b3455bdd2f..4a7094463d7 100644 --- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, 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 @@ -1474,7 +1474,7 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { return attached; } public void attach(String pid) { - attach(pid); + HSDB.this.attach(pid); } public void attach(String java, String core) { } From b49746775cd119ddf95e25d395b43166b20eddd6 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Fri, 7 Oct 2016 15:59:38 +0200 Subject: [PATCH 009/235] 8169497: Aarch64: Improve internal array handling Reviewed-by: aph --- .../aarch64/vm/c1_LIRAssembler_aarch64.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp index f4131ab5098..8740d2831ea 100644 --- a/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp +++ b/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp @@ -2249,6 +2249,25 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { __ cbz(dst, *stub->entry()); } + // If the compiler was not able to prove that exact type of the source or the destination + // of the arraycopy is an array type, check at runtime if the source or the destination is + // an instance type. + if (flags & LIR_OpArrayCopy::type_check) { + if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::dst_objarray)) { + __ load_klass(tmp, dst); + __ ldrw(rscratch1, Address(tmp, in_bytes(Klass::layout_helper_offset()))); + __ cmpw(rscratch1, Klass::_lh_neutral_value); + __ br(Assembler::GE, *stub->entry()); + } + + if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::src_objarray)) { + __ load_klass(tmp, src); + __ ldrw(rscratch1, Address(tmp, in_bytes(Klass::layout_helper_offset()))); + __ cmpw(rscratch1, Klass::_lh_neutral_value); + __ br(Assembler::GE, *stub->entry()); + } + } + // check if negative if (flags & LIR_OpArrayCopy::src_pos_positive_check) { __ cmpw(src_pos, 0); From 5ac345714ffdc82574172d0d4c8b83d7ed0245e2 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 31 Oct 2016 11:43:07 +0100 Subject: [PATCH 010/235] 8166837: [TESTBUG] Fix tests on Linux/s390x Reviewed-by: kvn, simonis --- test/lib/jdk/test/lib/Platform.java | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/test/lib/jdk/test/lib/Platform.java b/test/lib/jdk/test/lib/Platform.java index f648bfb670b..3f924371c43 100644 --- a/test/lib/jdk/test/lib/Platform.java +++ b/test/lib/jdk/test/lib/Platform.java @@ -160,9 +160,8 @@ public class Platform { return vmVersion; } - // Returns true for sparc and sparcv9. - public static boolean isSparc() { - return isArch("sparc.*"); + public static boolean isAArch64() { + return isArch("aarch64"); } public static boolean isARM() { @@ -173,9 +172,14 @@ public class Platform { return isArch("ppc.*"); } - public static boolean isX86() { - // On Linux it's 'i386', Windows 'x86' without '_64' suffix. - return isArch("(i386)|(x86(?!_64))"); + // Returns true for IBM z System running linux. + public static boolean isS390x() { + return isArch("s390.*") || isArch("s/390.*") || isArch("zArch_64"); + } + + // Returns true for sparc and sparcv9. + public static boolean isSparc() { + return isArch("sparc.*"); } public static boolean isX64() { @@ -183,8 +187,9 @@ public class Platform { return isArch("(amd64)|(x86_64)"); } - public static boolean isAArch64() { - return isArch("aarch64"); + public static boolean isX86() { + // On Linux it's 'i386', Windows 'x86' without '_64' suffix. + return isArch("(i386)|(x86(?!_64))"); } public static String getOsArch() { @@ -200,6 +205,7 @@ public class Platform { if (isAix()) { return false; // SA not implemented. } else if (isLinux()) { + if (isS390x()) { return false; } // SA not implemented. return canPtraceAttachLinux(); } else if (isOSX()) { return canAttachOSX(); From 04eb6a6783d18a7ed75acbe8f56054fc246d965d Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 31 Oct 2016 14:13:03 +0100 Subject: [PATCH 011/235] 8166837: [TESTBUG] Fix tests on Linux/s390x Reviewed-by: simonis --- jdk/test/java/awt/JAWT/JAWT.sh | 2 +- jdk/test/sun/tools/jhsdb/BasicLauncherTest.java | 5 ++--- jdk/test/sun/tools/jhsdb/HeapDumpTest.java | 5 ++--- jdk/test/sun/tools/jhsdb/heapconfig/JMapHeapConfigTest.java | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/jdk/test/java/awt/JAWT/JAWT.sh b/jdk/test/java/awt/JAWT/JAWT.sh index ab511d8a71e..d01ff022a42 100644 --- a/jdk/test/java/awt/JAWT/JAWT.sh +++ b/jdk/test/java/awt/JAWT/JAWT.sh @@ -122,7 +122,7 @@ esac # Skip unsupported platforms case `uname -m` in - arm* | ppc* ) + arm* | ppc* | s390* ) echo "Test passed. Not supported on current architecture." exit 0 ;; diff --git a/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java b/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java index 998e1b2eed2..9285044b358 100644 --- a/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java +++ b/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java @@ -44,7 +44,7 @@ import jdk.testlibrary.Utils; import jdk.testlibrary.OutputAnalyzer; import jdk.testlibrary.ProcessTools; import jdk.test.lib.apps.LingeredApp; -import jdk.testlibrary.Platform; +import jdk.test.lib.Platform; public class BasicLauncherTest { @@ -230,8 +230,7 @@ public class BasicLauncherTest { Arrays.asList(toolArgs)); } - public static void main(String[] args) - throws IOException { + public static void main(String[] args) throws Exception { if (!Platform.shouldSAAttach()) { // Silently skip the test if we don't have enough permissions to attach diff --git a/jdk/test/sun/tools/jhsdb/HeapDumpTest.java b/jdk/test/sun/tools/jhsdb/HeapDumpTest.java index 59772a3c421..bc1d6553885 100644 --- a/jdk/test/sun/tools/jhsdb/HeapDumpTest.java +++ b/jdk/test/sun/tools/jhsdb/HeapDumpTest.java @@ -41,7 +41,7 @@ import jdk.testlibrary.JDKToolLauncher; import jdk.testlibrary.OutputAnalyzer; import jdk.testlibrary.ProcessTools; import jdk.test.lib.apps.LingeredApp; -import jdk.testlibrary.Platform; +import jdk.test.lib.Platform; public class HeapDumpTest { @@ -109,8 +109,7 @@ public class HeapDumpTest { dump.delete(); } - public static void main(String[] args) - throws IOException { + public static void main(String[] args) throws Exception { if (!Platform.shouldSAAttach()) { // Silently skip the test if we don't have enough permissions to attach diff --git a/jdk/test/sun/tools/jhsdb/heapconfig/JMapHeapConfigTest.java b/jdk/test/sun/tools/jhsdb/heapconfig/JMapHeapConfigTest.java index 1f88fd325b1..75437fa4ed3 100644 --- a/jdk/test/sun/tools/jhsdb/heapconfig/JMapHeapConfigTest.java +++ b/jdk/test/sun/tools/jhsdb/heapconfig/JMapHeapConfigTest.java @@ -30,7 +30,7 @@ import java.util.Map; import jdk.test.lib.apps.LingeredApp; import jdk.testlibrary.Utils; -import jdk.testlibrary.Platform; +import jdk.test.lib.Platform; /* * @test From d19575bfaceb9076a5d4a0d6a8a7cd35cfbc9137 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Mon, 7 Nov 2016 10:38:42 +0100 Subject: [PATCH 012/235] 8167679: G1 phase logging is messy Reviewed-by: sjohanss, tschatzl --- hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp | 174 ++++++++++++------ hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp | 20 +- hotspot/test/gc/g1/TestGCLogMessages.java | 19 +- 3 files changed, 142 insertions(+), 71 deletions(-) diff --git a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp index 963fe804c09..2f7538f427d 100644 --- a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp +++ b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp @@ -218,7 +218,7 @@ size_t G1GCPhaseTimes::sum_thread_work_items(GCParPhases phase) { } template -void G1GCPhaseTimes::details(T* phase, const char* indent) { +void G1GCPhaseTimes::details(T* phase, const char* indent) const { Log(gc, phases, task) log; if (log.is_level(LogLevel::Trace)) { outputStream* trace_out = log.trace_stream(); @@ -227,7 +227,7 @@ void G1GCPhaseTimes::details(T* phase, const char* indent) { } } -void G1GCPhaseTimes::log_phase(WorkerDataArray* phase, uint indent, outputStream* out, bool print_sum) { +void G1GCPhaseTimes::log_phase(WorkerDataArray* phase, uint indent, outputStream* out, bool print_sum) const { out->print("%s", Indents[indent]); phase->print_summary_on(out, print_sum); details(phase, Indents[indent]); @@ -240,7 +240,7 @@ void G1GCPhaseTimes::log_phase(WorkerDataArray* phase, uint indent, outp } } -void G1GCPhaseTimes::debug_phase(WorkerDataArray* phase) { +void G1GCPhaseTimes::debug_phase(WorkerDataArray* phase) const { Log(gc, phases) log; if (log.is_level(LogLevel::Debug)) { ResourceMark rm; @@ -248,7 +248,7 @@ void G1GCPhaseTimes::debug_phase(WorkerDataArray* phase) { } } -void G1GCPhaseTimes::trace_phase(WorkerDataArray* phase, bool print_sum) { +void G1GCPhaseTimes::trace_phase(WorkerDataArray* phase, bool print_sum) const { Log(gc, phases) log; if (log.is_level(LogLevel::Trace)) { ResourceMark rm; @@ -256,37 +256,50 @@ void G1GCPhaseTimes::trace_phase(WorkerDataArray* phase, bool print_sum) } } -#define PHASE_DOUBLE_FORMAT "%s%s: %.1lfms" -#define PHASE_SIZE_FORMAT "%s%s: " SIZE_FORMAT +#define TIME_FORMAT "%.1lfms" -#define info_line(str, value) \ - log_info(gc, phases)(PHASE_DOUBLE_FORMAT, Indents[1], str, value); +void G1GCPhaseTimes::info_time(const char* name, double value) const { + log_info(gc, phases)("%s%s: " TIME_FORMAT, Indents[1], name, value); +} -#define debug_line(str, value) \ - log_debug(gc, phases)(PHASE_DOUBLE_FORMAT, Indents[2], str, value); +void G1GCPhaseTimes::debug_time(const char* name, double value) const { + log_debug(gc, phases)("%s%s: " TIME_FORMAT, Indents[2], name, value); +} -#define trace_line(str, value) \ - log_trace(gc, phases)(PHASE_DOUBLE_FORMAT, Indents[3], str, value); +void G1GCPhaseTimes::trace_time(const char* name, double value) const { + log_trace(gc, phases)("%s%s: " TIME_FORMAT, Indents[3], name, value); +} -#define trace_line_sz(str, value) \ - log_trace(gc, phases)(PHASE_SIZE_FORMAT, Indents[3], str, value); +void G1GCPhaseTimes::trace_count(const char* name, size_t value) const { + log_trace(gc, phases)("%s%s: " SIZE_FORMAT, Indents[3], name, value); +} -#define trace_line_ms(str, value) \ - log_trace(gc, phases)(PHASE_SIZE_FORMAT, Indents[3], str, value); +double G1GCPhaseTimes::print_pre_evacuate_collection_set() const { + const double sum_ms = _root_region_scan_wait_time_ms + + _recorded_young_cset_choice_time_ms + + _recorded_non_young_cset_choice_time_ms + + _cur_fast_reclaim_humongous_register_time_ms; -#define info_line_and_account(str, value) \ - info_line(str, value); \ - accounted_time_ms += value; + info_time("Pre Evacuate Collection Set", sum_ms); -void G1GCPhaseTimes::print() { - note_gc_end(); - - double accounted_time_ms = _external_accounted_time_ms; if (_root_region_scan_wait_time_ms > 0.0) { - info_line_and_account("Root Region Scan Waiting", _root_region_scan_wait_time_ms); + debug_time("Root Region Scan Waiting", _root_region_scan_wait_time_ms); + } + debug_time("Choose Collection Set", (_recorded_young_cset_choice_time_ms + _recorded_non_young_cset_choice_time_ms)); + if (G1EagerReclaimHumongousObjects) { + debug_time("Humongous Register", _cur_fast_reclaim_humongous_register_time_ms); + trace_count("Humongous Total", _cur_fast_reclaim_humongous_total); + trace_count("Humongous Candidate", _cur_fast_reclaim_humongous_candidates); } - info_line_and_account("Evacuate Collection Set", _cur_collection_par_time_ms); + return sum_ms; +} + +double G1GCPhaseTimes::print_evacuate_collection_set() const { + const double sum_ms = _cur_collection_par_time_ms; + + info_time("Evacuate Collection Set", sum_ms); + trace_phase(_gc_par_phases[GCWorkerStart], false); debug_phase(_gc_par_phases[ExtRootScan]); for (int i = ThreadRoots; i <= SATBFiltering; i++) { @@ -304,57 +317,98 @@ void G1GCPhaseTimes::print() { debug_phase(_gc_par_phases[GCWorkerTotal]); trace_phase(_gc_par_phases[GCWorkerEnd], false); - info_line_and_account("Code Roots", _cur_collection_code_root_fixup_time_ms + _cur_strong_code_root_purge_time_ms); - debug_line("Code Roots Fixup", _cur_collection_code_root_fixup_time_ms); - debug_line("Code Roots Purge", _cur_strong_code_root_purge_time_ms); + return sum_ms; +} + +double G1GCPhaseTimes::print_post_evacuate_collection_set() const { + const double evac_fail_handling = _cur_evac_fail_recalc_used + + _cur_evac_fail_remove_self_forwards + + _cur_evac_fail_restore_remsets; + const double sum_ms = evac_fail_handling + + _cur_collection_code_root_fixup_time_ms + + _recorded_preserve_cm_referents_time_ms + + _cur_ref_proc_time_ms + + _cur_ref_enq_time_ms + + _cur_clear_ct_time_ms + + _recorded_merge_pss_time_ms + + _cur_strong_code_root_purge_time_ms + + _recorded_redirty_logged_cards_time_ms + + _recorded_clear_claimed_marks_time_ms + + _recorded_total_free_cset_time_ms + + _cur_fast_reclaim_humongous_time_ms + + _cur_expand_heap_time_ms + + _cur_string_dedup_fixup_time_ms; + + info_time("Post Evacuate Collection Set", sum_ms); + + debug_time("Code Roots Fixup", _cur_collection_code_root_fixup_time_ms); + + debug_time("Preserve CM Refs", _recorded_preserve_cm_referents_time_ms); + trace_phase(_gc_par_phases[PreserveCMReferents]); + + debug_time("Reference Processing", _cur_ref_proc_time_ms); if (G1StringDedup::is_enabled()) { - info_line_and_account("String Dedup Fixup", _cur_string_dedup_fixup_time_ms); + debug_time("String Dedup Fixup", _cur_string_dedup_fixup_time_ms); debug_phase(_gc_par_phases[StringDedupQueueFixup]); debug_phase(_gc_par_phases[StringDedupTableFixup]); } - info_line_and_account("Clear Card Table", _cur_clear_ct_time_ms); - info_line_and_account("Expand Heap After Collection", _cur_expand_heap_time_ms); - info_line_and_account("Free Collection Set", _recorded_total_free_cset_time_ms); - debug_line("Free Collection Set Serial", _recorded_serial_free_cset_time_ms); - debug_phase(_gc_par_phases[YoungFreeCSet]); - debug_phase(_gc_par_phases[NonYoungFreeCSet]); + debug_time("Clear Card Table", _cur_clear_ct_time_ms); - info_line_and_account("Merge Per-Thread State", _recorded_merge_pss_time_ms); - - info_line("Other", _gc_pause_time_ms - accounted_time_ms); - if (_cur_verify_before_time_ms > 0.0) { - debug_line("Verify Before", _cur_verify_before_time_ms); - } if (G1CollectedHeap::heap()->evacuation_failed()) { - double evac_fail_handling = _cur_evac_fail_recalc_used + _cur_evac_fail_remove_self_forwards + - _cur_evac_fail_restore_remsets; - debug_line("Evacuation Failure", evac_fail_handling); - trace_line("Recalculate Used", _cur_evac_fail_recalc_used); - trace_line("Remove Self Forwards",_cur_evac_fail_remove_self_forwards); - trace_line("Restore RemSet", _cur_evac_fail_restore_remsets); + debug_time("Evacuation Failure", evac_fail_handling); + trace_time("Recalculate Used", _cur_evac_fail_recalc_used); + trace_time("Remove Self Forwards",_cur_evac_fail_remove_self_forwards); + trace_time("Restore RemSet", _cur_evac_fail_restore_remsets); } - debug_line("Choose CSet", (_recorded_young_cset_choice_time_ms + _recorded_non_young_cset_choice_time_ms)); - debug_line("Preserve CM Refs", _recorded_preserve_cm_referents_time_ms); - trace_phase(_gc_par_phases[PreserveCMReferents]); - debug_line("Reference Processing", _cur_ref_proc_time_ms); - debug_line("Reference Enqueuing", _cur_ref_enq_time_ms); - debug_line("Redirty Cards", _recorded_redirty_logged_cards_time_ms); + + debug_time("Reference Enqueuing", _cur_ref_enq_time_ms); + + debug_time("Merge Per-Thread State", _recorded_merge_pss_time_ms); + debug_time("Code Roots Purge", _cur_strong_code_root_purge_time_ms); + + debug_time("Redirty Cards", _recorded_redirty_logged_cards_time_ms); if (_recorded_clear_claimed_marks_time_ms > 0.0) { - debug_line("Clear Claimed Marks", _recorded_clear_claimed_marks_time_ms); + debug_time("Clear Claimed Marks", _recorded_clear_claimed_marks_time_ms); } trace_phase(_gc_par_phases[RedirtyCards]); + + debug_time("Free Collection Set", _recorded_total_free_cset_time_ms); + trace_time("Free Collection Set Serial", _recorded_serial_free_cset_time_ms); + trace_phase(_gc_par_phases[YoungFreeCSet]); + trace_phase(_gc_par_phases[NonYoungFreeCSet]); + if (G1EagerReclaimHumongousObjects) { - debug_line("Humongous Register", _cur_fast_reclaim_humongous_register_time_ms); - trace_line_sz("Humongous Total", _cur_fast_reclaim_humongous_total); - trace_line_sz("Humongous Candidate", _cur_fast_reclaim_humongous_candidates); - debug_line("Humongous Reclaim", _cur_fast_reclaim_humongous_time_ms); - trace_line_sz("Humongous Reclaimed", _cur_fast_reclaim_humongous_reclaimed); + debug_time("Humongous Reclaim", _cur_fast_reclaim_humongous_time_ms); + trace_count("Humongous Reclaimed", _cur_fast_reclaim_humongous_reclaimed); } + debug_time("Expand Heap After Collection", _cur_expand_heap_time_ms); + + + return sum_ms; +} + +void G1GCPhaseTimes::print_other(double accounted_ms) const { + info_time("Other", _gc_pause_time_ms - accounted_ms); +} + +void G1GCPhaseTimes::print() { + note_gc_end(); + + if (_cur_verify_before_time_ms > 0.0) { + debug_time("Verify Before", _cur_verify_before_time_ms); + } + + double accounted_ms = 0.0; + accounted_ms += print_pre_evacuate_collection_set(); + accounted_ms += print_evacuate_collection_set(); + accounted_ms += print_post_evacuate_collection_set(); + print_other(accounted_ms); + if (_cur_verify_after_time_ms > 0.0) { - debug_line("Verify After", _cur_verify_after_time_ms); + debug_time("Verify After", _cur_verify_after_time_ms); } } diff --git a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp index 9ee8e66a640..b8865c55da7 100644 --- a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp +++ b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp @@ -25,6 +25,7 @@ #ifndef SHARE_VM_GC_G1_G1GCPHASETIMES_HPP #define SHARE_VM_GC_G1_G1GCPHASETIMES_HPP +#include "logging/logLevel.hpp" #include "memory/allocation.hpp" class LineBuffer; @@ -132,10 +133,21 @@ class G1GCPhaseTimes : public CHeapObj { void reset(); template - void details(T* phase, const char* indent); - void log_phase(WorkerDataArray* phase, uint indent, outputStream* out, bool print_sum); - void debug_phase(WorkerDataArray* phase); - void trace_phase(WorkerDataArray* phase, bool print_sum = true); + void details(T* phase, const char* indent) const; + + void log_phase(WorkerDataArray* phase, uint indent, outputStream* out, bool print_sum) const; + void debug_phase(WorkerDataArray* phase) const; + void trace_phase(WorkerDataArray* phase, bool print_sum = true) const; + + void info_time(const char* name, double value) const; + void debug_time(const char* name, double value) const; + void trace_time(const char* name, double value) const; + void trace_count(const char* name, size_t value) const; + + double print_pre_evacuate_collection_set() const; + double print_evacuate_collection_set() const; + double print_post_evacuate_collection_set() const; + void print_other(double accounted_ms) const; public: G1GCPhaseTimes(uint max_gc_threads); diff --git a/hotspot/test/gc/g1/TestGCLogMessages.java b/hotspot/test/gc/g1/TestGCLogMessages.java index 5d6ddba0873..49d9d9f5d1a 100644 --- a/hotspot/test/gc/g1/TestGCLogMessages.java +++ b/hotspot/test/gc/g1/TestGCLogMessages.java @@ -73,6 +73,11 @@ public class TestGCLogMessages { }; private LogMessageWithLevel allLogMessages[] = new LogMessageWithLevel[] { + new LogMessageWithLevel("Pre Evacuate Collection Set", Level.INFO), + new LogMessageWithLevel("Evacuate Collection Set", Level.INFO), + new LogMessageWithLevel("Post Evacuate Collection Set", Level.INFO), + new LogMessageWithLevel("Other", Level.INFO), + // Update RS new LogMessageWithLevel("Scan HCC", Level.TRACE), // Ext Root Scan @@ -96,20 +101,20 @@ public class TestGCLogMessages { new LogMessageWithLevel("Redirtied Cards", Level.TRACE), // Misc Top-level new LogMessageWithLevel("Code Roots Purge", Level.DEBUG), - new LogMessageWithLevel("String Dedup Fixup", Level.INFO), - new LogMessageWithLevel("Expand Heap After Collection", Level.INFO), + new LogMessageWithLevel("String Dedup Fixup", Level.DEBUG), + new LogMessageWithLevel("Expand Heap After Collection", Level.DEBUG), // Free CSet - new LogMessageWithLevel("Free Collection Set", Level.INFO), - new LogMessageWithLevel("Free Collection Set Serial", Level.DEBUG), - new LogMessageWithLevel("Young Free Collection Set", Level.DEBUG), - new LogMessageWithLevel("Non-Young Free Collection Set", Level.DEBUG), + new LogMessageWithLevel("Free Collection Set", Level.DEBUG), + new LogMessageWithLevel("Free Collection Set Serial", Level.TRACE), + new LogMessageWithLevel("Young Free Collection Set", Level.TRACE), + new LogMessageWithLevel("Non-Young Free Collection Set", Level.TRACE), // Humongous Eager Reclaim new LogMessageWithLevel("Humongous Reclaim", Level.DEBUG), new LogMessageWithLevel("Humongous Register", Level.DEBUG), // Preserve CM Referents new LogMessageWithLevel("Preserve CM Refs", Level.DEBUG), // Merge PSS - new LogMessageWithLevel("Merge Per-Thread State", Level.INFO), + new LogMessageWithLevel("Merge Per-Thread State", Level.DEBUG), }; void checkMessagesAtLevel(OutputAnalyzer output, LogMessageWithLevel messages[], Level level) throws Exception { From c372aca124ffbdbc8b189bff9129a925bf64237d Mon Sep 17 00:00:00 2001 From: Razvan A Lupusoru Date: Wed, 9 Nov 2016 10:21:56 -0800 Subject: [PATCH 013/235] 8167067: Fix x86 SHA instructions to be non Vex encoded Reviewed-by: kvn --- hotspot/src/cpu/x86/vm/assembler_x86.cpp | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.cpp b/hotspot/src/cpu/x86/vm/assembler_x86.cpp index eb016ad6844..c819ffe9462 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp @@ -4285,8 +4285,7 @@ void Assembler::pblendw(XMMRegister dst, XMMRegister src, int imm8) { void Assembler::sha1rnds4(XMMRegister dst, XMMRegister src, int imm8) { assert(VM_Version::supports_sha(), ""); - InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false); - int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F_3A, &attributes); + int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3A, /* rex_w */ false); emit_int8((unsigned char)0xCC); emit_int8((unsigned char)(0xC0 | encode)); emit_int8((unsigned char)imm8); @@ -4294,24 +4293,21 @@ void Assembler::sha1rnds4(XMMRegister dst, XMMRegister src, int imm8) { void Assembler::sha1nexte(XMMRegister dst, XMMRegister src) { assert(VM_Version::supports_sha(), ""); - InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false); - int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes); + int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, /* rex_w */ false); emit_int8((unsigned char)0xC8); emit_int8((unsigned char)(0xC0 | encode)); } void Assembler::sha1msg1(XMMRegister dst, XMMRegister src) { assert(VM_Version::supports_sha(), ""); - InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false); - int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes); + int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, /* rex_w */ false); emit_int8((unsigned char)0xC9); emit_int8((unsigned char)(0xC0 | encode)); } void Assembler::sha1msg2(XMMRegister dst, XMMRegister src) { assert(VM_Version::supports_sha(), ""); - InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false); - int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes); + int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, /* rex_w */ false); emit_int8((unsigned char)0xCA); emit_int8((unsigned char)(0xC0 | encode)); } @@ -4319,24 +4315,21 @@ void Assembler::sha1msg2(XMMRegister dst, XMMRegister src) { // xmm0 is implicit additional source to this instruction. void Assembler::sha256rnds2(XMMRegister dst, XMMRegister src) { assert(VM_Version::supports_sha(), ""); - InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false); - int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes); + int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, /* rex_w */ false); emit_int8((unsigned char)0xCB); emit_int8((unsigned char)(0xC0 | encode)); } void Assembler::sha256msg1(XMMRegister dst, XMMRegister src) { assert(VM_Version::supports_sha(), ""); - InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false); - int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes); + int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, /* rex_w */ false); emit_int8((unsigned char)0xCC); emit_int8((unsigned char)(0xC0 | encode)); } void Assembler::sha256msg2(XMMRegister dst, XMMRegister src) { assert(VM_Version::supports_sha(), ""); - InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false); - int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes); + int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, /* rex_w */ false); emit_int8((unsigned char)0xCD); emit_int8((unsigned char)(0xC0 | encode)); } From df8bbfafc7f3ad38bd44b0f0b2f2b6d5199a700b Mon Sep 17 00:00:00 2001 From: Nils Eliasson Date: Thu, 10 Nov 2016 18:08:31 +0100 Subject: [PATCH 014/235] 8167656: Unstable MethodHandle inlining causing huge performance variations Profile calls without a reciever Reviewed-by: jrose, vlivanov, kvn --- hotspot/src/share/vm/c1/c1_GraphBuilder.cpp | 27 ++++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp index 9e63b641765..75a4f8aa3de 100644 --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp @@ -2056,17 +2056,26 @@ void GraphBuilder::invoke(Bytecodes::Code code) { } #endif - // invokespecial always needs a NULL check. invokevirtual where the target is - // final or where it's not known whether the target is final requires a NULL check. - // Otherwise normal invokevirtual will perform the null check during the lookup - // logic or the unverified entry point. Profiling of calls requires that - // the null check is performed in all cases. + // A null check is required here (when there is a receiver) for any of the following cases + // - invokespecial, always need a null check. + // - invokevirtual, when the target is final and loaded. Calls to final targets will become optimized + // and require null checking. If the target is loaded a null check is emitted here. + // If the target isn't loaded the null check must happen after the call resolution. We achieve that + // by using the target methods unverified entry point (see CompiledIC::compute_monomorphic_entry). + // (The JVM specification requires that LinkageError must be thrown before a NPE. An unloaded target may + // potentially fail, and can't have the null check before the resolution.) + // - A call that will be profiled. (But we can't add a null check when the target is unloaded, by the same + // reason as above, so calls with a receiver to unloaded targets can't be profiled.) + // + // Normal invokevirtual will perform the null check during lookup - bool do_null_check = (recv != NULL) && - (code == Bytecodes::_invokespecial || (target->is_loaded() && (target->is_final() || (is_profiling() && profile_calls())))); + bool need_null_check = (code == Bytecodes::_invokespecial) || + (target->is_loaded() && (target->is_final_method() || (is_profiling() && profile_calls()))); - if (do_null_check) { - null_check(recv); + if (need_null_check) { + if (recv != NULL) { + null_check(recv); + } if (is_profiling()) { // Note that we'd collect profile data in this method if we wanted it. From 72d04ec80a958fda187f1ebb261d51a185bd038e Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Thu, 10 Nov 2016 13:08:02 -0800 Subject: [PATCH 015/235] 8169554: [JVMCI] expose missing StubRoutines for intrinsics Reviewed-by: kvn --- hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp index 0117b4b9d93..ce712dc061e 100644 --- a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp +++ b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp @@ -280,8 +280,25 @@ static_field(StubRoutines, _aescrypt_decryptBlock, address) \ static_field(StubRoutines, _cipherBlockChaining_encryptAESCrypt, address) \ static_field(StubRoutines, _cipherBlockChaining_decryptAESCrypt, address) \ + static_field(StubRoutines, _counterMode_AESCrypt, address) \ + static_field(StubRoutines, _ghash_processBlocks, address) \ + static_field(StubRoutines, _sha1_implCompress, address) \ + static_field(StubRoutines, _sha1_implCompressMB, address) \ + static_field(StubRoutines, _sha256_implCompress, address) \ + static_field(StubRoutines, _sha256_implCompressMB, address) \ + static_field(StubRoutines, _sha512_implCompress, address) \ + static_field(StubRoutines, _sha512_implCompressMB, address) \ static_field(StubRoutines, _updateBytesCRC32, address) \ static_field(StubRoutines, _crc_table_adr, address) \ + static_field(StubRoutines, _crc32c_table_addr, address) \ + static_field(StubRoutines, _updateBytesCRC32C, address) \ + static_field(StubRoutines, _updateBytesAdler32, address) \ + static_field(StubRoutines, _multiplyToLen, address) \ + static_field(StubRoutines, _squareToLen, address) \ + static_field(StubRoutines, _mulAdd, address) \ + static_field(StubRoutines, _montgomeryMultiply, address) \ + static_field(StubRoutines, _montgomerySquare, address) \ + static_field(StubRoutines, _vectorizedMismatch, address) \ \ nonstatic_field(Thread, _tlab, ThreadLocalAllocBuffer) \ nonstatic_field(Thread, _allocated_bytes, jlong) \ From c5b56dab55bf49e803374a2edd4151b20b1008ed Mon Sep 17 00:00:00 2001 From: Rahul Raghavan Date: Thu, 10 Nov 2016 23:26:56 -0800 Subject: [PATCH 016/235] 8169201: Montgomery multiply intrinsic should use correct name Corrected stubName to montgomery_multiply for inline_montgomeryMultiply() Reviewed-by: aph, thartmann, zmajo --- hotspot/src/share/vm/opto/library_call.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index 73227150602..c298e318ab5 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -5513,7 +5513,7 @@ bool LibraryCallKit::inline_montgomeryMultiply() { } assert(UseMontgomeryMultiplyIntrinsic, "not implemented on this platform"); - const char* stubName = "montgomery_square"; + const char* stubName = "montgomery_multiply"; assert(callee()->signature()->size() == 7, "montgomeryMultiply has 7 parameters"); From 003b7aba4877abd91c6b7d578e3a698fb8bc2286 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 7 Nov 2016 12:37:28 +0100 Subject: [PATCH 017/235] 8169317: [s390] Various minor bug fixes and adaptions Reviewed-by: mdoerr --- .../src/cpu/s390/vm/c1_LIRAssembler_s390.cpp | 3 +- hotspot/src/cpu/s390/vm/frame_s390.cpp | 2 +- hotspot/src/cpu/s390/vm/frame_s390.inline.hpp | 2 +- hotspot/src/cpu/s390/vm/globals_s390.hpp | 3 -- .../src/cpu/s390/vm/macroAssembler_s390.hpp | 1 + hotspot/src/cpu/s390/vm/nativeInst_s390.cpp | 34 ++++++++----------- hotspot/src/cpu/s390/vm/relocInfo_s390.cpp | 7 ++-- hotspot/src/cpu/s390/vm/s390.ad | 9 ++--- .../src/cpu/s390/vm/templateTable_s390.cpp | 6 ++-- hotspot/src/cpu/s390/vm/vm_version_s390.cpp | 28 +++++++++++++-- .../os_cpu/linux_s390/vm/os_linux_s390.cpp | 9 ++++- 11 files changed, 60 insertions(+), 44 deletions(-) diff --git a/hotspot/src/cpu/s390/vm/c1_LIRAssembler_s390.cpp b/hotspot/src/cpu/s390/vm/c1_LIRAssembler_s390.cpp index b7d50636a89..c367b8efb6d 100644 --- a/hotspot/src/cpu/s390/vm/c1_LIRAssembler_s390.cpp +++ b/hotspot/src/cpu/s390/vm/c1_LIRAssembler_s390.cpp @@ -1075,8 +1075,7 @@ void LIR_Assembler::reg2mem(LIR_Opr from, LIR_Opr dest_opr, BasicType type, { if (UseCompressedOops && !wide) { Register compressed_src = Z_R14; - __ z_lgr(compressed_src, from->as_register()); - __ encode_heap_oop(compressed_src); + __ oop_encoder(compressed_src, from->as_register(), true, (disp_reg != Z_R1) ? Z_R1 : Z_R0, -1, true); offset = code_offset(); if (short_disp) { __ z_st(compressed_src, disp_value, disp_reg, dest); diff --git a/hotspot/src/cpu/s390/vm/frame_s390.cpp b/hotspot/src/cpu/s390/vm/frame_s390.cpp index 89a45c5f075..bf5cc5fc207 100644 --- a/hotspot/src/cpu/s390/vm/frame_s390.cpp +++ b/hotspot/src/cpu/s390/vm/frame_s390.cpp @@ -156,7 +156,7 @@ void frame::patch_pc(Thread* thread, address pc) { } own_abi()->return_pc = (uint64_t)pc; _cb = CodeCache::find_blob(pc); - address original_pc = nmethod::get_deopt_original_pc(this); + address original_pc = CompiledMethod::get_deopt_original_pc(this); if (original_pc != NULL) { assert(original_pc == _pc, "expected original to be stored before patching"); _deopt_state = is_deoptimized; diff --git a/hotspot/src/cpu/s390/vm/frame_s390.inline.hpp b/hotspot/src/cpu/s390/vm/frame_s390.inline.hpp index 9f56814d074..3231daf94d5 100644 --- a/hotspot/src/cpu/s390/vm/frame_s390.inline.hpp +++ b/hotspot/src/cpu/s390/vm/frame_s390.inline.hpp @@ -39,7 +39,7 @@ inline void frame::find_codeblob_and_set_pc_and_deopt_state(address pc) { _fp = (intptr_t *) own_abi()->callers_sp; - address original_pc = nmethod::get_deopt_original_pc(this); + address original_pc = CompiledMethod::get_deopt_original_pc(this); if (original_pc != NULL) { _pc = original_pc; _deopt_state = is_deoptimized; diff --git a/hotspot/src/cpu/s390/vm/globals_s390.hpp b/hotspot/src/cpu/s390/vm/globals_s390.hpp index 707534ac831..fcd3ff45227 100644 --- a/hotspot/src/cpu/s390/vm/globals_s390.hpp +++ b/hotspot/src/cpu/s390/vm/globals_s390.hpp @@ -92,9 +92,6 @@ define_pd_global(intx, InitArrayShortSize, 1*BytesPerLong); product(bool, ReoptimizeCallSequences, true, \ "Reoptimize code-sequences of calls at runtime.") \ \ - product(bool, UseCountLeadingZerosInstruction, true, \ - "Use count leading zeros instruction.") \ - \ product(bool, UseByteReverseInstruction, true, \ "Use byte reverse instruction.") \ \ diff --git a/hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp b/hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp index 73a981863bb..c9540860958 100644 --- a/hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp +++ b/hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp @@ -574,6 +574,7 @@ class MacroAssembler: public Assembler { static int call_far_patchable_ret_addr_offset() { return call_far_patchable_size(); } static bool call_far_patchable_requires_alignment_nop(address pc) { + if (!os::is_MP()) return false; int size = call_far_patchable_size(); return ((intptr_t)(pc + size) & 0x03L) != 0; } diff --git a/hotspot/src/cpu/s390/vm/nativeInst_s390.cpp b/hotspot/src/cpu/s390/vm/nativeInst_s390.cpp index d84785b0793..6d3eccd5aab 100644 --- a/hotspot/src/cpu/s390/vm/nativeInst_s390.cpp +++ b/hotspot/src/cpu/s390/vm/nativeInst_s390.cpp @@ -256,11 +256,7 @@ void NativeFarCall::verify() { address NativeFarCall::destination() { assert(MacroAssembler::is_call_far_patchable_at((address)this), "unexpected call type"); address ctable = NULL; - if (MacroAssembler::call_far_patchable_requires_alignment_nop((address)this)) { - return MacroAssembler::get_dest_of_call_far_patchable_at(((address)this)+MacroAssembler::nop_size(), ctable); - } else { - return MacroAssembler::get_dest_of_call_far_patchable_at((address)this, ctable); - } + return MacroAssembler::get_dest_of_call_far_patchable_at((address)this, ctable); } @@ -610,20 +606,20 @@ void NativeMovRegMem::verify() { unsigned long inst1; Assembler::get_instruction(l2, &inst1); - if (!Assembler::is_z_lb(inst1) && - !Assembler::is_z_llgh(inst1) && - !Assembler::is_z_lh(inst1) && - !Assembler::is_z_l(inst1) && - !Assembler::is_z_llgf(inst1) && - !Assembler::is_z_lg(inst1) && - !Assembler::is_z_le(inst1) && - !Assembler::is_z_ld(inst1) && - !Assembler::is_z_stc(inst1) && - !Assembler::is_z_sth(inst1) && - !Assembler::is_z_st(inst1) && - !(Assembler::is_z_lgr(inst1) && UseCompressedOops) && - !Assembler::is_z_stg(inst1) && - !Assembler::is_z_ste(inst1) && + if (!Assembler::is_z_lb(inst1) && + !Assembler::is_z_llgh(inst1) && + !Assembler::is_z_lh(inst1) && + !Assembler::is_z_l(inst1) && + !Assembler::is_z_llgf(inst1) && + !Assembler::is_z_lg(inst1) && + !Assembler::is_z_le(inst1) && + !Assembler::is_z_ld(inst1) && + !Assembler::is_z_stc(inst1) && + !Assembler::is_z_sth(inst1) && + !Assembler::is_z_st(inst1) && + !UseCompressedOops && + !Assembler::is_z_stg(inst1) && + !Assembler::is_z_ste(inst1) && !Assembler::is_z_std(inst1)) { tty->cr(); tty->print_cr("NativeMovRegMem::verify(): verifying addr " PTR_FORMAT diff --git a/hotspot/src/cpu/s390/vm/relocInfo_s390.cpp b/hotspot/src/cpu/s390/vm/relocInfo_s390.cpp index 5ac592934d3..fd1437c1d69 100644 --- a/hotspot/src/cpu/s390/vm/relocInfo_s390.cpp +++ b/hotspot/src/cpu/s390/vm/relocInfo_s390.cpp @@ -102,11 +102,8 @@ address Relocation::pd_call_destination(address orig_addr) { if (orig_addr == NULL) { call = nativeFarCall_at(inst_addr); } else { - if (MacroAssembler::is_call_far_patchable_pcrelative_at(inst_addr)) { - call = nativeFarCall_at(orig_addr); - } else { - call = nativeFarCall_at(orig_addr); // must access location (in CP) where destination is stored in unmoved code, because load from CP is pc-relative - } + // must access location (in CP) where destination is stored in unmoved code, because load from CP is pc-relative + call = nativeFarCall_at(orig_addr); } return call->destination(); } diff --git a/hotspot/src/cpu/s390/vm/s390.ad b/hotspot/src/cpu/s390/vm/s390.ad index 9385cbc72c5..f242833ca46 100644 --- a/hotspot/src/cpu/s390/vm/s390.ad +++ b/hotspot/src/cpu/s390/vm/s390.ad @@ -1489,8 +1489,8 @@ const bool Matcher::match_rule_supported(int opcode) { case Op_CountLeadingZerosL: case Op_CountTrailingZerosI: case Op_CountTrailingZerosL: - // Implementation requires FLOGR instruction. - return UseCountLeadingZerosInstruction; + // Implementation requires FLOGR instruction, which is available since z9. + return true; case Op_ReverseBytesI: case Op_ReverseBytesL: @@ -9897,7 +9897,6 @@ instruct string_compareUL(iRegP str1, iRegP str2, rarg2RegI cnt1, rarg5RegI cnt2 // String IndexOfChar instruct indexOfChar_U(iRegP haystack, iRegI haycnt, iRegI ch, iRegI result, roddRegL oddReg, revenRegL evenReg, flagsReg cr) %{ - predicate(CompactStrings); match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); effect(TEMP_DEF result, TEMP evenReg, TEMP oddReg, KILL cr); // R0, R1 are killed, too. ins_cost(200); @@ -10590,7 +10589,6 @@ instruct bytes_reverse_long(iRegL dst, iRegL src) %{ instruct countLeadingZerosI(revenRegI dst, iRegI src, roddRegI tmp, flagsReg cr) %{ match(Set dst (CountLeadingZerosI src)); effect(KILL tmp, KILL cr); - predicate(UseCountLeadingZerosInstruction); // See Matcher::match_rule_supported ins_cost(3 * DEFAULT_COST); size(14); format %{ "SLLG $dst,$src,32\t# no need to always count 32 zeroes first\n\t" @@ -10629,7 +10627,6 @@ instruct countLeadingZerosI(revenRegI dst, iRegI src, roddRegI tmp, flagsReg cr) instruct countLeadingZerosL(revenRegI dst, iRegL src, roddRegI tmp, flagsReg cr) %{ match(Set dst (CountLeadingZerosL src)); effect(KILL tmp, KILL cr); - predicate(UseCountLeadingZerosInstruction); // See Matcher::match_rule_supported ins_cost(DEFAULT_COST); size(4); format %{ "FLOGR $dst,$src \t# count leading zeros (long)\n\t" %} @@ -10655,7 +10652,6 @@ instruct countLeadingZerosL(revenRegI dst, iRegL src, roddRegI tmp, flagsReg cr) instruct countTrailingZerosI(revenRegI dst, iRegI src, roddRegI tmp, flagsReg cr) %{ match(Set dst (CountTrailingZerosI src)); effect(TEMP_DEF dst, TEMP tmp, KILL cr); - predicate(UseCountLeadingZerosInstruction); // See Matcher::match_rule_supported ins_cost(8 * DEFAULT_COST); // TODO: s390 port size(FIXED_SIZE); // Emitted code depends on PreferLAoverADD being on/off. format %{ "LLGFR $dst,$src \t# clear upper 32 bits (we are dealing with int)\n\t" @@ -10709,7 +10705,6 @@ instruct countTrailingZerosI(revenRegI dst, iRegI src, roddRegI tmp, flagsReg cr instruct countTrailingZerosL(revenRegI dst, iRegL src, roddRegL tmp, flagsReg cr) %{ match(Set dst (CountTrailingZerosL src)); effect(TEMP_DEF dst, KILL tmp, KILL cr); - predicate(UseCountLeadingZerosInstruction); // See Matcher::match_rule_supported ins_cost(8 * DEFAULT_COST); // TODO: s390 port size(FIXED_SIZE); // Emitted code depends on PreferLAoverADD being on/off. format %{ "LCGR $dst,$src \t# preserve src\n\t" diff --git a/hotspot/src/cpu/s390/vm/templateTable_s390.cpp b/hotspot/src/cpu/s390/vm/templateTable_s390.cpp index aa02fd1b213..83d707dbd60 100644 --- a/hotspot/src/cpu/s390/vm/templateTable_s390.cpp +++ b/hotspot/src/cpu/s390/vm/templateTable_s390.cpp @@ -3831,17 +3831,17 @@ void TemplateTable::newarray() { // Call runtime. __ z_llgc(Z_ARG2, at_bcp(1)); // type - // size in Z_tos + __ z_lgfr(Z_ARG3, Z_tos); // size call_VM(Z_RET, CAST_FROM_FN_PTR(address, InterpreterRuntime::newarray), - Z_ARG2, Z_tos); + Z_ARG2, Z_ARG3); } void TemplateTable::anewarray() { transition(itos, atos); __ get_2_byte_integer_at_bcp(Z_ARG3, 1, InterpreterMacroAssembler::Unsigned); __ get_constant_pool(Z_ARG2); - __ z_llgfr(Z_ARG4, Z_tos); + __ z_lgfr(Z_ARG4, Z_tos); call_VM(Z_tos, CAST_FROM_FN_PTR(address, InterpreterRuntime::anewarray), Z_ARG2, Z_ARG3, Z_ARG4); } diff --git a/hotspot/src/cpu/s390/vm/vm_version_s390.cpp b/hotspot/src/cpu/s390/vm/vm_version_s390.cpp index 37e1da9e00f..7c40162534a 100644 --- a/hotspot/src/cpu/s390/vm/vm_version_s390.cpp +++ b/hotspot/src/cpu/s390/vm/vm_version_s390.cpp @@ -271,6 +271,31 @@ void VM_Version::set_features_string() { tty->print_cr(" oldest detected generation is %s", _features_string); _features_string = "z/Architecture (ambiguous detection)"; } + + if (has_Crypto_AES()) { + char buf[256]; + assert(strlen(_features_string) + 4 + 3*4 + 1 < sizeof(buf), "increase buffer size"); + jio_snprintf(buf, sizeof(buf), "%s aes%s%s%s", // String 'aes' must be surrounded by spaces so that jtreg tests recognize it. + _features_string, + has_Crypto_AES128() ? " 128" : "", + has_Crypto_AES192() ? " 192" : "", + has_Crypto_AES256() ? " 256" : ""); + _features_string = os::strdup(buf); + } + + if (has_Crypto_SHA()) { + char buf[256]; + assert(strlen(_features_string) + 4 + 2 + 2*4 + 6 + 1 < sizeof(buf), "increase buffer size"); + // String 'sha1' etc must be surrounded by spaces so that jtreg tests recognize it. + jio_snprintf(buf, sizeof(buf), "%s %s%s%s%s", + _features_string, + has_Crypto_SHA1() ? " sha1" : "", + has_Crypto_SHA256() ? " sha256" : "", + has_Crypto_SHA512() ? " sha512" : "", + has_Crypto_GHASH() ? " ghash" : ""); + if (has_Crypto_AES()) { os::free((void *)_features_string); } + _features_string = os::strdup(buf); + } } // featureBuffer - bit array indicating availability of various features @@ -369,7 +394,7 @@ void VM_Version::print_features_internal(const char* text, bool print_anyway) { if (has_Crypto()) { tty->cr(); - tty->print_cr("detailled availability of %s capabilities:", "CryptoFacility"); + tty->print_cr("detailed availability of %s capabilities:", "CryptoFacility"); if (test_feature_bit(&_cipher_features[0], -1, 2*Cipher::_featureBits)) { tty->cr(); tty->print_cr(" available: %s", "Message Cipher Functions"); @@ -479,7 +504,6 @@ void VM_Version::reset_features(bool reset) { } } - void VM_Version::set_features_z900(bool reset) { reset_features(reset); diff --git a/hotspot/src/os_cpu/linux_s390/vm/os_linux_s390.cpp b/hotspot/src/os_cpu/linux_s390/vm/os_linux_s390.cpp index c906109ea9e..1ca241df9cd 100644 --- a/hotspot/src/os_cpu/linux_s390/vm/os_linux_s390.cpp +++ b/hotspot/src/os_cpu/linux_s390/vm/os_linux_s390.cpp @@ -171,6 +171,8 @@ frame os::get_sender_for_C_frame(frame* fr) { } frame os::current_frame() { + // Expected to return the stack pointer of this method. + // But if inlined, returns the stack pointer of our caller! intptr_t* csp = (intptr_t*) *((intptr_t*) os::current_stack_pointer()); assert (csp != NULL, "sp should not be NULL"); // Pass a dummy pc. This way we don't have to load it from the @@ -184,8 +186,13 @@ frame os::current_frame() { assert(senderFrame.pc() != NULL, "Sender pc should not be NULL"); // Return sender of sender of current topframe which hopefully // both have pc != NULL. +#ifdef _NMT_NOINLINE_ // Is set in slowdebug builds. + // Current_stack_pointer is not inlined, we must pop one more frame. frame tmp = os::get_sender_for_C_frame(&topframe); return os::get_sender_for_C_frame(&tmp); +#else + return os::get_sender_for_C_frame(&topframe); +#endif } } @@ -374,7 +381,7 @@ JVM_handle_linux_signal(int sig, // BugId 4454115: A read from a MappedByteBuffer can fault here if the // underlying file has been truncated. Do not crash the VM in such a case. CodeBlob* cb = CodeCache::find_blob_unsafe(pc); - nmethod* nm = (cb != NULL && cb->is_nmethod()) ? (nmethod*)cb : NULL; + CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL; if (nm != NULL && nm->has_unsafe_access()) { // We don't really need a stub here! Just set the pending exeption and // continue at the next instruction after the faulting read. Returning From d89285aebb30756f7e028a862d01691c87d1d3b7 Mon Sep 17 00:00:00 2001 From: Jesper Wilhelmsson Date: Fri, 11 Nov 2016 16:52:44 +0100 Subject: [PATCH 018/235] 8169597: Quarantine TestCpoolForInvokeDynamic.java until JDK-8169232 is solved Reviewed-by: egahlin, gtriantafill --- hotspot/test/serviceability/sa/TestCpoolForInvokeDynamic.java | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/test/serviceability/sa/TestCpoolForInvokeDynamic.java b/hotspot/test/serviceability/sa/TestCpoolForInvokeDynamic.java index 80160d5cf84..e8f1fd86703 100644 --- a/hotspot/test/serviceability/sa/TestCpoolForInvokeDynamic.java +++ b/hotspot/test/serviceability/sa/TestCpoolForInvokeDynamic.java @@ -51,6 +51,7 @@ import jdk.test.lib.Asserts; * jdk.hotspot.agent/sun.jvm.hotspot.oops * jdk.hotspot.agent/sun.jvm.hotspot.debugger * jdk.hotspot.agent/sun.jvm.hotspot.ui.classbrowser + * @ignore 8169232 * @run main/othervm TestCpoolForInvokeDynamic */ From 82da03621f852bd95d888157044af09bf0141daf Mon Sep 17 00:00:00 2001 From: Volker Simonis Date: Mon, 14 Nov 2016 11:15:43 +0100 Subject: [PATCH 019/235] 8169625: Libjsig build doesn't set flags for ppc64/s390 builds Reviewed-by: erikj --- hotspot/make/lib/CompileLibjsig.gmk | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hotspot/make/lib/CompileLibjsig.gmk b/hotspot/make/lib/CompileLibjsig.gmk index 52c2896b190..d91993d65af 100644 --- a/hotspot/make/lib/CompileLibjsig.gmk +++ b/hotspot/make/lib/CompileLibjsig.gmk @@ -48,6 +48,12 @@ ifneq ($(OPENJDK_TARGET_OS), windows) LIBJSIG_CPU_FLAGS := -m64 else ifeq ($(OPENJDK_TARGET_CPU), x86) LIBJSIG_CPU_FLAGS := -m32 -march=i586 + else ifeq ($(OPENJDK_TARGET_CPU), ppc64) + LIBJSIG_CPU_FLAGS := -mcpu=powerpc64 -mtune=power5 + else ifeq ($(OPENJDK_TARGET_CPU), ppc64le) + LIBJSIG_CPU_FLAGS := -DABI_ELFv2 -mcpu=power8 -mtune=power8 + else ifeq ($(OPENJDK_TARGET_CPU), s390x) + LIBJSIG_CPU_FLAGS := -mbackchain -march=z10 endif else ifeq ($(OPENJDK_TARGET_OS), solaris) From d718f0e61e53c115ed2243673d037b4133a9ee83 Mon Sep 17 00:00:00 2001 From: Yang Zhang Date: Mon, 14 Nov 2016 10:10:10 -0800 Subject: [PATCH 020/235] 8169261: Fix for JDK-8067744 creates build failures with some versions of gcc and/or linux Reviewed-by: kvn, drwhite --- hotspot/make/test/JtregNative.gmk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hotspot/make/test/JtregNative.gmk b/hotspot/make/test/JtregNative.gmk index 78e78d774e5..cca48d09435 100644 --- a/hotspot/make/test/JtregNative.gmk +++ b/hotspot/make/test/JtregNative.gmk @@ -53,7 +53,6 @@ BUILD_HOTSPOT_JTREG_NATIVE_SRC := \ $(HOTSPOT_TOPDIR)/test/runtime/BoolReturn \ $(HOTSPOT_TOPDIR)/test/compiler/floatingpoint/ \ $(HOTSPOT_TOPDIR)/test/compiler/calls \ - $(HOTSPOT_TOPDIR)/test/compiler/native \ $(HOTSPOT_TOPDIR)/test/serviceability/jvmti/GetNamedModule \ $(HOTSPOT_TOPDIR)/test/testlibrary/jvmti \ $(HOTSPOT_TOPDIR)/test/compiler/jvmci/jdk.vm.ci.code.test \ @@ -91,7 +90,7 @@ ifeq ($(OPENJDK_TARGET_OS), linux) BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libtest-rwx := -z execstack BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exeinvoke := -ljvm -lpthread BUILD_TEST_invoke_exeinvoke.c_OPTIMIZATION := NONE - BUILD_HOTSPOT_JTREG_EXECUTABLES_LDFLAGS_exeFPRegs := -ldl + BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exeFPRegs := -ldl endif ifeq ($(OPENJDK_TARGET_OS), windows) From 1c8fc7bca4ae29f7edddb255302c8580b3c0239c Mon Sep 17 00:00:00 2001 From: Calvin Cheung Date: Mon, 14 Nov 2016 10:42:13 -0800 Subject: [PATCH 021/235] 8168796: relax vm options checking during CDS dump time Warning instead of exit for the following vm options specified during CDS dump time: --module-path, --upgrade-module-path, --add-modules Reviewed-by: hseigel, jiangli, sspitsyn --- hotspot/src/share/vm/runtime/arguments.cpp | 23 +++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index b02fa54e95f..4ba3ec45004 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1315,22 +1315,31 @@ bool Arguments::add_property(const char* prop, PropertyWriteable writeable, Prop #if INCLUDE_CDS void Arguments::check_unsupported_dumping_properties() { assert(DumpSharedSpaces, "this function is only used with -Xshare:dump"); - const char* unsupported_properties[5] = { "jdk.module.main", + const char* unsupported_properties[] = { "jdk.module.main", + "jdk.module.limitmods", "jdk.module.path", "jdk.module.upgrade.path", - "jdk.module.addmods.0", - "jdk.module.limitmods" }; - const char* unsupported_options[5] = { "-m", + "jdk.module.addmods.0" }; + const char* unsupported_options[] = { "-m", + "--limit-modules", "--module-path", "--upgrade-module-path", - "--add-modules", - "--limit-modules" }; + "--add-modules" }; + assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be"); + // If a vm option is found in the unsupported_options array with index less than the warning_idx, + // vm will exit with an error message. Otherwise, it will result in a warning message. + uint warning_idx = 2; SystemProperty* sp = system_properties(); while (sp != NULL) { - for (int i = 0; i < 5; i++) { + for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) { if (strcmp(sp->key(), unsupported_properties[i]) == 0) { + if (i < warning_idx) { vm_exit_during_initialization( "Cannot use the following option when dumping the shared archive", unsupported_options[i]); + } else { + warning( + "the %s option is ignored when dumping the shared archive", unsupported_options[i]); + } } } sp = sp->next(); From 70abdc1e0e824891450a4c85b713ed6d5032ee5a Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Mon, 14 Nov 2016 18:03:44 -0500 Subject: [PATCH 022/235] 8168790: CDS: assert(max_delta <= (0x7FFFFFFF)) failed: range check Change the assert to check the current delta is less than 0x7FFFFFFF. Reviewed-by: iklam, ddmitriev --- .../share/vm/classfile/compactHashtable.cpp | 6 +-- .../SharedArchiveFile/LargeSharedSpace.java | 48 +++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 hotspot/test/runtime/SharedArchiveFile/LargeSharedSpace.java diff --git a/hotspot/src/share/vm/classfile/compactHashtable.cpp b/hotspot/src/share/vm/classfile/compactHashtable.cpp index a9b6b28f365..d40b5fd2b9e 100644 --- a/hotspot/src/share/vm/classfile/compactHashtable.cpp +++ b/hotspot/src/share/vm/classfile/compactHashtable.cpp @@ -171,11 +171,11 @@ void CompactHashtableWriter::dump(SimpleCompactHashtable *cht, const char* table void CompactSymbolTableWriter::add(unsigned int hash, Symbol *symbol) { address base_address = address(MetaspaceShared::shared_rs()->base()); - uintx max_delta = uintx(MetaspaceShared::shared_rs()->size()); - assert(max_delta <= MAX_SHARED_DELTA, "range check"); uintx deltax = address(symbol) - base_address; - assert(deltax < max_delta, "range check"); + // The symbols are in RO space, which is smaler than MAX_SHARED_DELTA. + // The assert below is just to be extra cautious. + assert(deltax <= MAX_SHARED_DELTA, "the delta is too large to encode"); u4 delta = u4(deltax); CompactHashtableWriter::add(hash, delta); diff --git a/hotspot/test/runtime/SharedArchiveFile/LargeSharedSpace.java b/hotspot/test/runtime/SharedArchiveFile/LargeSharedSpace.java new file mode 100644 index 00000000000..e84c350c421 --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/LargeSharedSpace.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016, 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 LargeSharedSpace + * @bug 8168790 + * @summary Test CDS dumping with specific space size. + * The space size used in the test might not be suitable on windows and 32-bit platforms. + * @requires (sun.arch.data.model != "32") & (os.family != "windows") + * @library /test/lib + * @modules java.base/jdk.internal.misc + * java.management + * @run main LargeSharedSpace + */ + +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; + +public class LargeSharedSpace { + public static void main(String[] args) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:SharedMiscCodeSize=1066924031", "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=./LargeSharedSpace.jsa", "-Xshare:dump"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("Loading classes to share"); + output.shouldHaveExitValue(0); + } +} From cf892bc7886c1d0cbc3ff32bda764ad255cda423 Mon Sep 17 00:00:00 2001 From: Michail Chernov Date: Tue, 15 Nov 2016 14:04:39 +0300 Subject: [PATCH 023/235] 8168934: [TESTBUG] gc/g1/logging/TestG1LoggingFailure.java failed Reviewed-by: tschatzl, dfazunen --- hotspot/test/gc/g1/logging/TestG1LoggingFailure.java | 1 - 1 file changed, 1 deletion(-) diff --git a/hotspot/test/gc/g1/logging/TestG1LoggingFailure.java b/hotspot/test/gc/g1/logging/TestG1LoggingFailure.java index 8f89007c518..52ee2efe524 100644 --- a/hotspot/test/gc/g1/logging/TestG1LoggingFailure.java +++ b/hotspot/test/gc/g1/logging/TestG1LoggingFailure.java @@ -66,7 +66,6 @@ public class TestG1LoggingFailure { OutputAnalyzer out = ProcessTools.executeTestJvm(options.toArray(new String[options.size()])); out.shouldNotContain("pure virtual method called"); - out.shouldContain("Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread \"main\""); if (out.getExitValue() == 0) { System.out.println(out.getOutput()); From 198498171bd51760b82f3e302b86a4bb5a1ee43d Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Tue, 15 Nov 2016 08:34:56 -0500 Subject: [PATCH 024/235] 8169551: Segfaults in error traces when module version is null Make sure module->version() is not null before dereferencing it. Reviewed-by: coleenp, gtriantafill, lfoltan --- hotspot/src/share/vm/runtime/frame.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/runtime/frame.cpp b/hotspot/src/share/vm/runtime/frame.cpp index dcfd0b91492..d2c1d301557 100644 --- a/hotspot/src/share/vm/runtime/frame.cpp +++ b/hotspot/src/share/vm/runtime/frame.cpp @@ -664,8 +664,10 @@ void frame::print_on_error(outputStream* st, char* buf, int buflen, bool verbose if (module->is_named()) { module->name()->as_C_string(buf, buflen); st->print(" %s", buf); - module->version()->as_C_string(buf, buflen); - st->print("@%s", buf); + if (module->version() != NULL) { + module->version()->as_C_string(buf, buflen); + st->print("@%s", buf); + } } } else { st->print("j " PTR_FORMAT, p2i(pc())); @@ -694,8 +696,10 @@ void frame::print_on_error(outputStream* st, char* buf, int buflen, bool verbose if (module->is_named()) { module->name()->as_C_string(buf, buflen); st->print(" %s", buf); - module->version()->as_C_string(buf, buflen); - st->print("@%s", buf); + if (module->version() != NULL) { + module->version()->as_C_string(buf, buflen); + st->print("@%s", buf); + } } st->print(" (%d bytes) @ " PTR_FORMAT " [" PTR_FORMAT "+" INTPTR_FORMAT "]", m->code_size(), p2i(_pc), p2i(_cb->code_begin()), _pc - _cb->code_begin()); From 7d9d3aa1a01013e7945a0a2fef85e4da30ed40fa Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Tue, 15 Nov 2016 19:39:51 -0500 Subject: [PATCH 025/235] 8169423: Infinite loop in G1's ConcurrentMarkThread Also terminate loop if has_aborted flag is set. Reviewed-by: tschatzl, sjohanss --- .../src/share/vm/gc/g1/concurrentMarkThread.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp index 9c94863a43b..a84a70f414d 100644 --- a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp +++ b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp @@ -156,9 +156,7 @@ void ConcurrentMarkThread::run_service() { jlong mark_start = os::elapsed_counter(); log_info(gc, marking)("Concurrent Mark (%.3fs)", TimeHelper::counter_to_seconds(mark_start)); - int iter = 0; - do { - iter++; + for (uint iter = 1; true; ++iter) { if (!cm()->has_aborted()) { G1ConcPhaseTimer t(_cm, "Concurrent Mark From Roots"); _cm->mark_from_roots(); @@ -178,11 +176,14 @@ void ConcurrentMarkThread::run_service() { VM_CGC_Operation op(&final_cl, "Pause Remark"); VMThread::execute(&op); } - if (cm()->restart_for_overflow()) { - log_debug(gc, marking)("Restarting Concurrent Marking because of Mark Stack Overflow in Remark (Iteration #%d).", iter); - log_info(gc, marking)("Concurrent Mark Restart due to overflow"); + + if (!cm()->restart_for_overflow() || cm()->has_aborted()) { + break; } - } while (cm()->restart_for_overflow()); + + log_info(gc, marking)("Concurrent Mark Restart due to overflow" + " (iteration #%u", iter); + } if (!cm()->has_aborted()) { G1ConcPhaseTimer t(_cm, "Concurrent Create Live Data"); From 7c690441e4ebc98a6311ecdecd832924d553a682 Mon Sep 17 00:00:00 2001 From: Sharath Ballal Date: Wed, 16 Nov 2016 14:11:30 +0300 Subject: [PATCH 026/235] 7107013: sun.jvm.hotspot.runtime.Bytes.swapLong conversion to long mishandled Cast to long to avoid truncation in swapLong() Reviewed-by: dsamersoff --- .../share/classes/sun/jvm/hotspot/runtime/Bytes.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Bytes.java b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Bytes.java index b0cc278b812..f2c7abfe639 100644 --- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Bytes.java +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Bytes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, 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 @@ -51,7 +51,7 @@ public class Bytes { if (!swap) return x; - return (swapShort((short) x) << 16) | (swapShort((short) (x >> 16)) & 0xFFFF); + return ((int)swapShort((short) x) << 16) | (swapShort((short) (x >> 16)) & 0xFFFF); } /** Should only swap if the hardware's underlying byte order is @@ -60,6 +60,6 @@ public class Bytes { if (!swap) return x; - return (swapInt((int) x) << 32) | (swapInt((int) (x >> 32)) & 0xFFFFFFFF); + return ((long)swapInt((int) x) << 32) | (swapInt((int) (x >> 32)) & 0xFFFFFFFF); } } From 5f5f5e574d19d8b29bcee6ed38d3464593b5121d Mon Sep 17 00:00:00 2001 From: Michail Chernov Date: Wed, 16 Nov 2016 18:57:42 +0300 Subject: [PATCH 027/235] 8165955: TestFullGCCount test failed with CMS and -XX:+ExplicitGCInvokesConcurrent Reviewed-by: dfazunen, tschatzl --- hotspot/test/gc/TestFullGCCount.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hotspot/test/gc/TestFullGCCount.java b/hotspot/test/gc/TestFullGCCount.java index 9e5dddf4d7d..416b18a189d 100644 --- a/hotspot/test/gc/TestFullGCCount.java +++ b/hotspot/test/gc/TestFullGCCount.java @@ -21,10 +21,11 @@ * questions. */ -/* +/** * @test TestFullGCCount.java * @bug 7072527 * @summary CMS: JMM GC counters overcount in some cases + * @requires !(vm.gc.ConcMarkSweep & vm.opt.ExplicitGCInvokesConcurrent == true) * @modules java.management * @run main/othervm -Xlog:gc TestFullGCCount */ From 81f1e7056b3e734978b6ea45dc909321b646cded Mon Sep 17 00:00:00 2001 From: Jini George Date: Thu, 17 Nov 2016 15:54:48 +0300 Subject: [PATCH 028/235] 8169638: serviceability/sa/TestInstanceKlassSize.java and serviceability/sa/TestInstanceKlassSizeForInterface.java fail compilation Modified the jtreg tests to use @modules Reviewed-by: dsamersoff, rehn --- .../sa/TestInstanceKlassSize.java | 18 +++++------------- .../sa/TestInstanceKlassSizeForInterface.java | 18 +++++------------- 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/hotspot/test/serviceability/sa/TestInstanceKlassSize.java b/hotspot/test/serviceability/sa/TestInstanceKlassSize.java index 4af527eaa46..9890b3d6739 100644 --- a/hotspot/test/serviceability/sa/TestInstanceKlassSize.java +++ b/hotspot/test/serviceability/sa/TestInstanceKlassSize.java @@ -45,19 +45,11 @@ import java.util.*; * @test * @library /test/lib * @modules java.base/jdk.internal.misc - * @compile -XDignore.symbol.file=true - * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED - * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED - * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED - * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED - * TestInstanceKlassSize.java - * @run main/othervm - * --add-modules=jdk.hotspot.agent - * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED - * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED - * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED - * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED - * TestInstanceKlassSize + * jdk.hotspot.agent/sun.jvm.hotspot + * jdk.hotspot.agent/sun.jvm.hotspot.utilities + * jdk.hotspot.agent/sun.jvm.hotspot.oops + * jdk.hotspot.agent/sun.jvm.hotspot.debugger + * @run main/othervm TestInstanceKlassSize */ public class TestInstanceKlassSize { diff --git a/hotspot/test/serviceability/sa/TestInstanceKlassSizeForInterface.java b/hotspot/test/serviceability/sa/TestInstanceKlassSizeForInterface.java index f6a9c3f0bf8..5369c761073 100644 --- a/hotspot/test/serviceability/sa/TestInstanceKlassSizeForInterface.java +++ b/hotspot/test/serviceability/sa/TestInstanceKlassSizeForInterface.java @@ -38,19 +38,11 @@ import jdk.test.lib.Asserts; * @test * @library /test/lib * @modules java.base/jdk.internal.misc - * @compile -XDignore.symbol.file=true - * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED - * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED - * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED - * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED - * TestInstanceKlassSizeForInterface.java - * @run main/othervm - * --add-modules=jdk.hotspot.agent - * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED - * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED - * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED - * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED - * TestInstanceKlassSizeForInterface + * jdk.hotspot.agent/sun.jvm.hotspot + * jdk.hotspot.agent/sun.jvm.hotspot.utilities + * jdk.hotspot.agent/sun.jvm.hotspot.oops + * jdk.hotspot.agent/sun.jvm.hotspot.debugger + * @run main/othervm TestInstanceKlassSizeForInterface */ interface Language { From ccbb28f6a0bdc081207412cb82b348d1c43cd5a2 Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Thu, 17 Nov 2016 14:23:29 -0500 Subject: [PATCH 029/235] 8166304: Skipping access check for classes generated by core reflection Only allow boot and reflection class loader to load sub-types of jdk.internal.reflect Reviewed-by: acorn, lfoltan, rehn --- .../share/vm/classfile/classFileParser.cpp | 23 +++++- .../src/share/vm/classfile/javaClasses.cpp | 23 +++--- .../src/share/vm/classfile/javaClasses.hpp | 4 ++ hotspot/src/share/vm/classfile/vmSymbols.hpp | 1 + .../classFileParserBug/FakeMethodAcc.java | 47 ++++++++++++ .../fakeMethodAccessor.jasm | 72 +++++++++++++++++++ 6 files changed, 161 insertions(+), 9 deletions(-) create mode 100644 hotspot/test/runtime/classFileParserBug/FakeMethodAcc.java create mode 100644 hotspot/test/runtime/classFileParserBug/fakeMethodAccessor.jasm diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 22f18286c74..0754a91e7f5 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -4349,13 +4349,34 @@ static void check_super_class_access(const InstanceKlass* this_klass, TRAPS) { assert(this_klass != NULL, "invariant"); const Klass* const super = this_klass->super(); if (super != NULL) { + + // If the loader is not the boot loader then throw an exception if its + // superclass is in package jdk.internal.reflect and its loader is not a + // special reflection class loader + if (!this_klass->class_loader_data()->is_the_null_class_loader_data()) { + assert(super->is_instance_klass(), "super is not instance klass"); + PackageEntry* super_package = super->package(); + if (super_package != NULL && + super_package->name()->fast_compare(vmSymbols::jdk_internal_reflect()) == 0 && + !java_lang_ClassLoader::is_reflection_class_loader(this_klass->class_loader())) { + ResourceMark rm(THREAD); + Exceptions::fthrow( + THREAD_AND_LOCATION, + vmSymbols::java_lang_IllegalAccessError(), + "class %s loaded by %s cannot access jdk/internal/reflect superclass %s", + this_klass->external_name(), + this_klass->class_loader_data()->loader_name(), + super->external_name()); + return; + } + } + Reflection::VerifyClassAccessResults vca_result = Reflection::verify_class_access(this_klass, super, false); if (vca_result != Reflection::ACCESS_OK) { ResourceMark rm(THREAD); char* msg = Reflection::verify_class_access_msg(this_klass, super, vca_result); if (msg == NULL) { - ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_IllegalAccessError(), diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp index 3da3b09f96d..dc5fe6a90f7 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.cpp +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp @@ -3525,17 +3525,24 @@ bool java_lang_ClassLoader::is_trusted_loader(oop loader) { return false; } -oop java_lang_ClassLoader::non_reflection_class_loader(oop loader) { +// Return true if this is one of the class loaders associated with +// the generated bytecodes for reflection. +bool java_lang_ClassLoader::is_reflection_class_loader(oop loader) { if (loader != NULL) { - // See whether this is one of the class loaders associated with - // the generated bytecodes for reflection, and if so, "magically" - // delegate to its parent to prevent class loading from occurring - // in places where applications using reflection didn't expect it. Klass* delegating_cl_class = SystemDictionary::reflect_DelegatingClassLoader_klass(); // This might be null in non-1.4 JDKs - if (delegating_cl_class != NULL && loader->is_a(delegating_cl_class)) { - return parent(loader); - } + return (delegating_cl_class != NULL && loader->is_a(delegating_cl_class)); + } + return false; +} + +oop java_lang_ClassLoader::non_reflection_class_loader(oop loader) { + // See whether this is one of the class loaders associated with + // the generated bytecodes for reflection, and if so, "magically" + // delegate to its parent to prevent class loading from occurring + // in places where applications using reflection didn't expect it. + if (is_reflection_class_loader(loader)) { + return parent(loader); } return loader; } diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp index d4cba683a9a..a9a5cd1ed76 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.hpp +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp @@ -1243,6 +1243,10 @@ class java_lang_ClassLoader : AllStatic { static bool is_trusted_loader(oop loader); + // Return true if this is one of the class loaders associated with + // the generated bytecodes for reflection. + static bool is_reflection_class_loader(oop loader); + // Fix for 4474172 static oop non_reflection_class_loader(oop loader); diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp index fd3b3fe4173..33c77f17bdf 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp @@ -228,6 +228,7 @@ \ /* Support for reflection based on dynamic bytecode generation (JDK 1.4 and above) */ \ \ + template(jdk_internal_reflect, "jdk/internal/reflect") \ template(reflect_MagicAccessorImpl, "jdk/internal/reflect/MagicAccessorImpl") \ template(reflect_MethodAccessorImpl, "jdk/internal/reflect/MethodAccessorImpl") \ template(reflect_ConstructorAccessorImpl, "jdk/internal/reflect/ConstructorAccessorImpl") \ diff --git a/hotspot/test/runtime/classFileParserBug/FakeMethodAcc.java b/hotspot/test/runtime/classFileParserBug/FakeMethodAcc.java new file mode 100644 index 00000000000..ba8304319b5 --- /dev/null +++ b/hotspot/test/runtime/classFileParserBug/FakeMethodAcc.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, 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 8166304 + * @summary Skipping access check for classes generated by core reflection + * @compile fakeMethodAccessor.jasm + * @run main FakeMethodAcc + */ + +/* + * Test that trying to create a sub-type of a 'magic' jdk.internal.reflect + * class should fail with an IllegalAccessError exception. +*/ +public class FakeMethodAcc { + public static void main(String args[]) throws Throwable { + + System.out.println("Regression test for bug 8166304"); + try { + Class newClass = Class.forName("fakeMethodAccessor"); + throw new RuntimeException( + "Missing expected IllegalAccessError exception"); + } catch (java.lang.IllegalAccessError e) { + } + } +} diff --git a/hotspot/test/runtime/classFileParserBug/fakeMethodAccessor.jasm b/hotspot/test/runtime/classFileParserBug/fakeMethodAccessor.jasm new file mode 100644 index 00000000000..36cebcb5049 --- /dev/null +++ b/hotspot/test/runtime/classFileParserBug/fakeMethodAccessor.jasm @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016, 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. + */ + +/* + // This is the Java representation of the below jasm code. The test tries + // to create a sub-type of jdk.internal.reflect.MethodAccessorImpl in order + // to bypass Reflection.getCallerClass. That should fail with an IAE. + // + import java.lang.reflect.Module; + class fakeMethodAccessor extends jdk.internal.reflect.MethodAccessorImpl { + public static void main(String[] a) throws Exception { + fakeMethodAccessor f = new fakeMethodAccessor(); + System.out.println(String.class.getModule() + .isExported("jdk.internal.misc", fakeMethodAccessor.class.getModule())); + } + } +*/ + +super class fakeMethodAccessor + extends jdk/internal/reflect/MethodAccessorImpl + version 53:0 +{ + + +Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method jdk/internal/reflect/MethodAccessorImpl."":"()V"; + return; +} + +public static Method main:"([Ljava/lang/String;)V" + throws java/lang/Exception + stack 4 locals 2 +{ + new class FakeMethodAccessor; + dup; + invokespecial Method "":"()V"; + astore_1; + getstatic Field java/lang/System.out:"Ljava/io/PrintStream;"; + ldc class java/lang/String; + invokevirtual Method java/lang/Class.getModule:"()Ljava/lang/reflect/Module;"; + ldc String "jdk.internal.misc"; + ldc class FakeMethodAccessor; + invokevirtual Method java/lang/Class.getModule:"()Ljava/lang/reflect/Module;"; + invokevirtual Method java/lang/reflect/Module.isExported:"(Ljava/lang/String;Ljava/lang/reflect/Module;)Z"; + invokevirtual Method java/io/PrintStream.println:"(Z)V"; + return; +} + +} // end Class FakeMethodAccessor From 3f2be39bb350777b3aa13258e1dad7936b4f42e1 Mon Sep 17 00:00:00 2001 From: Rachel Protacio Date: Thu, 17 Nov 2016 16:28:45 -0500 Subject: [PATCH 030/235] 8165550: Add class loader names to ClassCastException message Adds new format of class loader names to VM ClassCastException messages Reviewed-by: dholmes, mchung, lfoltan --- .../src/share/vm/classfile/moduleEntry.cpp | 11 ++ .../src/share/vm/classfile/moduleEntry.hpp | 2 + .../share/vm/classfile/systemDictionary.cpp | 4 +- .../src/share/vm/runtime/sharedRuntime.cpp | 122 ++++++++++++----- .../test/runtime/modules/CCE_module_msg.java | 124 +++++++++++++++++- hotspot/test/runtime/modules/p4/c4.java | 29 ++++ 6 files changed, 253 insertions(+), 39 deletions(-) create mode 100644 hotspot/test/runtime/modules/p4/c4.java diff --git a/hotspot/src/share/vm/classfile/moduleEntry.cpp b/hotspot/src/share/vm/classfile/moduleEntry.cpp index e4bbb08b2f7..42f79db8dc5 100644 --- a/hotspot/src/share/vm/classfile/moduleEntry.cpp +++ b/hotspot/src/share/vm/classfile/moduleEntry.cpp @@ -54,6 +54,17 @@ void ModuleEntry::set_location(Symbol* location) { } } +bool ModuleEntry::is_non_jdk_module() { + ResourceMark rm; + if (location() != NULL) { + const char* loc = location()->as_C_string(); + if (strncmp(loc, "jrt:/java.", 10) != 0 && strncmp(loc, "jrt:/jdk.", 9) != 0) { + return true; + } + } + return false; +} + void ModuleEntry::set_version(Symbol* version) { if (_version != NULL) { // _version symbol's refcounts are managed by ModuleEntry, diff --git a/hotspot/src/share/vm/classfile/moduleEntry.hpp b/hotspot/src/share/vm/classfile/moduleEntry.hpp index 82f0747a2ae..cffc672a7f2 100644 --- a/hotspot/src/share/vm/classfile/moduleEntry.hpp +++ b/hotspot/src/share/vm/classfile/moduleEntry.hpp @@ -36,6 +36,7 @@ #include "utilities/ostream.hpp" #define UNNAMED_MODULE "Unnamed Module" +#define JAVA_BASE_NAME "java.base" class ModuleClosure; @@ -100,6 +101,7 @@ public: Symbol* location() const { return _location; } void set_location(Symbol* location); + bool is_non_jdk_module(); bool can_read(ModuleEntry* m) const; bool has_reads() const; diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp index c6ae8e1e36a..259d4b43c8f 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp @@ -2897,11 +2897,11 @@ void SystemDictionary::verify() { // caller needs ResourceMark const char* SystemDictionary::loader_name(const oop loader) { return ((loader) == NULL ? "" : - InstanceKlass::cast((loader)->klass())->name()->as_C_string()); + InstanceKlass::cast((loader)->klass())->name()->as_C_string()); } // caller needs ResourceMark const char* SystemDictionary::loader_name(const ClassLoaderData* loader_data) { return (loader_data->class_loader() == NULL ? "" : - InstanceKlass::cast((loader_data->class_loader())->klass())->name()->as_C_string()); + SystemDictionary::loader_name(loader_data->class_loader())); } diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp index 8a14881be43..46f70657daf 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp @@ -55,6 +55,7 @@ #include "runtime/handles.inline.hpp" #include "runtime/init.hpp" #include "runtime/interfaceSupport.hpp" +#include "runtime/java.hpp" #include "runtime/javaCalls.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" @@ -1933,44 +1934,103 @@ char* SharedRuntime::generate_class_cast_message( return generate_class_cast_message(caster_klass, target_klass); } +// The caller of class_loader_and_module_name() (or one of its callers) +// must use a ResourceMark in order to correctly free the result. +const char* class_loader_and_module_name(Klass* klass) { + const char* delim = "/"; + size_t delim_len = strlen(delim); + + const char* fqn = klass->external_name(); + // Length of message to return; always include FQN + size_t msglen = strlen(fqn) + 1; + + bool has_cl_name = false; + bool has_mod_name = false; + bool has_version = false; + + // Use class loader name, if exists and not builtin + const char* class_loader_name = ""; + ClassLoaderData* cld = klass->class_loader_data(); + assert(cld != NULL, "class_loader_data should not be NULL"); + if (!cld->is_builtin_class_loader_data()) { + // If not builtin, look for name + oop loader = klass->class_loader(); + if (loader != NULL) { + oop class_loader_name_oop = java_lang_ClassLoader::name(loader); + if (class_loader_name_oop != NULL) { + class_loader_name = java_lang_String::as_utf8_string(class_loader_name_oop); + if (class_loader_name != NULL && class_loader_name[0] != '\0') { + has_cl_name = true; + msglen += strlen(class_loader_name) + delim_len; + } + } + } + } + + const char* module_name = ""; + const char* version = ""; + Klass* bottom_klass = klass->is_objArray_klass() ? + ObjArrayKlass::cast(klass)->bottom_klass() : klass; + if (bottom_klass->is_instance_klass()) { + ModuleEntry* module = InstanceKlass::cast(bottom_klass)->module(); + // Use module name, if exists + if (module->is_named()) { + has_mod_name = true; + module_name = module->name()->as_C_string(); + msglen += strlen(module_name); + // Use version if exists and is not a jdk module + if (module->is_non_jdk_module() && module->version() != NULL) { + has_version = true; + version = module->version()->as_C_string(); + msglen += strlen("@") + strlen(version); + } + } + } else { + // klass is an array of primitives, so its module is java.base + module_name = JAVA_BASE_NAME; + } + + if (has_cl_name || has_mod_name) { + msglen += delim_len; + } + + char* message = NEW_RESOURCE_ARRAY_RETURN_NULL(char, msglen); + + // Just return the FQN if error in allocating string + if (message == NULL) { + return fqn; + } + + jio_snprintf(message, msglen, "%s%s%s%s%s%s%s", + class_loader_name, + (has_cl_name) ? delim : "", + (has_mod_name) ? module_name : "", + (has_version) ? "@" : "", + (has_version) ? version : "", + (has_cl_name || has_mod_name) ? delim : "", + fqn); + return message; +} + char* SharedRuntime::generate_class_cast_message( Klass* caster_klass, Klass* target_klass) { - const char* caster_klass_name = caster_klass->external_name(); - Klass* c_klass = caster_klass->is_objArray_klass() ? - ObjArrayKlass::cast(caster_klass)->bottom_klass() : caster_klass; - ModuleEntry* caster_module; - const char* caster_module_name; - if (c_klass->is_instance_klass()) { - caster_module = InstanceKlass::cast(c_klass)->module(); - caster_module_name = caster_module->is_named() ? - caster_module->name()->as_C_string() : UNNAMED_MODULE; - } else { - caster_module_name = "java.base"; - } - const char* target_klass_name = target_klass->external_name(); - Klass* t_klass = target_klass->is_objArray_klass() ? - ObjArrayKlass::cast(target_klass)->bottom_klass() : target_klass; - ModuleEntry* target_module; - const char* target_module_name; - if (t_klass->is_instance_klass()) { - target_module = InstanceKlass::cast(t_klass)->module(); - target_module_name = target_module->is_named() ? - target_module->name()->as_C_string(): UNNAMED_MODULE; - } else { - target_module_name = "java.base"; - } + const char* caster_name = class_loader_and_module_name(caster_klass); - size_t msglen = strlen(caster_klass_name) + strlen(caster_module_name) + - strlen(target_klass_name) + strlen(target_module_name) + 50; + const char* target_name = class_loader_and_module_name(target_klass); - char* message = NEW_RESOURCE_ARRAY(char, msglen); - if (NULL == message) { + size_t msglen = strlen(caster_name) + strlen(" cannot be cast to ") + strlen(target_name) + 1; + + char* message = NEW_RESOURCE_ARRAY_RETURN_NULL(char, msglen); + if (message == NULL) { // Shouldn't happen, but don't cause even more problems if it does - message = const_cast(caster_klass_name); + message = const_cast(caster_klass->external_name()); } else { - jio_snprintf(message, msglen, "%s (in module: %s) cannot be cast to %s (in module: %s)", - caster_klass_name, caster_module_name, target_klass_name, target_module_name); + jio_snprintf(message, + msglen, + "%s cannot be cast to %s", + caster_name, + target_name); } return message; } diff --git a/hotspot/test/runtime/modules/CCE_module_msg.java b/hotspot/test/runtime/modules/CCE_module_msg.java index 54ece088b29..38ff41fde2d 100644 --- a/hotspot/test/runtime/modules/CCE_module_msg.java +++ b/hotspot/test/runtime/modules/CCE_module_msg.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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,17 +23,39 @@ /** * @test - * @run main/othervm CCE_module_msg + * @modules java.base/jdk.internal.misc + * @library /test/lib .. + * @compile p2/c2.java + * @compile p4/c4.java + * @build sun.hotspot.WhiteBox + * @compile/module=java.base java/lang/reflect/ModuleHelper.java + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI CCE_module_msg */ +import java.io.*; +import java.lang.reflect.Module; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Path; +import java.nio.file.Paths; +import static jdk.test.lib.Asserts.*; + // Test that the message in a runtime ClassCastException contains module info. public class CCE_module_msg { + private static final Path CLASSES_DIR = Paths.get("classes"); - public static void main(String[] args) { - invalidCastTest(); + public static void main(String[] args) throws Throwable { + // Should not display version + invalidObjectToDerived(); + // Should display version + invalidClassToString(); + // Should display customer class loader + invalidClassToStringCustomLoader(); } - public static void invalidCastTest() { + public static void invalidObjectToDerived() { java.lang.Object instance = new java.lang.Object(); int left = 23; int right = 42; @@ -44,11 +66,69 @@ public class CCE_module_msg { throw new RuntimeException("ClassCastException wasn't thrown, test failed."); } catch (ClassCastException cce) { System.out.println(cce.getMessage()); - if (!cce.getMessage().contains("java.lang.Object (in module: java.base) cannot be cast")) { + if (!cce.getMessage().contains("java.base/java.lang.Object cannot be cast to Derived")) { throw new RuntimeException("Wrong message: " + cce.getMessage()); } } } + + public static void invalidClassToString() throws Throwable { + // Get the java.lang.reflect.Module object for module java.base. + Class jlObject = Class.forName("java.lang.Object"); + Object jlObject_jlrM = jlObject.getModule(); + assertNotNull(jlObject_jlrM, "jlrModule object of java.lang.Object should not be null"); + + // Get the class loader for CCE_module_msg and assume it's also used to + // load classes p1.c1 and p2.c2. + ClassLoader this_cldr = CCE_module_msg.class.getClassLoader(); + + // Define a module for p2. + Object m2 = ModuleHelper.ModuleObject("module2", this_cldr, new String[] { "p2" }); + assertNotNull(m2, "Module should not be null"); + ModuleHelper.DefineModule(m2, "9.0", "m2/there", new String[] { "p2" }); + ModuleHelper.AddReadsModule(m2, jlObject_jlrM); + + try { + ModuleHelper.AddModuleExportsToAll(m2, "p2"); + Object p2Obj = new p2.c2(); + System.out.println((String)p2Obj); + throw new RuntimeException("ClassCastException wasn't thrown, test failed."); + } catch (ClassCastException cce) { + String exception = cce.getMessage(); + System.out.println(exception); + if (exception.contains("module2/p2.c2") || + !(exception.contains("module2@") && + exception.contains("/p2.c2 cannot be cast to java.base/java.lang.String"))) { + throw new RuntimeException("Wrong message: " + exception); + } + } + } + + public static void invalidClassToStringCustomLoader() throws Throwable { + // Get the java.lang.reflect.Module object for module java.base. + Class jlObject = Class.forName("java.lang.Object"); + Object jlObject_jlrM = jlObject.getModule(); + assertNotNull(jlObject_jlrM, "jlrModule object of java.lang.Object should not be null"); + + // Create a customer class loader to load class p4/c4. + URL[] urls = new URL[] { CLASSES_DIR.toUri().toURL() }; + ClassLoader parent = ClassLoader.getSystemClassLoader(); + MyURLClassLoader myCldr = new MyURLClassLoader("MyClassLoader", urls, parent); + + try { + // Class p4.c4 should be defined to the unnamed module of myCldr + Class p4_c4_class = myCldr.loadClass("p4.c4"); + Object c4Obj = p4_c4_class.newInstance(); + System.out.println((String)c4Obj); + throw new RuntimeException("ClassCastException wasn't thrown, test failed."); + } catch (ClassCastException cce) { + String exception = cce.getMessage(); + System.out.println(exception); + if (!exception.contains("MyClassLoader//p4.c4 cannot be cast to java.base/java.lang.String")) { + throw new RuntimeException("Wrong message: " + exception); + } + } + } } class Derived extends java.lang.Object { @@ -56,3 +136,35 @@ class Derived extends java.lang.Object { return right; } } + +class MyURLClassLoader extends URLClassLoader { + public MyURLClassLoader(String name, + URL[] urls, + ClassLoader parent) { + super(name, urls, parent); + } + + public Class loadClass(String name) throws ClassNotFoundException { + if (!name.equals("p4.c4")) { + return super.loadClass(name); + } + byte[] data = getClassData(name); + return defineClass(name, data, 0, data.length); + } + + byte[] getClassData(String name) { + try { + String TempName = name.replaceAll("\\.", "/"); + String currentDir = System.getProperty("test.classes"); + String filename = currentDir + File.separator + TempName + ".class"; + FileInputStream fis = new FileInputStream(filename); + byte[] b = new byte[5000]; + int cnt = fis.read(b, 0, 5000); + byte[] c = new byte[cnt]; + for (int i=0; i Date: Fri, 18 Nov 2016 03:40:56 -0800 Subject: [PATCH 031/235] 8169529: AArch64: Revert old JDK-8167595 changes after JDK-8159035 fix is pushed Removed the zero check Reviewed-by: adinn, aph, thartmann --- hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp index 41a7956c20e..681ecf34277 100644 --- a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp +++ b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp @@ -2743,7 +2743,7 @@ class StubGenerator: public StubCodeGenerator { __ align(CodeEntryAlignment); StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_encryptAESCrypt"); - Label L_loadkeys_44, L_loadkeys_52, L_aes_loop, L_rounds_44, L_rounds_52, _L_finish; + Label L_loadkeys_44, L_loadkeys_52, L_aes_loop, L_rounds_44, L_rounds_52; const Register from = c_rarg0; // source array address const Register to = c_rarg1; // destination array address @@ -2757,8 +2757,7 @@ class StubGenerator: public StubCodeGenerator { __ enter(); - __ subsw(rscratch2, len_reg, zr); - __ br(Assembler::LE, _L_finish); + __ movw(rscratch2, len_reg); __ ldrw(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT))); @@ -2823,7 +2822,6 @@ class StubGenerator: public StubCodeGenerator { __ st1(v0, __ T16B, rvec); - __ BIND(_L_finish); __ mov(r0, rscratch2); __ leave(); @@ -2849,7 +2847,7 @@ class StubGenerator: public StubCodeGenerator { __ align(CodeEntryAlignment); StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_decryptAESCrypt"); - Label L_loadkeys_44, L_loadkeys_52, L_aes_loop, L_rounds_44, L_rounds_52, _L_finish; + Label L_loadkeys_44, L_loadkeys_52, L_aes_loop, L_rounds_44, L_rounds_52; const Register from = c_rarg0; // source array address const Register to = c_rarg1; // destination array address @@ -2863,8 +2861,7 @@ class StubGenerator: public StubCodeGenerator { __ enter(); - __ subsw(rscratch2, len_reg, zr); - __ br(Assembler::LE, _L_finish); + __ movw(rscratch2, len_reg); __ ldrw(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT))); @@ -2933,7 +2930,6 @@ class StubGenerator: public StubCodeGenerator { __ st1(v2, __ T16B, rvec); - __ BIND(_L_finish); __ mov(r0, rscratch2); __ leave(); From 71c22433e4d3c75b459b7de42f1ccc3e6bacd843 Mon Sep 17 00:00:00 2001 From: Michail Chernov Date: Fri, 18 Nov 2016 18:46:08 +0300 Subject: [PATCH 032/235] 8166719: gc/stress/TestStressG1Humongous.java fails with OOME Reviewed-by: tschatzl, dfazunen --- .../test/gc/stress/TestStressG1Humongous.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/hotspot/test/gc/stress/TestStressG1Humongous.java b/hotspot/test/gc/stress/TestStressG1Humongous.java index 501f64672f5..cd951ea31c6 100644 --- a/hotspot/test/gc/stress/TestStressG1Humongous.java +++ b/hotspot/test/gc/stress/TestStressG1Humongous.java @@ -21,7 +21,7 @@ * questions. */ - /* +/* * @test TestStressG1Humongous * @key gc * @key stress @@ -42,8 +42,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Collections; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; public class TestStressG1Humongous { @@ -56,7 +54,7 @@ public class TestStressG1Humongous { private static final int NUMBER_OF_FREE_REGIONS = 2; private volatile boolean isRunning; - private final ExecutorService threadExecutor; + private final Thread[] threads; private final AtomicInteger alocatedObjectsCount; private CountDownLatch countDownLatch; public static final List GARBAGE = Collections.synchronizedList(new ArrayList<>()); @@ -67,12 +65,12 @@ public class TestStressG1Humongous { public TestStressG1Humongous() { isRunning = true; - threadExecutor = Executors.newFixedThreadPool(THREAD_COUNT + 1); + threads = new Thread[THREAD_COUNT]; alocatedObjectsCount = new AtomicInteger(0); } private void run() throws InterruptedException { - threadExecutor.submit(new Timer()); + new Thread(new Timer()).start(); int checkedAmountOfHObjects = getExpectedAmountOfObjects(); while (isRunning()) { countDownLatch = new CountDownLatch(THREAD_COUNT); @@ -82,7 +80,6 @@ public class TestStressG1Humongous { System.out.println("Allocated " + alocatedObjectsCount.get() + " objects."); alocatedObjectsCount.set(0); } - threadExecutor.shutdown(); System.out.println("Done!"); } @@ -110,9 +107,12 @@ public class TestStressG1Humongous { int objectsPerThread = totalObjects / THREAD_COUNT; int objectsForLastThread = objectsPerThread + totalObjects % THREAD_COUNT; for (int i = 0; i < THREAD_COUNT - 1; ++i) { - threadExecutor.submit(new AllocationThread(countDownLatch, objectsPerThread, alocatedObjectsCount)); + threads[i] = new Thread(new AllocationThread(countDownLatch, objectsPerThread, alocatedObjectsCount)); + } + threads[THREAD_COUNT - 1] = new Thread(new AllocationThread(countDownLatch, objectsForLastThread, alocatedObjectsCount)); + for (int i = 0; i < THREAD_COUNT; ++i) { + threads[i].start(); } - threadExecutor.submit(new AllocationThread(countDownLatch, objectsForLastThread, alocatedObjectsCount)); } /** From d1f8287a4921547cd80bd01d46c711cb443ee31c Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 18 Nov 2016 19:04:48 +0000 Subject: [PATCH 033/235] 8169901: AArch64: CompareAndExchange intrinsics clobber address register Reviewed-by: aph --- hotspot/src/cpu/aarch64/vm/aarch64.ad | 31 ++++++++++++-------- hotspot/src/cpu/aarch64/vm/cas.m4 | 41 ++++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 16 deletions(-) diff --git a/hotspot/src/cpu/aarch64/vm/aarch64.ad b/hotspot/src/cpu/aarch64/vm/aarch64.ad index 3708908e33f..8f58c83136c 100644 --- a/hotspot/src/cpu/aarch64/vm/aarch64.ad +++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad @@ -9646,6 +9646,10 @@ instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegN // --------------------------------------------------------------------- + + +// BEGIN This section of the file is automatically generated. Do not edit -------------- + // Sundry CAS operations. Note that release is always true, // regardless of the memory ordering of the CAS. This is because we // need the volatile case to be sequentially consistent but there is @@ -9656,10 +9660,11 @@ instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegN // This section is generated from aarch64_ad_cas.m4 -instruct compareAndExchangeB(iRegI_R0 res, indirect mem, iRegI_R2 oldval, iRegI_R3 newval, rFlagsReg cr) %{ + +instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ match(Set res (CompareAndExchangeB mem (Binary oldval newval))); ins_cost(2 * VOLATILE_REF_COST); - effect(KILL cr); + effect(TEMP_DEF res, KILL cr); format %{ "cmpxchg $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" %} @@ -9673,10 +9678,10 @@ instruct compareAndExchangeB(iRegI_R0 res, indirect mem, iRegI_R2 oldval, iRegI_ ins_pipe(pipe_slow); %} -instruct compareAndExchangeS(iRegI_R0 res, indirect mem, iRegI_R2 oldval, iRegI_R3 newval, rFlagsReg cr) %{ +instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ match(Set res (CompareAndExchangeS mem (Binary oldval newval))); ins_cost(2 * VOLATILE_REF_COST); - effect(KILL cr); + effect(TEMP_DEF res, KILL cr); format %{ "cmpxchg $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" %} @@ -9690,10 +9695,10 @@ instruct compareAndExchangeS(iRegI_R0 res, indirect mem, iRegI_R2 oldval, iRegI_ ins_pipe(pipe_slow); %} -instruct compareAndExchangeI(iRegI_R0 res, indirect mem, iRegI_R2 oldval, iRegI_R3 newval, rFlagsReg cr) %{ +instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ match(Set res (CompareAndExchangeI mem (Binary oldval newval))); ins_cost(2 * VOLATILE_REF_COST); - effect(KILL cr); + effect(TEMP_DEF res, KILL cr); format %{ "cmpxchg $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" %} @@ -9705,10 +9710,10 @@ instruct compareAndExchangeI(iRegI_R0 res, indirect mem, iRegI_R2 oldval, iRegI_ ins_pipe(pipe_slow); %} -instruct compareAndExchangeL(iRegL_R0 res, indirect mem, iRegL_R2 oldval, iRegL_R3 newval, rFlagsReg cr) %{ +instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ match(Set res (CompareAndExchangeL mem (Binary oldval newval))); ins_cost(2 * VOLATILE_REF_COST); - effect(KILL cr); + effect(TEMP_DEF res, KILL cr); format %{ "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" %} @@ -9720,10 +9725,10 @@ instruct compareAndExchangeL(iRegL_R0 res, indirect mem, iRegL_R2 oldval, iRegL_ ins_pipe(pipe_slow); %} -instruct compareAndExchangeN(iRegN_R0 res, indirect mem, iRegN_R2 oldval, iRegN_R3 newval, rFlagsReg cr) %{ +instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ match(Set res (CompareAndExchangeN mem (Binary oldval newval))); ins_cost(2 * VOLATILE_REF_COST); - effect(KILL cr); + effect(TEMP_DEF res, KILL cr); format %{ "cmpxchg $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" %} @@ -9735,10 +9740,10 @@ instruct compareAndExchangeN(iRegN_R0 res, indirect mem, iRegN_R2 oldval, iRegN_ ins_pipe(pipe_slow); %} -instruct compareAndExchangeP(iRegP_R0 res, indirect mem, iRegP_R2 oldval, iRegP_R3 newval, rFlagsReg cr) %{ +instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ match(Set res (CompareAndExchangeP mem (Binary oldval newval))); ins_cost(2 * VOLATILE_REF_COST); - effect(KILL cr); + effect(TEMP_DEF res, KILL cr); format %{ "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" %} @@ -9853,6 +9858,8 @@ instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP ne %} ins_pipe(pipe_slow); %} + +// END This section of the file is automatically generated. Do not edit -------------- // --------------------------------------------------------------------- instruct get_and_setI(indirect mem, iRegINoSp newv, iRegI prev) %{ diff --git a/hotspot/src/cpu/aarch64/vm/cas.m4 b/hotspot/src/cpu/aarch64/vm/cas.m4 index eb276df3880..b56112b347b 100644 --- a/hotspot/src/cpu/aarch64/vm/cas.m4 +++ b/hotspot/src/cpu/aarch64/vm/cas.m4 @@ -1,3 +1,31 @@ +dnl Copyright (c) 2016, Red Hat Inc. All rights reserved. +dnl DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +dnl +dnl This code is free software; you can redistribute it and/or modify it +dnl under the terms of the GNU General Public License version 2 only, as +dnl published by the Free Software Foundation. +dnl +dnl This code is distributed in the hope that it will be useful, but WITHOUT +dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +dnl version 2 for more details (a copy is included in the LICENSE file that +dnl accompanied this code). +dnl +dnl You should have received a copy of the GNU General Public License version +dnl 2 along with this work; if not, write to the Free Software Foundation, +dnl Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +dnl +dnl Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +dnl or visit www.oracle.com if you need additional information or have any +dnl questions. +dnl +dnl +dnl Process this file with m4 cas.m4 to generate the CAE and wCAS +dnl instructions used in aarch64.ad. +dnl + +// BEGIN This section of the file is automatically generated. Do not edit -------------- + // Sundry CAS operations. Note that release is always true, // regardless of the memory ordering of the CAS. This is because we // need the volatile case to be sequentially consistent but there is @@ -5,13 +33,16 @@ // can't check the type of memory ordering here, so we always emit a // STLXR. +// This section is generated from aarch64_ad_cas.m4 + + define(`CAS_INSN', ` -instruct compareAndExchange$1$5(iReg$2_R0 res, indirect mem, iReg$2_R2 oldval, iReg$2_R3 newval, rFlagsReg cr) %{ +instruct compareAndExchange$1$5(iReg$2NoSp res, indirect mem, iReg$2 oldval, iReg$2 newval, rFlagsReg cr) %{ match(Set res (CompareAndExchange$1 mem (Binary oldval newval))); ifelse($5,Acq,' predicate(needs_acquiring_load_exclusive(n)); ins_cost(VOLATILE_REF_COST);`,' ins_cost(2 * VOLATILE_REF_COST);`) - effect(KILL cr); + effect(TEMP_DEF res, KILL cr); format %{ "cmpxchg $res = $mem, $oldval, $newval\t# ($3, weak) if $mem == $oldval then $mem <-- $newval" %} @@ -24,11 +55,11 @@ instruct compareAndExchange$1$5(iReg$2_R0 res, indirect mem, iReg$2_R2 oldval, i %}')dnl define(`CAS_INSN4', ` -instruct compareAndExchange$1$7(iReg$2_R0 res, indirect mem, iReg$2_R2 oldval, iReg$2_R3 newval, rFlagsReg cr) %{ +instruct compareAndExchange$1$7(iReg$2NoSp res, indirect mem, iReg$2 oldval, iReg$2 newval, rFlagsReg cr) %{ match(Set res (CompareAndExchange$1 mem (Binary oldval newval))); ifelse($7,Acq,' predicate(needs_acquiring_load_exclusive(n)); ins_cost(VOLATILE_REF_COST);`,' ins_cost(2 * VOLATILE_REF_COST);`) - effect(KILL cr); + effect(TEMP_DEF res, KILL cr); format %{ "cmpxchg $res = $mem, $oldval, $newval\t# ($3, weak) if $mem == $oldval then $mem <-- $newval" %} @@ -107,3 +138,5 @@ dnl CAS_INSN3(L,L,long,xword,Acq) dnl CAS_INSN3(N,N,narrow oop,word,Acq) dnl CAS_INSN3(P,P,ptr,xword,Acq) dnl + +// END This section of the file is automatically generated. Do not edit -------------- From 94e3514d8fd41a7d53c9b154ed2fd9d9a427fc87 Mon Sep 17 00:00:00 2001 From: Tobias Hartmann Date: Mon, 21 Nov 2016 08:27:10 +0100 Subject: [PATCH 034/235] 8169711: CDS does not patch entry trampoline if intrinsic method is disabled Always create interpreter method entries for intrinsified methods but replace them with vanilla entries if the intrinsic is disabled at runtime. Reviewed-by: kvn, iklam --- .../templateInterpreterGenerator_aarch64.cpp | 3 + hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp | 2 +- .../templateInterpreterGenerator_x86_32.cpp | 6 ++ .../templateInterpreterGenerator_x86_64.cpp | 6 ++ .../vm/interpreter/abstractInterpreter.cpp | 39 +++----- .../templateInterpreterGenerator.cpp | 23 ++--- .../TestInterpreterMethodEntries.java | 96 +++++++++++++++++++ 7 files changed, 132 insertions(+), 43 deletions(-) create mode 100644 hotspot/test/runtime/SharedArchiveFile/TestInterpreterMethodEntries.java diff --git a/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp index 8ff0bc6b962..e3cd202f351 100644 --- a/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp +++ b/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp @@ -203,6 +203,9 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M __ mov(sp, r13); generate_transcendental_entry(kind, 2); break; + case Interpreter::java_lang_math_fmaD : + case Interpreter::java_lang_math_fmaF : + return NULL; default: ; } diff --git a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp index 51f793928ab..70be6c60687 100644 --- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp @@ -351,7 +351,7 @@ void VM_Version::initialize() { FLAG_SET_DEFAULT(UseCRC32Intrinsics, true); } } else if (UseCRC32Intrinsics) { - warning("SPARC CRC32 intrinsics require VIS3 insructions support. Intriniscs will be disabled"); + warning("SPARC CRC32 intrinsics require VIS3 instructions support. Intrinsics will be disabled"); FLAG_SET_DEFAULT(UseCRC32Intrinsics, false); } diff --git a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_32.cpp index 98b52c7cf1b..861403164ae 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_32.cpp @@ -342,6 +342,9 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M // [ hi(arg) ] // if (kind == Interpreter::java_lang_math_fmaD) { + if (!UseFMA) { + return NULL; // Generate a vanilla entry + } __ movdbl(xmm2, Address(rsp, 5 * wordSize)); __ movdbl(xmm1, Address(rsp, 3 * wordSize)); __ movdbl(xmm0, Address(rsp, 1 * wordSize)); @@ -352,6 +355,9 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M return entry_point; } else if (kind == Interpreter::java_lang_math_fmaF) { + if (!UseFMA) { + return NULL; // Generate a vanilla entry + } __ movflt(xmm2, Address(rsp, 3 * wordSize)); __ movflt(xmm1, Address(rsp, 2 * wordSize)); __ movflt(xmm0, Address(rsp, 1 * wordSize)); diff --git a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_64.cpp index 6cdf3c64cfd..99e859fc36b 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_64.cpp @@ -370,11 +370,17 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M // if (kind == Interpreter::java_lang_math_fmaD) { + if (!UseFMA) { + return NULL; // Generate a vanilla entry + } __ movdbl(xmm0, Address(rsp, wordSize)); __ movdbl(xmm1, Address(rsp, 3 * wordSize)); __ movdbl(xmm2, Address(rsp, 5 * wordSize)); __ fmad(xmm0, xmm1, xmm2, xmm0); } else if (kind == Interpreter::java_lang_math_fmaF) { + if (!UseFMA) { + return NULL; // Generate a vanilla entry + } __ movflt(xmm0, Address(rsp, wordSize)); __ movflt(xmm1, Address(rsp, 2 * wordSize)); __ movflt(xmm2, Address(rsp, 3 * wordSize)); diff --git a/hotspot/src/share/vm/interpreter/abstractInterpreter.cpp b/hotspot/src/share/vm/interpreter/abstractInterpreter.cpp index 1b054792532..c7f3b706df7 100644 --- a/hotspot/src/share/vm/interpreter/abstractInterpreter.cpp +++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.cpp @@ -124,29 +124,19 @@ AbstractInterpreter::MethodKind AbstractInterpreter::method_kind(methodHandle m) } #ifndef CC_INTERP - if (UseCRC32Intrinsics && m->is_native()) { + switch (m->intrinsic_id()) { // Use optimized stub code for CRC32 native methods. - switch (m->intrinsic_id()) { - case vmIntrinsics::_updateCRC32 : return java_util_zip_CRC32_update; - case vmIntrinsics::_updateBytesCRC32 : return java_util_zip_CRC32_updateBytes; - case vmIntrinsics::_updateByteBufferCRC32 : return java_util_zip_CRC32_updateByteBuffer; - } - } - if (UseCRC32CIntrinsics) { + case vmIntrinsics::_updateCRC32 : return java_util_zip_CRC32_update; + case vmIntrinsics::_updateBytesCRC32 : return java_util_zip_CRC32_updateBytes; + case vmIntrinsics::_updateByteBufferCRC32 : return java_util_zip_CRC32_updateByteBuffer; // Use optimized stub code for CRC32C methods. - switch (m->intrinsic_id()) { - case vmIntrinsics::_updateBytesCRC32C : return java_util_zip_CRC32C_updateBytes; - case vmIntrinsics::_updateDirectByteBufferCRC32C : return java_util_zip_CRC32C_updateDirectByteBuffer; - } + case vmIntrinsics::_updateBytesCRC32C : return java_util_zip_CRC32C_updateBytes; + case vmIntrinsics::_updateDirectByteBufferCRC32C : return java_util_zip_CRC32C_updateDirectByteBuffer; + case vmIntrinsics::_intBitsToFloat: return java_lang_Float_intBitsToFloat; + case vmIntrinsics::_floatToRawIntBits: return java_lang_Float_floatToRawIntBits; + case vmIntrinsics::_longBitsToDouble: return java_lang_Double_longBitsToDouble; + case vmIntrinsics::_doubleToRawLongBits: return java_lang_Double_doubleToRawLongBits; } - - switch(m->intrinsic_id()) { - case vmIntrinsics::_intBitsToFloat: return java_lang_Float_intBitsToFloat; - case vmIntrinsics::_floatToRawIntBits: return java_lang_Float_floatToRawIntBits; - case vmIntrinsics::_longBitsToDouble: return java_lang_Double_longBitsToDouble; - case vmIntrinsics::_doubleToRawLongBits: return java_lang_Double_doubleToRawLongBits; - } - #endif // CC_INTERP // Native method? @@ -189,18 +179,13 @@ AbstractInterpreter::MethodKind AbstractInterpreter::method_kind(methodHandle m) case vmIntrinsics::_dlog10: return java_lang_math_log10; case vmIntrinsics::_dpow : return java_lang_math_pow ; case vmIntrinsics::_dexp : return java_lang_math_exp ; + case vmIntrinsics::_fmaD : return java_lang_math_fmaD ; + case vmIntrinsics::_fmaF : return java_lang_math_fmaF ; case vmIntrinsics::_Reference_get: return java_lang_ref_reference_get; } - if (UseFMA) { - switch (m->intrinsic_id()) { - case vmIntrinsics::_fmaD: return java_lang_math_fmaD; - case vmIntrinsics::_fmaF: return java_lang_math_fmaF; - } - } - // Accessor method? if (m->is_getter()) { // TODO: We should have used ::is_accessor above, but fast accessors in Zero expect only getters. diff --git a/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.cpp b/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.cpp index 73de575a731..ebb194a9682 100644 --- a/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.cpp +++ b/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.cpp @@ -239,10 +239,8 @@ void TemplateInterpreterGenerator::generate_all() { method_entry(java_lang_math_log10) method_entry(java_lang_math_exp ) method_entry(java_lang_math_pow ) - if (UseFMA) { - method_entry(java_lang_math_fmaF) - method_entry(java_lang_math_fmaD) - } + method_entry(java_lang_math_fmaF ) + method_entry(java_lang_math_fmaD ) method_entry(java_lang_ref_reference_get) AbstractInterpreter::initialize_method_handle_entries(); @@ -253,16 +251,11 @@ void TemplateInterpreterGenerator::generate_all() { method_entry(native_synchronized) Interpreter::_native_entry_end = Interpreter::code()->code_end(); - if (UseCRC32Intrinsics) { - method_entry(java_util_zip_CRC32_update) - method_entry(java_util_zip_CRC32_updateBytes) - method_entry(java_util_zip_CRC32_updateByteBuffer) - } - - if (UseCRC32CIntrinsics) { - method_entry(java_util_zip_CRC32C_updateBytes) - method_entry(java_util_zip_CRC32C_updateDirectByteBuffer) - } + method_entry(java_util_zip_CRC32_update) + method_entry(java_util_zip_CRC32_updateBytes) + method_entry(java_util_zip_CRC32_updateByteBuffer) + method_entry(java_util_zip_CRC32C_updateBytes) + method_entry(java_util_zip_CRC32C_updateDirectByteBuffer) method_entry(java_lang_Float_intBitsToFloat); method_entry(java_lang_Float_floatToRawIntBits); @@ -451,7 +444,7 @@ address TemplateInterpreterGenerator::generate_method_entry( case Interpreter::java_lang_math_pow : // fall thru case Interpreter::java_lang_math_exp : // fall thru case Interpreter::java_lang_math_fmaD : // fall thru - case Interpreter::java_lang_math_fmaF : entry_point = generate_math_entry(kind); break; + case Interpreter::java_lang_math_fmaF : entry_point = generate_math_entry(kind); break; case Interpreter::java_lang_ref_reference_get : entry_point = generate_Reference_get_entry(); break; case Interpreter::java_util_zip_CRC32_update diff --git a/hotspot/test/runtime/SharedArchiveFile/TestInterpreterMethodEntries.java b/hotspot/test/runtime/SharedArchiveFile/TestInterpreterMethodEntries.java new file mode 100644 index 00000000000..0526d3cdf80 --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/TestInterpreterMethodEntries.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2016, 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 InterpreterMethodEntries + * @bug 8169711 + * @summary Test interpreter method entries for intrinsics with CDS (class data sharing) + * and different settings of the intrinsic flag during dump/use of the archive. + * @library /test/lib + * @modules java.base/jdk.internal.misc + * java.management + * @run main TestInterpreterMethodEntries + */ + +import java.lang.Math; +import java.util.zip.CRC32; +import java.util.zip.CRC32C; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; + +public class TestInterpreterMethodEntries { + + public static void main(String[] args) throws Exception { + if (args.length == 0) { + // Dump and use shared archive with different flag combinations + dumpAndUseSharedArchive("+", "-"); + dumpAndUseSharedArchive("-", "+"); + } else { + // Call intrinsified java.lang.Math::fma() + Math.fma(1.0, 2.0, 3.0); + + byte[] buffer = new byte[256]; + // Call intrinsified java.util.zip.CRC32::update() + CRC32 crc32 = new CRC32(); + crc32.update(buffer, 0, 256); + + // Call intrinsified java.util.zip.CRC32C::updateBytes(..) + CRC32C crc32c = new CRC32C(); + crc32c.update(buffer, 0, 256); + } + } + + private static void dumpAndUseSharedArchive(String dump, String use) throws Exception { + String dumpFMA = "-XX:" + dump + "UseFMA"; + String dumpCRC32 = "-XX:" + dump + "UseCRC32Intrinsics"; + String dumpCRC32C = "-XX:" + dump + "UseCRC32CIntrinsics"; + String useFMA = "-XX:" + use + "UseFMA"; + String useCRC32 = "-XX:" + use + "UseCRC32Intrinsics"; + String useCRC32C = "-XX:" + use + "UseCRC32CIntrinsics"; + + // Dump shared archive + String filename = "./TestInterpreterMethodEntries" + dump + ".jsa"; + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=" + filename, + "-Xshare:dump", + dumpFMA, dumpCRC32, dumpCRC32C); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + CDSTestUtils.checkDump(output); + + // Use shared archive + pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=" + filename, + "-Xshare:on", + useFMA, useCRC32, useCRC32C, + "TestInterpreterMethodEntries", "run"); + output = new OutputAnalyzer(pb.start()); + if (CDSTestUtils.isUnableToMap(output)) { + System.out.println("Unable to map shared archive: test did not complete; assumed PASS"); + return; + } + output.shouldHaveExitValue(0); + } +} + From e52cf63f69320c1e1a622b38a10c2a0a55a7ba9f Mon Sep 17 00:00:00 2001 From: Tobias Hartmann Date: Mon, 21 Nov 2016 09:33:06 +0100 Subject: [PATCH 035/235] 8169941: CodeBlob::is_frame_complete_at() does not honor CodeOffsets::frame_never_safe CodeBlob::is_frame_complete_at() should always return false if _frame_complete_offset is set to CodeOffsets::frame_never_safe (-1). Reviewed-by: kvn, dlong --- hotspot/src/share/vm/code/codeBlob.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/code/codeBlob.hpp b/hotspot/src/share/vm/code/codeBlob.hpp index ff0f9cf8975..b3f9d420127 100644 --- a/hotspot/src/share/vm/code/codeBlob.hpp +++ b/hotspot/src/share/vm/code/codeBlob.hpp @@ -159,7 +159,8 @@ public: bool blob_contains(address addr) const { return header_begin() <= addr && addr < data_end(); } bool code_contains(address addr) const { return code_begin() <= addr && addr < code_end(); } bool contains(address addr) const { return content_begin() <= addr && addr < content_end(); } - bool is_frame_complete_at(address addr) const { return code_contains(addr) && addr >= code_begin() + _frame_complete_offset; } + bool is_frame_complete_at(address addr) const { return _frame_complete_offset != CodeOffsets::frame_never_safe && + code_contains(addr) && addr >= code_begin() + _frame_complete_offset; } // CodeCache support: really only used by the nmethods, but in order to get // asserts and certain bookkeeping to work in the CodeCache they are defined From cbdf3828d8ec9e3535d91e43b70b370b490319e1 Mon Sep 17 00:00:00 2001 From: Andrew Haley Date: Mon, 21 Nov 2016 17:29:17 +0000 Subject: [PATCH 036/235] 8170098: AArch64: VM is extremely slow with JVMTI debugging enabled Reviewed-by: roland --- hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp index 76e0cbeabf8..ed95d410e36 100644 --- a/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp +++ b/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp @@ -407,10 +407,8 @@ void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register // JVMTI events, such as single-stepping, are implemented partly by avoiding running // compiled code in threads for which the event is enabled. Check here for // interp_only_mode if these events CAN be enabled. - // interp_only is an int, on little endian it is sufficient to test the byte only - // Is a cmpl faster? - ldr(rscratch1, Address(rthread, JavaThread::interp_only_mode_offset())); - cbz(rscratch1, run_compiled_code); + ldrw(rscratch1, Address(rthread, JavaThread::interp_only_mode_offset())); + cbzw(rscratch1, run_compiled_code); ldr(rscratch1, Address(method, Method::interpreter_entry_offset())); br(rscratch1); bind(run_compiled_code); From 753b3cf3e61f5257bc5ccd624856999279580efd Mon Sep 17 00:00:00 2001 From: Andrew Haley Date: Mon, 21 Nov 2016 17:38:13 +0000 Subject: [PATCH 037/235] 8170100: AArch64: Crash in C1-compiled code accessing References Reviewed-by: roland --- .../cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp index e3cd202f351..383f26118af 100644 --- a/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp +++ b/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp @@ -886,7 +886,7 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) { // and so we don't need to call the G1 pre-barrier. Thus we can use the // regular method entry code to generate the NPE. // - // This code is based on generate_accessor_enty. + // This code is based on generate_accessor_entry. // // rmethod: Method* // r13: senderSP must preserve for slow path, set SP to it on fast path @@ -904,11 +904,11 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) { __ ldr(local_0, Address(esp, 0)); __ cbz(local_0, slow_path); - // Load the value of the referent field. const Address field_address(local_0, referent_offset); __ load_heap_oop(local_0, field_address); + __ mov(r19, r13); // Move senderSP to a callee-saved register // Generate the G1 pre-barrier code to log the value of // the referent field in an SATB buffer. __ enter(); // g1_write may call runtime @@ -920,7 +920,7 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) { true /* expand_call */); __ leave(); // areturn - __ andr(sp, r13, -16); // done with stack + __ andr(sp, r19, -16); // done with stack __ ret(lr); // generate a vanilla interpreter entry as the slow path From 1b1cffb128c96c6e0fe5fadd8d9de594908b36c8 Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Mon, 21 Nov 2016 21:07:45 -0500 Subject: [PATCH 038/235] 8169870: CDS: "assert(partition_size <= size()) failed: partition failed" on 32 bit JVM Exit the VM and report error if the second ReservedSpace() call also fails. Reviewed-by: cjplummer, sspitsyn, iklam --- hotspot/src/share/vm/memory/metaspace.cpp | 4 +++ .../SharedArchiveFile/LargeSharedSpace.java | 31 +++++++++++++------ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 948629b6684..d5843df1077 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -489,6 +489,10 @@ VirtualSpaceNode::VirtualSpaceNode(size_t bytes) : _top(NULL), _next(NULL), _rs( // Get a mmap region anywhere if the SharedBaseAddress fails. _rs = ReservedSpace(bytes, Metaspace::reserve_alignment(), large_pages); } + if (!_rs.is_reserved()) { + vm_exit_during_initialization("Unable to allocate memory for shared space", + err_msg(SIZE_FORMAT " bytes.", bytes)); + } MetaspaceShared::initialize_shared_rs(&_rs); } else #endif diff --git a/hotspot/test/runtime/SharedArchiveFile/LargeSharedSpace.java b/hotspot/test/runtime/SharedArchiveFile/LargeSharedSpace.java index e84c350c421..1d62853c314 100644 --- a/hotspot/test/runtime/SharedArchiveFile/LargeSharedSpace.java +++ b/hotspot/test/runtime/SharedArchiveFile/LargeSharedSpace.java @@ -23,10 +23,10 @@ /* * @test LargeSharedSpace - * @bug 8168790 + * @bug 8168790 8169870 * @summary Test CDS dumping with specific space size. - * The space size used in the test might not be suitable on windows and 32-bit platforms. - * @requires (sun.arch.data.model != "32") & (os.family != "windows") + * The space size used in the test might not be suitable on windows. + * @requires (os.family != "windows") * @library /test/lib * @modules java.base/jdk.internal.misc * java.management @@ -38,11 +38,24 @@ import jdk.test.lib.process.OutputAnalyzer; public class LargeSharedSpace { public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - "-XX:SharedMiscCodeSize=1066924031", "-XX:+UnlockDiagnosticVMOptions", - "-XX:SharedArchiveFile=./LargeSharedSpace.jsa", "-Xshare:dump"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("Loading classes to share"); - output.shouldHaveExitValue(0); + String sizes[] = {"1066924031", "1600386047"}; + String expectedOutputs[] = + {/* can dump using the given size */ + "Loading classes to share", + /* the size is too large, exceeding the limit for compressed klass support */ + "larger than compressed klass limit"}; + for (int i = 0; i < sizes.length; i++) { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:SharedMiscCodeSize="+sizes[i], "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=./LargeSharedSpace.jsa", "-Xshare:dump"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + try { + output.shouldContain(expectedOutputs[i]); + } catch (RuntimeException e) { + /* failed to reserve the memory for the required size, might happen + on 32-bit platforms */ + output.shouldContain("Unable to allocate memory for shared space"); + } + } } } From ba634d1749abb86714106ce3e9a4571675152c51 Mon Sep 17 00:00:00 2001 From: Michail Chernov Date: Tue, 22 Nov 2016 16:13:13 +0300 Subject: [PATCH 039/235] 8168396: Unexpected OOME in GcCauseTest02 and GcTest02 Reviewed-by: tschatzl, dfazunen --- .../tmtools/jstat/GcCapacityTest.java | 2 +- .../tmtools/jstat/GcCauseTest01.java | 2 +- .../tmtools/jstat/GcCauseTest02.java | 10 +- .../tmtools/jstat/GcNewTest.java | 2 +- .../tmtools/jstat/GcTest01.java | 2 +- .../tmtools/jstat/GcTest02.java | 10 +- .../tmtools/jstat/utils/GcProvoker.java | 132 ++++++++++++++++-- 7 files changed, 133 insertions(+), 27 deletions(-) diff --git a/hotspot/test/serviceability/tmtools/jstat/GcCapacityTest.java b/hotspot/test/serviceability/tmtools/jstat/GcCapacityTest.java index 08b72d1f2aa..6723e6e02d1 100644 --- a/hotspot/test/serviceability/tmtools/jstat/GcCapacityTest.java +++ b/hotspot/test/serviceability/tmtools/jstat/GcCapacityTest.java @@ -45,7 +45,7 @@ public class GcCapacityTest { measurement1.assertConsistency(); // Provoke a gc and verify the changed values - GcProvoker gcProvoker = GcProvoker.createGcProvoker(); + GcProvoker gcProvoker = new GcProvoker(); gcProvoker.provokeGc(); JstatGcCapacityResults measurement2 = jstatGcTool.measure(); measurement2.assertConsistency(); diff --git a/hotspot/test/serviceability/tmtools/jstat/GcCauseTest01.java b/hotspot/test/serviceability/tmtools/jstat/GcCauseTest01.java index 60c0a60c092..9e4c5eb2e64 100644 --- a/hotspot/test/serviceability/tmtools/jstat/GcCauseTest01.java +++ b/hotspot/test/serviceability/tmtools/jstat/GcCauseTest01.java @@ -47,7 +47,7 @@ public class GcCauseTest01 { JstatGcCauseResults measurement1 = jstatGcTool.measure(); measurement1.assertConsistency(); - GcProvoker gcProvoker = GcProvoker.createGcProvoker(); + GcProvoker gcProvoker = new GcProvoker(); // Provoke GC then run the tool again and get the results asserting that they are reasonable gcProvoker.provokeGc(); diff --git a/hotspot/test/serviceability/tmtools/jstat/GcCauseTest02.java b/hotspot/test/serviceability/tmtools/jstat/GcCauseTest02.java index 56ef9387cf8..2bdf04d39c2 100644 --- a/hotspot/test/serviceability/tmtools/jstat/GcCauseTest02.java +++ b/hotspot/test/serviceability/tmtools/jstat/GcCauseTest02.java @@ -27,11 +27,11 @@ * Test scenario: * tests forces debuggee application eat ~70% of heap and runs jstat. * jstat should show that ~70% of heap (OC/OU ~= 70%). + * @requires vm.opt.ExplicitGCInvokesConcurrent != true * @modules java.base/jdk.internal.misc * @library /test/lib * @library ../share - * @ignore 8168396 - * @run main/othervm -XX:+UsePerfData -Xmx128M -XX:MaxMetaspaceSize=128M GcCauseTest02 + * @run main/othervm -XX:+UsePerfData -XX:InitialHeapSize=128M -XX:MaxHeapSize=128M -XX:MaxMetaspaceSize=128M GcCauseTest02 */ import utils.*; @@ -48,10 +48,12 @@ public class GcCauseTest02 { JstatGcCauseResults measurement1 = jstatGcTool.measure(); measurement1.assertConsistency(); - GcProvoker gcProvoker = GcProvoker.createGcProvoker(); + GcProvoker gcProvoker = new GcProvoker(); // Eat metaspace and heap then run the tool again and get the results asserting that they are reasonable - gcProvoker.eatMetaspaceAndHeap(targetMemoryUsagePercent); + gcProvoker.allocateAvailableMetaspaceAndHeap(targetMemoryUsagePercent); + // Collect garbage. Also update VM statistics + System.gc(); JstatGcCauseResults measurement2 = jstatGcTool.measure(); measurement2.assertConsistency(); diff --git a/hotspot/test/serviceability/tmtools/jstat/GcNewTest.java b/hotspot/test/serviceability/tmtools/jstat/GcNewTest.java index 10a8e60cd2a..8e1d6ae364a 100644 --- a/hotspot/test/serviceability/tmtools/jstat/GcNewTest.java +++ b/hotspot/test/serviceability/tmtools/jstat/GcNewTest.java @@ -46,7 +46,7 @@ public class GcNewTest { JstatGcNewResults measurement1 = jstatGcTool.measure(); measurement1.assertConsistency(); - GcProvoker gcProvoker = GcProvoker.createGcProvoker(); + GcProvoker gcProvoker = new GcProvoker(); // Provoke GC and run the tool again gcProvoker.provokeGc(); diff --git a/hotspot/test/serviceability/tmtools/jstat/GcTest01.java b/hotspot/test/serviceability/tmtools/jstat/GcTest01.java index cabfc9ec80a..cc0bf5261e2 100644 --- a/hotspot/test/serviceability/tmtools/jstat/GcTest01.java +++ b/hotspot/test/serviceability/tmtools/jstat/GcTest01.java @@ -50,7 +50,7 @@ public class GcTest01 { JstatGcResults measurement1 = jstatGcTool.measure(); measurement1.assertConsistency(); - GcProvoker gcProvoker = GcProvoker.createGcProvoker(); + GcProvoker gcProvoker = new GcProvoker(); // Provoke GC then run the tool again and get the results // asserting that they are reasonable diff --git a/hotspot/test/serviceability/tmtools/jstat/GcTest02.java b/hotspot/test/serviceability/tmtools/jstat/GcTest02.java index c46b4ad5b5d..91406fa3838 100644 --- a/hotspot/test/serviceability/tmtools/jstat/GcTest02.java +++ b/hotspot/test/serviceability/tmtools/jstat/GcTest02.java @@ -28,11 +28,11 @@ import utils.*; * Test scenario: * tests forces debuggee application eat ~70% of heap and runs jstat. * jstat should show that ~70% of heap is utilized (OC/OU ~= 70%). + * @requires vm.opt.ExplicitGCInvokesConcurrent != true * @modules java.base/jdk.internal.misc * @library /test/lib * @library ../share - * @ignore 8168396 - * @run main/othervm -XX:+UsePerfData -Xmx128M -XX:MaxMetaspaceSize=128M GcTest02 + * @run main/othervm -XX:+UsePerfData -XX:InitialHeapSize=128M -XX:MaxHeapSize=128M -XX:MaxMetaspaceSize=128M GcTest02 */ public class GcTest02 { @@ -48,10 +48,12 @@ public class GcTest02 { JstatGcResults measurement1 = jstatGcTool.measure(); measurement1.assertConsistency(); - GcProvoker gcProvoker = GcProvoker.createGcProvoker(); + GcProvoker gcProvoker = new GcProvoker(); // Eat metaspace and heap then run the tool again and get the results asserting that they are reasonable - gcProvoker.eatMetaspaceAndHeap(targetMemoryUsagePercent); + gcProvoker.allocateAvailableMetaspaceAndHeap(targetMemoryUsagePercent); + // Collect garbage. Also updates VM statistics + System.gc(); JstatGcResults measurement2 = jstatGcTool.measure(); measurement2.assertConsistency(); diff --git a/hotspot/test/serviceability/tmtools/jstat/utils/GcProvoker.java b/hotspot/test/serviceability/tmtools/jstat/utils/GcProvoker.java index 697b4225452..f2111fa5724 100644 --- a/hotspot/test/serviceability/tmtools/jstat/utils/GcProvoker.java +++ b/hotspot/test/serviceability/tmtools/jstat/utils/GcProvoker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, 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 @@ -22,34 +22,136 @@ */ package utils; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryPoolMXBean; +import java.lang.management.MemoryUsage; +import java.util.ArrayList; +import java.util.List; + /** - * This is an interface used to provoke GC and perform other GC-related + * This is an class used to provoke GC and perform other GC-related * procedures * */ -public interface GcProvoker { +public class GcProvoker{ - /** - * The default implementation - * - * @return the default GC provoker - */ - public static GcProvoker createGcProvoker() { - return new GcProvokerImpl(); + // Uses fixed small objects to avoid Humongous objects allocation in G1 + public static final int MEMORY_CHUNK = 2048; + public static final float ALLOCATION_TOLERANCE = 0.05f; + + public static List allocatedMetaspace; + public static List allocatedMemory; + + private final Runtime runtime; + + private List allocateHeap(float targetUsage) { + long maxMemory = runtime.maxMemory(); + List list = new ArrayList<>(); + long used = 0; + long target = (long) (maxMemory * targetUsage); + while (used < target) { + try { + list.add(new byte[MEMORY_CHUNK]); + used += MEMORY_CHUNK; + } catch (OutOfMemoryError e) { + list = null; + throw new RuntimeException("Unexpected OOME '" + e.getMessage() + "' while eating " + targetUsage + " of heap memory."); + } + } + return list; + } + + private List allocateAvailableHeap(float targetUsage) { + // Calculates size of free memory after allocation with small tolerance. + long minFreeMemory = (long) ((1.0 - (targetUsage + ALLOCATION_TOLERANCE)) * runtime.maxMemory()); + List list = new ArrayList<>(); + do { + try { + list.add(new byte[MEMORY_CHUNK]); + } catch (OutOfMemoryError e) { + list = null; + throw new RuntimeException("Unexpected OOME '" + e.getMessage() + "' while eating " + targetUsage + " of heap memory."); + } + } while (runtime.freeMemory() > minFreeMemory); + return list; } /** * This method provokes a GC */ - public void provokeGc(); + public void provokeGc() { + for (int i = 0; i < 3; i++) { + long edenSize = Pools.getEdenCommittedSize(); + long heapSize = Pools.getHeapCommittedSize(); + float targetPercent = ((float) edenSize) / (heapSize); + if ((targetPercent < 0) || (targetPercent > 1.0)) { + throw new RuntimeException("Error in the percent calculation" + " (eden size: " + edenSize + ", heap size: " + heapSize + ", calculated eden percent: " + targetPercent + ")"); + } + allocateHeap(targetPercent); + allocateHeap(targetPercent); + System.gc(); + } + } /** - * Eats heap and metaspace Upon exit targetMemoryUsagePercent percents of - * heap and metaspace is have been eaten + * Allocates heap and metaspace upon exit not less than targetMemoryUsagePercent percents + * of heap and metaspace have been consumed. * * @param targetMemoryUsagePercent how many percent of heap and metaspace to - * eat + * allocate */ - public void eatMetaspaceAndHeap(float targetMemoryUsagePercent); + + public void allocateMetaspaceAndHeap(float targetMemoryUsagePercent) { + // Metaspace should be filled before Java Heap to prevent unexpected OOME + // in the Java Heap while filling Metaspace + allocatedMetaspace = eatMetaspace(targetMemoryUsagePercent); + allocatedMemory = allocateHeap(targetMemoryUsagePercent); + } + + /** + * Allocates heap and metaspace upon exit targetMemoryUsagePercent percents + * of heap and metaspace have been consumed. + * + * @param targetMemoryUsagePercent how many percent of heap and metaspace to + * allocate + */ + public void allocateAvailableMetaspaceAndHeap(float targetMemoryUsagePercent) { + // Metaspace should be filled before Java Heap to prevent unexpected OOME + // in the Java Heap while filling Metaspace + allocatedMetaspace = eatMetaspace(targetMemoryUsagePercent); + allocatedMemory = allocateAvailableHeap(targetMemoryUsagePercent); + } + + private List eatMetaspace(float targetUsage) { + List list = new ArrayList<>(); + final String metaspacePoolName = "Metaspace"; + MemoryPoolMXBean metaspacePool = null; + for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) { + if (pool.getName().contains(metaspacePoolName)) { + metaspacePool = pool; + break; + } + } + if (metaspacePool == null) { + throw new RuntimeException("MXBean for Metaspace pool wasn't found"); + } + float currentUsage; + GeneratedClassProducer gp = new GeneratedClassProducer(); + do { + try { + list.add(gp.create(0)); + } catch (OutOfMemoryError oome) { + list = null; + throw new RuntimeException("Unexpected OOME '" + oome.getMessage() + "' while eating " + targetUsage + " of Metaspace."); + } + MemoryUsage memoryUsage = metaspacePool.getUsage(); + currentUsage = (((float) memoryUsage.getUsed()) / memoryUsage.getMax()); + } while (currentUsage < targetUsage); + return list; + } + + public GcProvoker() { + runtime = Runtime.getRuntime(); + } } From 56ed7077a8e795ed6607f2598cc02d759d7d9b29 Mon Sep 17 00:00:00 2001 From: Michael Berg Date: Tue, 22 Nov 2016 11:34:11 -0800 Subject: [PATCH 040/235] 8170039: Change UseAVX < 3 on SKX/KNL to not emit evex vector check Reviewed-by: kvn --- hotspot/src/cpu/x86/vm/vm_version_x86.cpp | 91 ++++++++++++----------- 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp index 93c6e580062..7bed10749f7 100644 --- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp +++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp @@ -65,6 +65,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator { const int CPU_FAMILY_SHIFT = 8; const uint32_t CPU_FAMILY_386 = (3 << CPU_FAMILY_SHIFT); const uint32_t CPU_FAMILY_486 = (4 << CPU_FAMILY_SHIFT); + bool use_evex = FLAG_IS_DEFAULT(UseAVX) || (UseAVX > 2); Label detect_486, cpu486, detect_586, std_cpuid1, std_cpuid4; Label sef_cpuid, ext_cpuid, ext_cpuid1, ext_cpuid5, ext_cpuid7, done, wrapup; @@ -358,36 +359,39 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ cmpl(rax, 0xE0); __ jccb(Assembler::notEqual, legacy_setup); // jump if EVEX is not supported - // EVEX setup: run in lowest evex mode - VM_Version::set_evex_cpuFeatures(); // Enable temporary to pass asserts - UseAVX = 3; - UseSSE = 2; + // If UseAVX is unitialized or is set by the user to include EVEX + if (use_evex) { + // EVEX setup: run in lowest evex mode + VM_Version::set_evex_cpuFeatures(); // Enable temporary to pass asserts + UseAVX = 3; + UseSSE = 2; #ifdef _WINDOWS - // xmm5-xmm15 are not preserved by caller on windows - // https://msdn.microsoft.com/en-us/library/9z1stfyw.aspx - __ subptr(rsp, 64); - __ evmovdqul(Address(rsp, 0), xmm7, Assembler::AVX_512bit); + // xmm5-xmm15 are not preserved by caller on windows + // https://msdn.microsoft.com/en-us/library/9z1stfyw.aspx + __ subptr(rsp, 64); + __ evmovdqul(Address(rsp, 0), xmm7, Assembler::AVX_512bit); #ifdef _LP64 - __ subptr(rsp, 64); - __ evmovdqul(Address(rsp, 0), xmm8, Assembler::AVX_512bit); - __ subptr(rsp, 64); - __ evmovdqul(Address(rsp, 0), xmm31, Assembler::AVX_512bit); + __ subptr(rsp, 64); + __ evmovdqul(Address(rsp, 0), xmm8, Assembler::AVX_512bit); + __ subptr(rsp, 64); + __ evmovdqul(Address(rsp, 0), xmm31, Assembler::AVX_512bit); #endif // _LP64 #endif // _WINDOWS - // load value into all 64 bytes of zmm7 register - __ movl(rcx, VM_Version::ymm_test_value()); - __ movdl(xmm0, rcx); - __ movl(rcx, 0xffff); - __ kmovwl(k1, rcx); - __ evpbroadcastd(xmm0, xmm0, Assembler::AVX_512bit); - __ evmovdqul(xmm7, xmm0, Assembler::AVX_512bit); + // load value into all 64 bytes of zmm7 register + __ movl(rcx, VM_Version::ymm_test_value()); + __ movdl(xmm0, rcx); + __ movl(rcx, 0xffff); + __ kmovwl(k1, rcx); + __ evpbroadcastd(xmm0, xmm0, Assembler::AVX_512bit); + __ evmovdqul(xmm7, xmm0, Assembler::AVX_512bit); #ifdef _LP64 - __ evmovdqul(xmm8, xmm0, Assembler::AVX_512bit); - __ evmovdqul(xmm31, xmm0, Assembler::AVX_512bit); + __ evmovdqul(xmm8, xmm0, Assembler::AVX_512bit); + __ evmovdqul(xmm31, xmm0, Assembler::AVX_512bit); #endif - VM_Version::clean_cpuFeatures(); - __ jmp(save_restore_except); + VM_Version::clean_cpuFeatures(); + __ jmp(save_restore_except); + } __ bind(legacy_setup); // AVX setup @@ -441,32 +445,35 @@ class VM_Version_StubGenerator: public StubCodeGenerator { __ cmpl(rax, 0xE0); __ jccb(Assembler::notEqual, legacy_save_restore); - // EVEX check: run in lowest evex mode - VM_Version::set_evex_cpuFeatures(); // Enable temporary to pass asserts - UseAVX = 3; - UseSSE = 2; - __ lea(rsi, Address(rbp, in_bytes(VM_Version::zmm_save_offset()))); - __ evmovdqul(Address(rsi, 0), xmm0, Assembler::AVX_512bit); - __ evmovdqul(Address(rsi, 64), xmm7, Assembler::AVX_512bit); + // If UseAVX is unitialized or is set by the user to include EVEX + if (use_evex) { + // EVEX check: run in lowest evex mode + VM_Version::set_evex_cpuFeatures(); // Enable temporary to pass asserts + UseAVX = 3; + UseSSE = 2; + __ lea(rsi, Address(rbp, in_bytes(VM_Version::zmm_save_offset()))); + __ evmovdqul(Address(rsi, 0), xmm0, Assembler::AVX_512bit); + __ evmovdqul(Address(rsi, 64), xmm7, Assembler::AVX_512bit); #ifdef _LP64 - __ evmovdqul(Address(rsi, 128), xmm8, Assembler::AVX_512bit); - __ evmovdqul(Address(rsi, 192), xmm31, Assembler::AVX_512bit); + __ evmovdqul(Address(rsi, 128), xmm8, Assembler::AVX_512bit); + __ evmovdqul(Address(rsi, 192), xmm31, Assembler::AVX_512bit); #endif #ifdef _WINDOWS #ifdef _LP64 - __ evmovdqul(xmm31, Address(rsp, 0), Assembler::AVX_512bit); - __ addptr(rsp, 64); - __ evmovdqul(xmm8, Address(rsp, 0), Assembler::AVX_512bit); - __ addptr(rsp, 64); + __ evmovdqul(xmm31, Address(rsp, 0), Assembler::AVX_512bit); + __ addptr(rsp, 64); + __ evmovdqul(xmm8, Address(rsp, 0), Assembler::AVX_512bit); + __ addptr(rsp, 64); #endif // _LP64 - __ evmovdqul(xmm7, Address(rsp, 0), Assembler::AVX_512bit); - __ addptr(rsp, 64); + __ evmovdqul(xmm7, Address(rsp, 0), Assembler::AVX_512bit); + __ addptr(rsp, 64); #endif // _WINDOWS - VM_Version::clean_cpuFeatures(); - UseAVX = saved_useavx; - UseSSE = saved_usesse; - __ jmp(wrapup); + VM_Version::clean_cpuFeatures(); + UseAVX = saved_useavx; + UseSSE = saved_usesse; + __ jmp(wrapup); + } __ bind(legacy_save_restore); // AVX check From 1170f8e5c80f4753fa30f8111768d66180d46c30 Mon Sep 17 00:00:00 2001 From: Vivek Deshpande Date: Tue, 22 Nov 2016 13:59:45 -0800 Subject: [PATCH 041/235] 8165287: fix compress intrinsics to produce correct results with avx512 Reviewed-by: kvn --- hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp | 45 ++++++------------- 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp index 99286eaa9da..3d4dee751a5 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp @@ -10773,16 +10773,13 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register le // save length for return push(len); - // 8165287: EVEX version disabled for now, needs to be refactored as - // it is returning incorrect results. if ((UseAVX > 2) && // AVX512 - 0 && VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()) { set_vector_masking(); // opening of the stub context for programming mask registers - Label copy_32_loop, copy_loop_tail, copy_just_portion_of_candidates; + Label copy_32_loop, copy_loop_tail, restore_k1_return_zero; // alignement Label post_alignement; @@ -10797,16 +10794,16 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register le movl(result, 0x00FF); evpbroadcastw(tmp2Reg, result, Assembler::AVX_512bit); - testl(len, -64); - jcc(Assembler::zero, post_alignement); - // Save k1 kmovql(k3, k1); + testl(len, -64); + jcc(Assembler::zero, post_alignement); + movl(tmp5, dst); - andl(tmp5, (64 - 1)); + andl(tmp5, (32 - 1)); negl(tmp5); - andl(tmp5, (64 - 1)); + andl(tmp5, (32 - 1)); // bail out when there is nothing to be done testl(tmp5, 0xFFFFFFFF); @@ -10816,13 +10813,12 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register le movl(result, 0xFFFFFFFF); shlxl(result, result, tmp5); notl(result); - kmovdl(k1, result); evmovdquw(tmp1Reg, k1, Address(src, 0), Assembler::AVX_512bit); evpcmpuw(k2, k1, tmp1Reg, tmp2Reg, Assembler::le, Assembler::AVX_512bit); ktestd(k2, k1); - jcc(Assembler::carryClear, copy_just_portion_of_candidates); + jcc(Assembler::carryClear, restore_k1_return_zero); evpmovwb(Address(dst, 0), k1, tmp1Reg, Assembler::AVX_512bit); @@ -10835,7 +10831,7 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register le // end of alignement movl(tmp5, len); - andl(tmp5, (32 - 1)); // tail count (in chars) + andl(tmp5, (32 - 1)); // tail count (in chars) andl(len, ~(32 - 1)); // vector count (in chars) jcc(Assembler::zero, copy_loop_tail); @@ -10847,7 +10843,7 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register le evmovdquw(tmp1Reg, Address(src, len, Address::times_2), Assembler::AVX_512bit); evpcmpuw(k2, tmp1Reg, tmp2Reg, Assembler::le, Assembler::AVX_512bit); kortestdl(k2, k2); - jcc(Assembler::carryClear, copy_just_portion_of_candidates); + jcc(Assembler::carryClear, restore_k1_return_zero); // All elements in current processed chunk are valid candidates for // compression. Write a truncated byte elements to the memory. @@ -10858,11 +10854,10 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register le bind(copy_loop_tail); // bail out when there is nothing to be done testl(tmp5, 0xFFFFFFFF); + // Restore k1 + kmovql(k1, k3); jcc(Assembler::zero, return_length); - // Save k1 - kmovql(k3, k1); - movl(len, tmp5); // ~(~0 << len), where len is the # of remaining elements to process @@ -10875,30 +10870,16 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register le evmovdquw(tmp1Reg, k1, Address(src, 0), Assembler::AVX_512bit); evpcmpuw(k2, k1, tmp1Reg, tmp2Reg, Assembler::le, Assembler::AVX_512bit); ktestd(k2, k1); - jcc(Assembler::carryClear, copy_just_portion_of_candidates); + jcc(Assembler::carryClear, restore_k1_return_zero); evpmovwb(Address(dst, 0), k1, tmp1Reg, Assembler::AVX_512bit); // Restore k1 kmovql(k1, k3); - jmp(return_length); - bind(copy_just_portion_of_candidates); - kmovdl(tmp5, k2); - tzcntl(tmp5, tmp5); - - // ~(~0 << tmp5), where tmp5 is a number of elements in an array from the - // result to the first element larger than 0xFF - movl(result, 0xFFFFFFFF); - shlxl(result, result, tmp5); - notl(result); - - kmovdl(k1, result); - - evpmovwb(Address(dst, 0), k1, tmp1Reg, Assembler::AVX_512bit); + bind(restore_k1_return_zero); // Restore k1 kmovql(k1, k3); - jmp(return_zero); clear_vector_masking(); // closing of the stub context for programming mask registers From 213906ee83d0a884dcc37893908964499b7cb5a7 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Tue, 22 Nov 2016 20:24:47 -0500 Subject: [PATCH 042/235] 8166607: G1 needs klass_or_null_acquire Use acquire where needed, split refinment humongous and non to simplify. Reviewed-by: tschatzl, ehelin --- .../src/share/vm/gc/g1/g1BlockOffsetTable.cpp | 2 +- .../vm/gc/g1/g1BlockOffsetTable.inline.hpp | 4 +- hotspot/src/share/vm/gc/g1/g1RemSet.cpp | 7 +- hotspot/src/share/vm/gc/g1/heapRegion.cpp | 120 ++++++++++++------ hotspot/src/share/vm/gc/g1/heapRegion.hpp | 2 +- 5 files changed, 88 insertions(+), 47 deletions(-) diff --git a/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp index 3a50ee45a6b..435bd5a6116 100644 --- a/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp +++ b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp @@ -227,7 +227,7 @@ HeapWord* G1BlockOffsetTablePart::forward_to_block_containing_addr_slow(HeapWord while (n <= next_boundary) { q = n; oop obj = oop(q); - if (obj->klass_or_null() == NULL) return q; + if (obj->klass_or_null_acquire() == NULL) return q; n += block_size(q); } assert(q <= next_boundary && n > next_boundary, "Consequence of loop"); diff --git a/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.inline.hpp b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.inline.hpp index f207f2586ba..9788eed0bfe 100644 --- a/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.inline.hpp +++ b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.inline.hpp @@ -136,7 +136,7 @@ inline HeapWord* G1BlockOffsetTablePart::forward_to_block_containing_addr_const( while (n <= addr) { q = n; oop obj = oop(q); - if (obj->klass_or_null() == NULL) { + if (obj->klass_or_null_acquire() == NULL) { return q; } n += block_size(q); @@ -148,7 +148,7 @@ inline HeapWord* G1BlockOffsetTablePart::forward_to_block_containing_addr_const( inline HeapWord* G1BlockOffsetTablePart::forward_to_block_containing_addr(HeapWord* q, const void* addr) { - if (oop(q)->klass_or_null() == NULL) { + if (oop(q)->klass_or_null_acquire() == NULL) { return q; } HeapWord* n = q + block_size(q); diff --git a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp index ccb8fbdd2fd..61e7523cd0d 100644 --- a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp +++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp @@ -675,9 +675,10 @@ bool G1RemSet::refine_card(jbyte* card_ptr, card_ptr); // If unable to process the card then we encountered an unparsable - // part of the heap (e.g. a partially allocated object). Redirty - // and re-enqueue: if we put off the card until a GC pause, then the - // allocation will have completed. + // part of the heap (e.g. a partially allocated object) while + // processing a stale card. Despite the card being stale, redirty + // and re-enqueue, because we've already cleaned the card. Without + // this we could incorrectly discard a non-stale card. if (!card_processed) { assert(!_g1->is_gc_active(), "Unparsable heap during GC"); // The card might have gotten re-dirtied and re-enqueued while we diff --git a/hotspot/src/share/vm/gc/g1/heapRegion.cpp b/hotspot/src/share/vm/gc/g1/heapRegion.cpp index f2df4a3c5b8..e787719fb1b 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp +++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp @@ -352,6 +352,49 @@ void HeapRegion::note_self_forwarding_removal_end(bool during_initial_mark, _prev_marked_bytes = marked_bytes; } +// Humongous objects are allocated directly in the old-gen. Need +// special handling for concurrent processing encountering an +// in-progress allocation. +static bool do_oops_on_card_in_humongous(MemRegion mr, + FilterOutOfRegionClosure* cl, + HeapRegion* hr, + G1CollectedHeap* g1h) { + assert(hr->is_humongous(), "precondition"); + HeapRegion* sr = hr->humongous_start_region(); + oop obj = oop(sr->bottom()); + + // If concurrent and klass_or_null is NULL, then space has been + // allocated but the object has not yet been published by setting + // the klass. That can only happen if the card is stale. However, + // we've already set the card clean, so we must return failure, + // since the allocating thread could have performed a write to the + // card that might be missed otherwise. + if (!g1h->is_gc_active() && (obj->klass_or_null_acquire() == NULL)) { + return false; + } + + // Only filler objects follow a humongous object in the containing + // regions, and we can ignore those. So only process the one + // humongous object. + if (!g1h->is_obj_dead(obj, sr)) { + if (obj->is_objArray() || (sr->bottom() < mr.start())) { + // objArrays are always marked precisely, so limit processing + // with mr. Non-objArrays might be precisely marked, and since + // it's humongous it's worthwhile avoiding full processing. + // However, the card could be stale and only cover filler + // objects. That should be rare, so not worth checking for; + // instead let it fall out from the bounded iteration. + obj->oop_iterate(cl, mr); + } else { + // If obj is not an objArray and mr contains the start of the + // obj, then this could be an imprecise mark, and we need to + // process the entire object. + obj->oop_iterate(cl); + } + } + return true; +} + bool HeapRegion::oops_on_card_seq_iterate_careful(MemRegion mr, FilterOutOfRegionClosure* cl, jbyte* card_ptr) { @@ -369,7 +412,6 @@ bool HeapRegion::oops_on_card_seq_iterate_careful(MemRegion mr, if (mr.is_empty()) { return true; } - // Otherwise, find the obj that extends onto mr.start(). // The intersection of the incoming mr (for the card) and the // allocated part of the region is non-empty. This implies that @@ -387,54 +429,52 @@ bool HeapRegion::oops_on_card_seq_iterate_careful(MemRegion mr, // We must complete this write before we do any of the reads below. OrderAccess::storeload(); + // Special handling for humongous regions. + if (is_humongous()) { + return do_oops_on_card_in_humongous(mr, cl, this, g1h); + } + + // During GC we limit mr by scan_top. So we never get here with an + // mr covering objects allocated during GC. Non-humongous objects + // are only allocated in the old-gen during GC. So the parts of the + // heap that may be examined here are always parsable; there's no + // need to use klass_or_null here to detect in-progress allocations. + // Cache the boundaries of the memory region in some const locals HeapWord* const start = mr.start(); HeapWord* const end = mr.end(); - // Update BOT as needed while finding start of (potential) object. + // Find the obj that extends onto mr.start(). + // Update BOT as needed while finding start of (possibly dead) + // object containing the start of the region. HeapWord* cur = block_start(start); - assert(cur <= start, "Postcondition"); - oop obj; - - HeapWord* next = cur; - do { - cur = next; - obj = oop(cur); - if (obj->klass_or_null() == NULL) { - // Ran into an unparseable point. - assert(!g1h->is_gc_active(), - "Unparsable heap during GC at " PTR_FORMAT, p2i(cur)); - return false; - } - // Otherwise... - next = cur + block_size(cur); - } while (next <= start); - - // If we finish the above loop...We have a parseable object that - // begins on or before the start of the memory region, and ends - // inside or spans the entire region. - assert(cur <= start, "Loop postcondition"); - assert(obj->klass_or_null() != NULL, "Loop postcondition"); +#ifdef ASSERT + { + assert(cur <= start, + "cur: " PTR_FORMAT ", start: " PTR_FORMAT, p2i(cur), p2i(start)); + HeapWord* next = cur + block_size(cur); + assert(start < next, + "start: " PTR_FORMAT ", next: " PTR_FORMAT, p2i(start), p2i(next)); + } +#endif do { - obj = oop(cur); - assert((cur + block_size(cur)) > (HeapWord*)obj, "Loop invariant"); - if (obj->klass_or_null() == NULL) { - // Ran into an unparseable point. - assert(!g1h->is_gc_active(), - "Unparsable heap during GC at " PTR_FORMAT, p2i(cur)); - return false; - } + oop obj = oop(cur); + assert(obj->is_oop(true), "Not an oop at " PTR_FORMAT, p2i(cur)); + assert(obj->klass_or_null() != NULL, + "Unparsable heap at " PTR_FORMAT, p2i(cur)); - // Advance the current pointer. "obj" still points to the object to iterate. - cur = cur + block_size(cur); - - if (!g1h->is_obj_dead(obj)) { - // Non-objArrays are sometimes marked imprecise at the object start. We - // always need to iterate over them in full. - // We only iterate over object arrays in full if they are completely contained - // in the memory region. + if (g1h->is_obj_dead(obj, this)) { + // Carefully step over dead object. + cur += block_size(cur); + } else { + // Step over live object, and process its references. + cur += obj->size(); + // Non-objArrays are usually marked imprecise at the object + // start, in which case we need to iterate over them in full. + // objArrays are precisely marked, but can still be iterated + // over in full if completely covered. if (!obj->is_objArray() || (((HeapWord*)obj) >= start && cur <= end)) { obj->oop_iterate(cl); } else { diff --git a/hotspot/src/share/vm/gc/g1/heapRegion.hpp b/hotspot/src/share/vm/gc/g1/heapRegion.hpp index 7f4de70b597..3410cbcd11e 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegion.hpp +++ b/hotspot/src/share/vm/gc/g1/heapRegion.hpp @@ -658,7 +658,7 @@ class HeapRegion: public G1ContiguousSpace { // mr: the memory region covered by the card. // card_ptr: if we decide that the card is not young and we iterate // over it, we'll clean the card before we start the iteration. - // Returns true if card was successfully processed, false if an + // Returns true if the card was successfully processed, false if an // unparsable part of the heap was encountered, which should only // happen when invoked concurrently with the mutator. bool oops_on_card_seq_iterate_careful(MemRegion mr, From 358f09e305c4ee5b0c3dd300972e6f7b4d3f899c Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Tue, 22 Nov 2016 20:50:31 -0500 Subject: [PATCH 043/235] 8166811: Missing memory fences between memory allocation and refinement Refactored to have needed barrier Reviewed-by: tschatzl, ehelin --- .../src/share/vm/gc/g1/g1CollectedHeap.cpp | 2 + hotspot/src/share/vm/gc/g1/g1RemSet.cpp | 118 ++++++++++++------ hotspot/src/share/vm/gc/g1/heapRegion.cpp | 44 ++----- hotspot/src/share/vm/gc/g1/heapRegion.hpp | 28 +++-- hotspot/src/share/vm/gc/g1/heapRegionType.hpp | 4 +- 5 files changed, 106 insertions(+), 90 deletions(-) diff --git a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp index 1ba5cb7b51b..3bcd4675c23 100644 --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp @@ -300,6 +300,8 @@ G1CollectedHeap::humongous_obj_allocate_initialize_regions(uint first, // thread to calculate the object size incorrectly. Copy::fill_to_words(new_obj, oopDesc::header_size(), 0); + // Next, pad out the unused tail of the last region with filler + // objects, for improved usage accounting. // How many words we use for filler objects. size_t word_fill_size = word_size_sum - word_size; diff --git a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp index 61e7523cd0d..11a8806a4ea 100644 --- a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp +++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp @@ -575,18 +575,26 @@ bool G1RemSet::refine_card(jbyte* card_ptr, // And find the region containing it. HeapRegion* r = _g1->heap_region_containing(start); - // Why do we have to check here whether a card is on a young region, - // given that we dirty young regions and, as a result, the - // post-barrier is supposed to filter them out and never to enqueue - // them? When we allocate a new region as the "allocation region" we - // actually dirty its cards after we release the lock, since card - // dirtying while holding the lock was a performance bottleneck. So, - // as a result, it is possible for other threads to actually - // allocate objects in the region (after the acquire the lock) - // before all the cards on the region are dirtied. This is unlikely, - // and it doesn't happen often, but it can happen. So, the extra - // check below filters out those cards. - if (r->is_young()) { + // This check is needed for some uncommon cases where we should + // ignore the card. + // + // The region could be young. Cards for young regions are + // distinctly marked (set to g1_young_gen), so the post-barrier will + // filter them out. However, that marking is performed + // concurrently. A write to a young object could occur before the + // card has been marked young, slipping past the filter. + // + // The card could be stale, because the region has been freed since + // the card was recorded. In this case the region type could be + // anything. If (still) free or (reallocated) young, just ignore + // it. If (reallocated) old or humongous, the later card trimming + // and additional checks in iteration may detect staleness. At + // worst, we end up processing a stale card unnecessarily. + // + // In the normal (non-stale) case, the synchronization between the + // enqueueing of the card and processing it here will have ensured + // we see the up-to-date region type here. + if (!r->is_old_or_humongous()) { return false; } @@ -617,26 +625,69 @@ bool G1RemSet::refine_card(jbyte* card_ptr, assert(!check_for_refs_into_cset, "sanity"); assert(!SafepointSynchronize::is_at_safepoint(), "sanity"); + const jbyte* orig_card_ptr = card_ptr; card_ptr = _hot_card_cache->insert(card_ptr); if (card_ptr == NULL) { // There was no eviction. Nothing to do. return false; - } + } else if (card_ptr != orig_card_ptr) { + // Original card was inserted and an old card was evicted. + start = _ct_bs->addr_for(card_ptr); + r = _g1->heap_region_containing(start); - start = _ct_bs->addr_for(card_ptr); - r = _g1->heap_region_containing(start); - - // Checking whether the region we got back from the cache - // is young here is inappropriate. The region could have been - // freed, reallocated and tagged as young while in the cache. - // Hence we could see its young type change at any time. + // Check whether the region formerly in the cache should be + // ignored, as discussed earlier for the original card. The + // region could have been freed while in the cache. The cset is + // not relevant here, since we're in concurrent phase. + if (!r->is_old_or_humongous()) { + return false; + } + } // Else we still have the original card. } + // Trim the region designated by the card to what's been allocated + // in the region. The card could be stale, or the card could cover + // (part of) an object at the end of the allocated space and extend + // beyond the end of allocation. + HeapWord* scan_limit; + if (_g1->is_gc_active()) { + // If we're in a STW GC, then a card might be in a GC alloc region + // and extend onto a GC LAB, which may not be parsable. Stop such + // at the "scan_top" of the region. + scan_limit = r->scan_top(); + } else { + // Non-humongous objects are only allocated in the old-gen during + // GC, so if region is old then top is stable. Humongous object + // allocation sets top last; if top has not yet been set, this is + // a stale card and we'll end up with an empty intersection. If + // this is not a stale card, the synchronization between the + // enqueuing of the card and processing it here will have ensured + // we see the up-to-date top here. + scan_limit = r->top(); + } + if (scan_limit <= start) { + // If the trimmed region is empty, the card must be stale. + return false; + } + + // Okay to clean and process the card now. There are still some + // stale card cases that may be detected by iteration and dealt with + // as iteration failure. + *const_cast(card_ptr) = CardTableModRefBS::clean_card_val(); + + // This fence serves two purposes. First, the card must be cleaned + // before processing the contents. Second, we can't proceed with + // processing until after the read of top, for synchronization with + // possibly concurrent humongous object allocation. It's okay that + // reading top and reading type were racy wrto each other. We need + // both set, in any order, to proceed. + OrderAccess::fence(); + // Don't use addr_for(card_ptr + 1) which can ask for - // a card beyond the heap. This is not safe without a perm - // gen at the upper end of the heap. - HeapWord* end = start + CardTableModRefBS::card_size_in_words; - MemRegion dirtyRegion(start, end); + // a card beyond the heap. + HeapWord* end = start + CardTableModRefBS::card_size_in_words; + MemRegion dirty_region(start, MIN2(scan_limit, end)); + assert(!dirty_region.is_empty(), "sanity"); G1UpdateRSOrPushRefOopClosure update_rs_oop_cl(_g1, _g1->g1_rem_set(), @@ -655,24 +706,9 @@ bool G1RemSet::refine_card(jbyte* card_ptr, (OopClosure*)&mux : (OopClosure*)&update_rs_oop_cl)); - // The region for the current card may be a young region. The - // current card may have been a card that was evicted from the - // card cache. When the card was inserted into the cache, we had - // determined that its region was non-young. While in the cache, - // the region may have been freed during a cleanup pause, reallocated - // and tagged as young. - // - // We wish to filter out cards for such a region but the current - // thread, if we're running concurrently, may "see" the young type - // change at any time (so an earlier "is_young" check may pass or - // fail arbitrarily). We tell the iteration code to perform this - // filtering when it has been determined that there has been an actual - // allocation in this region and making it safe to check the young type. - bool card_processed = - r->oops_on_card_seq_iterate_careful(dirtyRegion, - &filter_then_update_rs_oop_cl, - card_ptr); + r->oops_on_card_seq_iterate_careful(dirty_region, + &filter_then_update_rs_oop_cl); // If unable to process the card then we encountered an unparsable // part of the heap (e.g. a partially allocated object) while diff --git a/hotspot/src/share/vm/gc/g1/heapRegion.cpp b/hotspot/src/share/vm/gc/g1/heapRegion.cpp index e787719fb1b..8a566d9eaf3 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp +++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp @@ -373,6 +373,7 @@ static bool do_oops_on_card_in_humongous(MemRegion mr, return false; } + // We have a well-formed humongous object at the start of sr. // Only filler objects follow a humongous object in the containing // regions, and we can ignore those. So only process the one // humongous object. @@ -396,49 +397,20 @@ static bool do_oops_on_card_in_humongous(MemRegion mr, } bool HeapRegion::oops_on_card_seq_iterate_careful(MemRegion mr, - FilterOutOfRegionClosure* cl, - jbyte* card_ptr) { - assert(card_ptr != NULL, "pre-condition"); + FilterOutOfRegionClosure* cl) { + assert(MemRegion(bottom(), end()).contains(mr), "Card region not in heap region"); G1CollectedHeap* g1h = G1CollectedHeap::heap(); - // If we're within a stop-world GC, then we might look at a card in a - // GC alloc region that extends onto a GC LAB, which may not be - // parseable. Stop such at the "scan_top" of the region. - if (g1h->is_gc_active()) { - mr = mr.intersection(MemRegion(bottom(), scan_top())); - } else { - mr = mr.intersection(used_region()); - } - if (mr.is_empty()) { - return true; - } - - // The intersection of the incoming mr (for the card) and the - // allocated part of the region is non-empty. This implies that - // we have actually allocated into this region. The code in - // G1CollectedHeap.cpp that allocates a new region sets the - // is_young tag on the region before allocating. Thus we - // safely know if this region is young. - if (is_young()) { - return true; - } - - // We can only clean the card here, after we make the decision that - // the card is not young. - *card_ptr = CardTableModRefBS::clean_card_val(); - // We must complete this write before we do any of the reads below. - OrderAccess::storeload(); - // Special handling for humongous regions. if (is_humongous()) { return do_oops_on_card_in_humongous(mr, cl, this, g1h); } + assert(is_old(), "precondition"); - // During GC we limit mr by scan_top. So we never get here with an - // mr covering objects allocated during GC. Non-humongous objects - // are only allocated in the old-gen during GC. So the parts of the - // heap that may be examined here are always parsable; there's no - // need to use klass_or_null here to detect in-progress allocations. + // Because mr has been trimmed to what's been allocated in this + // region, the parts of the heap that are examined here are always + // parsable; there's no need to use klass_or_null to detect + // in-progress allocation. // Cache the boundaries of the memory region in some const locals HeapWord* const start = mr.start(); diff --git a/hotspot/src/share/vm/gc/g1/heapRegion.hpp b/hotspot/src/share/vm/gc/g1/heapRegion.hpp index 3410cbcd11e..10e45c1c1ba 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegion.hpp +++ b/hotspot/src/share/vm/gc/g1/heapRegion.hpp @@ -51,8 +51,9 @@ // object is larger than a heap region, the following regions will // be of type ContinuesHumongous. In this case the top() of the // StartHumongous region and all ContinuesHumongous regions except -// the last will point to their own end. For the last ContinuesHumongous -// region, top() will equal the object's top. +// the last will point to their own end. The last ContinuesHumongous +// region may have top() equal the end of object if there isn't +// room for filler objects to pad out to the end of the region. class G1CollectedHeap; class HeapRegionRemSet; @@ -433,6 +434,8 @@ class HeapRegion: public G1ContiguousSpace { bool is_old() const { return _type.is_old(); } + bool is_old_or_humongous() const { return _type.is_old_or_humongous(); } + // A pinned region contains objects which are not moved by garbage collections. // Humongous regions and archive regions are pinned. bool is_pinned() const { return _type.is_pinned(); } @@ -653,17 +656,18 @@ class HeapRegion: public G1ContiguousSpace { } } - // Iterate over the card in the card designated by card_ptr, - // applying cl to all references in the region. - // mr: the memory region covered by the card. - // card_ptr: if we decide that the card is not young and we iterate - // over it, we'll clean the card before we start the iteration. - // Returns true if the card was successfully processed, false if an - // unparsable part of the heap was encountered, which should only - // happen when invoked concurrently with the mutator. + // Iterate over the objects overlapping part of a card, applying cl + // to all references in the region. This is a helper for + // G1RemSet::refine_card, and is tightly coupled with it. + // mr: the memory region covered by the card, trimmed to the + // allocated space for this region. Must not be empty. + // This region must be old or humongous. + // Returns true if the designated objects were successfully + // processed, false if an unparsable part of the heap was + // encountered; that only happens when invoked concurrently with the + // mutator. bool oops_on_card_seq_iterate_careful(MemRegion mr, - FilterOutOfRegionClosure* cl, - jbyte* card_ptr); + FilterOutOfRegionClosure* cl); size_t recorded_rs_length() const { return _recorded_rs_length; } double predicted_elapsed_time_ms() const { return _predicted_elapsed_time_ms; } diff --git a/hotspot/src/share/vm/gc/g1/heapRegionType.hpp b/hotspot/src/share/vm/gc/g1/heapRegionType.hpp index b118020ac74..e6566c37f77 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegionType.hpp +++ b/hotspot/src/share/vm/gc/g1/heapRegionType.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, 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 @@ -120,6 +120,8 @@ public: // is_old regions may or may not also be pinned bool is_old() const { return (get() & OldMask) != 0; } + bool is_old_or_humongous() const { return (get() & (OldMask | HumongousMask)) != 0; } + // is_pinned regions may be archive or humongous bool is_pinned() const { return (get() & PinnedMask) != 0; } From 95a418feb0c076ba8ffebf5740b4204c6b75725d Mon Sep 17 00:00:00 2001 From: Jini George Date: Wed, 23 Nov 2016 12:08:37 +0530 Subject: [PATCH 044/235] 8169232: SA: TestCpoolForInvokeDynamic.java fails with sun.jvm.hotspot.debugger.DebuggerException: binary search bug: should have found entry 1 Avoid potential data loss by avoiding the long-to-int cast of the return value of minus() Reviewed-by: dsamersoff, sspitsyn --- .../share/classes/sun/jvm/hotspot/oops/InstanceKlass.java | 2 +- .../share/classes/sun/jvm/hotspot/oops/Symbol.java | 6 +++--- .../test/serviceability/sa/TestCpoolForInvokeDynamic.java | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java index 99dbadf0e2b..db8a1c15ffc 100644 --- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java @@ -975,7 +975,7 @@ public class InstanceKlass extends Klass { while (l <= h) { int mid = (l + h) >> 1; Method m = methods.at(mid); - int res = m.getName().fastCompare(name); + long res = m.getName().fastCompare(name); if (res == 0) { // found matching name; do linear search to find matching signature // first, quick check for common case diff --git a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Symbol.java b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Symbol.java index 89502c4c24f..2a3216476bc 100644 --- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Symbol.java +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Symbol.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, 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 @@ -139,8 +139,8 @@ public class Symbol extends VMObject { time-invariant order Since Symbol* are in C_HEAP, their relative order in memory never changes, so use address comparison for speed. */ - public int fastCompare(Symbol other) { - return (int) addr.minus(other.addr); + public long fastCompare(Symbol other) { + return addr.minus(other.addr); } private static String readModifiedUTF8(byte[] buf) throws IOException { diff --git a/hotspot/test/serviceability/sa/TestCpoolForInvokeDynamic.java b/hotspot/test/serviceability/sa/TestCpoolForInvokeDynamic.java index e8f1fd86703..80160d5cf84 100644 --- a/hotspot/test/serviceability/sa/TestCpoolForInvokeDynamic.java +++ b/hotspot/test/serviceability/sa/TestCpoolForInvokeDynamic.java @@ -51,7 +51,6 @@ import jdk.test.lib.Asserts; * jdk.hotspot.agent/sun.jvm.hotspot.oops * jdk.hotspot.agent/sun.jvm.hotspot.debugger * jdk.hotspot.agent/sun.jvm.hotspot.ui.classbrowser - * @ignore 8169232 * @run main/othervm TestCpoolForInvokeDynamic */ From db6e54d85285902d8a1d97f197ccb00ae55788db Mon Sep 17 00:00:00 2001 From: Kirill Zhaldybin Date: Tue, 1 Nov 2016 16:23:29 +0300 Subject: [PATCH 045/235] 8168493: Convert TestBitMap_test to GTest Reviewed-by: kbarrett, tschatzl --- hotspot/src/share/vm/utilities/bitMap.cpp | 114 --------------- hotspot/src/share/vm/utilities/bitMap.hpp | 2 - .../share/vm/utilities/internalVMTests.cpp | 1 - hotspot/test/native/utilities/test_bitMap.cpp | 132 ++++++++++++++++++ 4 files changed, 132 insertions(+), 117 deletions(-) create mode 100644 hotspot/test/native/utilities/test_bitMap.cpp diff --git a/hotspot/src/share/vm/utilities/bitMap.cpp b/hotspot/src/share/vm/utilities/bitMap.cpp index b0b7d567f8e..19a54cc8e7b 100644 --- a/hotspot/src/share/vm/utilities/bitMap.cpp +++ b/hotspot/src/share/vm/utilities/bitMap.cpp @@ -680,118 +680,4 @@ void BitMap::print_on(outputStream* st) const { tty->cr(); } -class TestBitMap : public AllStatic { - const static BitMap::idx_t BITMAP_SIZE = 1024; - - template - static void fillBitMap(ResizableBitMapClass& map) { - map.set_bit(1); - map.set_bit(3); - map.set_bit(17); - map.set_bit(512); - } - - template - static void testResize(BitMap::idx_t start_size) { - ResourceMark rm; - - ResizableBitMapClass map(start_size); - map.resize(BITMAP_SIZE); - fillBitMap(map); - - ResizableBitMapClass map2(BITMAP_SIZE); - fillBitMap(map2); - assert(map.is_same(map2), "could be"); - } - - template - static void testResizeGrow() { - testResize(0); - testResize(128); - } - - template - static void testResizeSame() { - testResize(BITMAP_SIZE); - } - - template - static void testResizeShrink() { - testResize(BITMAP_SIZE * 2); - } - - static void testResizeGrow() { - testResizeGrow(); - testResizeGrow(); - } - - static void testResizeSame() { - testResizeSame(); - testResizeSame(); - } - - static void testResizeShrink() { - testResizeShrink(); - testResizeShrink(); - } - - static void testResize() { - testResizeGrow(); - testResizeSame(); - testResizeShrink(); - } - - template - static void testInitialize() { - ResourceMark rm; - - InitializableBitMapClass map; - map.initialize(BITMAP_SIZE); - fillBitMap(map); - - InitializableBitMapClass map2(BITMAP_SIZE); - fillBitMap(map2); - assert(map.is_same(map2), "could be"); - } - - static void testInitialize() { - testInitialize(); - testInitialize(); - } - - template - static void testReinitialize(BitMap::idx_t init_size) { - ResourceMark rm; - - ReinitializableBitMapClass map(init_size); - map.reinitialize(BITMAP_SIZE); - fillBitMap(map); - - ReinitializableBitMapClass map2(BITMAP_SIZE); - fillBitMap(map2); - assert(map.is_same(map2), "could be"); - } - - template - static void testReinitialize() { - testReinitialize(0); - testReinitialize(128); - testReinitialize(BITMAP_SIZE); - } - - static void testReinitialize() { - testReinitialize(); - } - - public: - static void test() { - testResize(); - testInitialize(); - testReinitialize(); - } -}; - -void TestBitMap_test() { - TestBitMap::test(); -} #endif diff --git a/hotspot/src/share/vm/utilities/bitMap.hpp b/hotspot/src/share/vm/utilities/bitMap.hpp index 919a54cd483..cc08eab08f2 100644 --- a/hotspot/src/share/vm/utilities/bitMap.hpp +++ b/hotspot/src/share/vm/utilities/bitMap.hpp @@ -312,7 +312,6 @@ class BitMapView : public BitMap { // A BitMap with storage in a ResourceArea. class ResourceBitMap : public BitMap { - friend class TestBitMap; public: ResourceBitMap() : BitMap(NULL, 0) {} @@ -351,7 +350,6 @@ class ArenaBitMap : public BitMap { // A BitMap with storage in the CHeap. class CHeapBitMap : public BitMap { - friend class TestBitMap; private: // Don't allow copy or assignment, to prevent the diff --git a/hotspot/src/share/vm/utilities/internalVMTests.cpp b/hotspot/src/share/vm/utilities/internalVMTests.cpp index 3ce41677a25..2f401ed28b4 100644 --- a/hotspot/src/share/vm/utilities/internalVMTests.cpp +++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp @@ -50,7 +50,6 @@ void InternalVMTests::run() { run_unit_test(TestGlobalDefinitions_test); run_unit_test(GCTimer_test); run_unit_test(CollectedHeap_test); - run_unit_test(TestBitMap_test); run_unit_test(ObjectMonitor_test); run_unit_test(DirectivesParser_test); #if INCLUDE_VM_STRUCTS diff --git a/hotspot/test/native/utilities/test_bitMap.cpp b/hotspot/test/native/utilities/test_bitMap.cpp new file mode 100644 index 00000000000..931e502fd60 --- /dev/null +++ b/hotspot/test/native/utilities/test_bitMap.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2016, 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 "memory/resourceArea.hpp" +#include "utilities/bitMap.inline.hpp" +#include "unittest.hpp" + +class BitMapTest { + + template + static void fillBitMap(ResizableBitMapClass& map) { + map.set_bit(1); + map.set_bit(3); + map.set_bit(17); + map.set_bit(512); + } + + template + static void testResize(BitMap::idx_t start_size) { + ResourceMark rm; + + ResizableBitMapClass map(start_size); + map.resize(BITMAP_SIZE); + fillBitMap(map); + + ResizableBitMapClass map2(BITMAP_SIZE); + fillBitMap(map2); + EXPECT_TRUE(map.is_same(map2)) << "With start_size " << start_size; + } + + public: + const static BitMap::idx_t BITMAP_SIZE = 1024; + + + template + static void testResizeGrow() { + testResize(0); + testResize(BITMAP_SIZE >> 3); + } + + template + static void testResizeSame() { + testResize(BITMAP_SIZE); + } + + template + static void testResizeShrink() { + testResize(BITMAP_SIZE * 2); + } + + template + static void testInitialize() { + ResourceMark rm; + + InitializableBitMapClass map; + map.initialize(BITMAP_SIZE); + fillBitMap(map); + + InitializableBitMapClass map2(BITMAP_SIZE); + fillBitMap(map2); + EXPECT_TRUE(map.is_same(map2)); + } + + + static void testReinitialize(BitMap::idx_t init_size) { + ResourceMark rm; + + ResourceBitMap map(init_size); + map.reinitialize(BITMAP_SIZE); + fillBitMap(map); + + ResourceBitMap map2(BITMAP_SIZE); + fillBitMap(map2); + EXPECT_TRUE(map.is_same(map2)) << "With init_size " << init_size; + } + +}; + +TEST_VM(BitMap, resize_grow) { + BitMapTest::testResizeGrow(); + EXPECT_FALSE(HasFailure()) << "Failed on type ResourceBitMap"; + BitMapTest::testResizeGrow(); + EXPECT_FALSE(HasFailure()) << "Failed on type CHeapBitMap"; +} + +TEST_VM(BitMap, resize_shrink) { + BitMapTest::testResizeShrink(); + EXPECT_FALSE(HasFailure()) << "Failed on type ResourceBitMap"; + BitMapTest::testResizeShrink(); + EXPECT_FALSE(HasFailure()) << "Failed on type CHeapBitMap"; +} + +TEST_VM(BitMap, resize_same) { + BitMapTest::testResizeSame(); + EXPECT_FALSE(HasFailure()) << "Failed on type ResourceBitMap"; + BitMapTest::testResizeSame(); + EXPECT_FALSE(HasFailure()) << "Failed on type CHeapBitMap"; +} + +TEST_VM(BitMap, initialize) { + BitMapTest::testInitialize(); + EXPECT_FALSE(HasFailure()) << "Failed on type ResourceBitMap"; + BitMapTest::testInitialize(); + EXPECT_FALSE(HasFailure()) << "Failed on type CHeapBitMap"; +} + +TEST_VM(BitMap, reinitialize) { + BitMapTest::testReinitialize(0); + BitMapTest::testReinitialize(BitMapTest::BITMAP_SIZE >> 3); + BitMapTest::testReinitialize(BitMapTest::BITMAP_SIZE); +} From 145cb85e75a24e00e249a3d81db72e60b072f56e Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Mon, 7 Nov 2016 16:14:18 -0800 Subject: [PATCH 046/235] 8160024: jdb returns invalid argument count if first parameter to Arrays.asList is null Adjust com/sun/jdi/MethodImpl.java for null argument Reviewed-by: dcubed, dsamersoff --- .../classes/com/sun/tools/jdi/MethodImpl.java | 10 ++- jdk/test/com/sun/jdi/EvalArraysAsList.sh | 85 +++++++++++++++++++ 2 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 jdk/test/com/sun/jdi/EvalArraysAsList.sh diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/MethodImpl.java b/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/MethodImpl.java index b5cd9c67abd..2cd645345c7 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/MethodImpl.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/MethodImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, 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 @@ -315,10 +315,14 @@ public abstract class MethodImpl extends TypeComponentImpl return; } Value nthArgValue = arguments.get(paramCount - 1); - if (nthArgValue == null) { + if (nthArgValue == null && argCount == paramCount) { + // We have one varargs parameter and it is null + // so we don't have to do anything. return; } - Type nthArgType = nthArgValue.type(); + // If the first varargs parameter is null, then don't + // access its type since it can't be an array. + Type nthArgType = (nthArgValue == null) ? null : nthArgValue.type(); if (nthArgType instanceof ArrayTypeImpl) { if (argCount == paramCount && ((ArrayTypeImpl)nthArgType).isAssignableTo(lastParamType)) { diff --git a/jdk/test/com/sun/jdi/EvalArraysAsList.sh b/jdk/test/com/sun/jdi/EvalArraysAsList.sh new file mode 100644 index 00000000000..fa5cd93c53a --- /dev/null +++ b/jdk/test/com/sun/jdi/EvalArraysAsList.sh @@ -0,0 +1,85 @@ +#!/bin/sh +# +# Copyright (c) 2016, 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 8160024 +# @summary jdb returns invalid argument count if first parameter to Arrays.asList is null +# +# @run shell/timeout=300 EvalArraysAsList.sh +# +# The test checks if evaluation of the expression java.util.Arrays.asList(null, "a") +# works normally and does not throw an IllegalArgumentException. + +classname=EvalArraysAsList + +createJavaFile() +{ + cat < $classname.java.1 +public class $classname { + public static void main(String[] args) { + java.util.List l = java.util.Arrays.asList(null, "a"); + System.out.println("java.util.Arrays.asList(null, \"a\") returns: " + l); + return; // @1 breakpoint + } +} +EOF +} + +# drive jdb by sending cmds to it and examining its output +dojdbCmds() +{ + setBkpts @1 + runToBkpt @1 + + cmd eval "java.util.Arrays.asList(null, null)" + jdbFailIfPresent "IllegalArgumentException" 3 + + cmd eval "java.util.Arrays.asList(null, \"a\")" + jdbFailIfPresent "IllegalArgumentException" 3 + + cmd eval "java.util.Arrays.asList(\"a\", null)" + jdbFailIfPresent "IllegalArgumentException" 3 +} + + +mysetup() +{ + if [ -z "$TESTSRC" ] ; then + TESTSRC=. + fi + + for ii in . $TESTSRC $TESTSRC/.. ; do + if [ -r "$ii/ShellScaffold.sh" ] ; then + . $ii/ShellScaffold.sh + break + fi + done +} + +# You could replace this next line with the contents +# of ShellScaffold.sh and this script will run just the same. +mysetup + +runit +pass From 34af3661d3fe5d2037d2a6407ea23e349b822c55 Mon Sep 17 00:00:00 2001 From: Ujwal Vangapally Date: Mon, 14 Nov 2016 12:05:26 +0530 Subject: [PATCH 047/235] 8168141: javax/management/remote/mandatory/notif/EmptyDomainNotificationTest.java: No notif received! Changed the time limit of 2 seconds for getting notification to default jtreg timeout. Reviewed-by: rehn, dholmes --- .../notif/EmptyDomainNotificationTest.java | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/jdk/test/javax/management/remote/mandatory/notif/EmptyDomainNotificationTest.java b/jdk/test/javax/management/remote/mandatory/notif/EmptyDomainNotificationTest.java index ebc0ab239d6..7301c4faa0b 100644 --- a/jdk/test/javax/management/remote/mandatory/notif/EmptyDomainNotificationTest.java +++ b/jdk/test/javax/management/remote/mandatory/notif/EmptyDomainNotificationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, 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,20 +103,13 @@ public class EmptyDomainNotificationTest { mbsc.invoke(mbean, "emitNotification", null, null); System.out.println("EmptyDomainNotificationTest-main: waiting notif..."); - final long stopTime = System.currentTimeMillis() + 2000; synchronized(li) { - long toWait = stopTime - System.currentTimeMillis(); - - while (li.received < 1 && toWait > 0) { - li.wait(toWait); - - toWait = stopTime - System.currentTimeMillis(); + while (li.received < 1) { + li.wait(); } } - if (li.received < 1) { - throw new RuntimeException("No notif received!"); - } else if (li.received > 1) { + if (li.received != 1) { throw new RuntimeException("Wait one notif but got: "+li.received); } From f5794aaadbf627913d691b9ff5bf5d054c987057 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Tue, 15 Nov 2016 08:58:29 -0800 Subject: [PATCH 048/235] 8153208: TIFFImageReadParam: should "contains()" check be appropriate for addAllowedTagSet() method? Do not add a duplicate TIFFTagSet instance and update the spec accordingly. Reviewed-by: prr --- .../javax/imageio/plugins/tiff/TIFFImageReadParam.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/TIFFImageReadParam.java b/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/TIFFImageReadParam.java index 1b8821aef1c..e6af9dfe887 100644 --- a/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/TIFFImageReadParam.java +++ b/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/TIFFImageReadParam.java @@ -50,7 +50,8 @@ import javax.imageio.ImageReadParam; */ public final class TIFFImageReadParam extends ImageReadParam { - private List allowedTagSets = new ArrayList(4); + private final List allowedTagSets = + new ArrayList(4); /** * Constructs a {@code TIFFImageReadParam}. Tags defined by @@ -72,7 +73,8 @@ public final class TIFFImageReadParam extends ImageReadParam { /** * Adds a {@code TIFFTagSet} object to the list of allowed - * tag sets. + * tag sets. Attempting to add a duplicate object to the list + * has no effect. * * @param tagSet a {@code TIFFTagSet}. * @@ -83,7 +85,9 @@ public final class TIFFImageReadParam extends ImageReadParam { if (tagSet == null) { throw new IllegalArgumentException("tagSet == null!"); } - allowedTagSets.add(tagSet); + if (!allowedTagSets.contains(tagSet)) { + allowedTagSets.add(tagSet); + } } /** From 15c92b98a3d49cbdced9e11834542c54f39c6504 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Wed, 16 Nov 2016 11:49:52 -0800 Subject: [PATCH 049/235] 8168759: Incorrect vertical positioning of diacritics Reviewed-by: serb --- .../share/native/libfontmanager/HBShaper.c | 2 +- .../font/TextLayout/ArabicDiacriticTest.java | 95 +++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/awt/font/TextLayout/ArabicDiacriticTest.java diff --git a/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c b/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c index 95a92f221ad..41cf1864178 100644 --- a/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c +++ b/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c @@ -140,7 +140,7 @@ jboolean storeGVData(JNIEnv* env, indices[storei] = baseIndex + cluster; glyphs[storei] = (unsigned int)(glyphInfo[i].codepoint | slot); positions[storei*2] = startX + x + glyphPos[i].x_offset * scale; - positions[(storei*2)+1] = startY + y + glyphPos[i].y_offset * scale; + positions[(storei*2)+1] = startY + y - glyphPos[i].y_offset * scale; x += glyphPos[i].x_advance * scale; y += glyphPos[i].y_advance * scale; storei++; diff --git a/jdk/test/java/awt/font/TextLayout/ArabicDiacriticTest.java b/jdk/test/java/awt/font/TextLayout/ArabicDiacriticTest.java new file mode 100644 index 00000000000..e74edf8b8ed --- /dev/null +++ b/jdk/test/java/awt/font/TextLayout/ArabicDiacriticTest.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2016, 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 + */ + +/* @test + * @summary verify Arab Diacritic Positioning + * @bug 8168759 + */ + +import java.awt.Font; +import java.awt.GridLayout; +import java.awt.Rectangle; +import java.awt.font.FontRenderContext; +import java.awt.font.TextLayout; +import java.util.Locale; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.SwingUtilities; +import javax.swing.WindowConstants; + +public class ArabicDiacriticTest { + + static final String SAMPLE = + "\u0627\u0644\u0639\u064e\u0631\u064e\u0628\u0650\u064a\u064e\u0651\u0629"; + + static final String STR1 = "\u0644\u0639\u064e\u0629"; + static final String STR2 = "\u0644\u0639\u0629"; + + static JFrame frame; + static final String FONT = "DejaVu Sans"; + + public static void main(String args[]) throws Exception { + showText(); // for a human + measureText(); // for the test harness + Thread.sleep(5000); + frame.dispose(); + } + + static void showText() { + SwingUtilities.invokeLater(() -> { + frame = new JFrame(); + JLabel label = new JLabel(SAMPLE); + Font font = new Font(FONT, Font.PLAIN, 36); + label.setFont(font); + frame.setLayout(new GridLayout(3,1)); + frame.add(label); + label = new JLabel(STR1); + label.setFont(font); + frame.add(label); + label = new JLabel(STR2); + label.setFont(font); + frame.add(label); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + } + + static void measureText() { + Font font = new Font(FONT, Font.PLAIN, 36); + if (!font.getFamily(Locale.ENGLISH).equals(FONT)) { + return; + } + FontRenderContext frc = new FontRenderContext(null, false, false); + TextLayout tl1 = new TextLayout(STR1, font, frc); + TextLayout tl2 = new TextLayout(STR2, font, frc); + Rectangle r1 = tl1.getPixelBounds(frc, 0f, 0f); + Rectangle r2 = tl2.getPixelBounds(frc, 0f, 0f); + if (r1.height > r2.height) { + System.out.println(font); + System.out.println(r1); + System.out.println(r2); + throw new RuntimeException("BAD BOUNDS"); + } + } +} From e266d93b8928fbeca59813214db0ba5238c92db0 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Wed, 16 Nov 2016 14:27:23 -0800 Subject: [PATCH 050/235] 8167182: Exported elements referring to inaccessible types in jdk.accessibility Reviewed-by: serb, ssadetsky --- make/CompileJavaModules.gmk | 2 -- 1 file changed, 2 deletions(-) diff --git a/make/CompileJavaModules.gmk b/make/CompileJavaModules.gmk index c222a400c85..0d3ede60f4b 100644 --- a/make/CompileJavaModules.gmk +++ b/make/CompileJavaModules.gmk @@ -344,8 +344,6 @@ jdk.charsets_COPY := .dat ################################################################################ -jdk.accessibility_ADD_JAVAC_FLAGS := -Xlint:-exports - ################################################################################ jdk.compiler_ADD_JAVAC_FLAGS := -Xdoclint:all/protected '-Xdoclint/package:-com.sun.tools.*,-jdk.internal.*' \ From 67657286e45a35a11f54e94a0de2f0408d8904e7 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Wed, 16 Nov 2016 14:27:39 -0800 Subject: [PATCH 051/235] 8167182: Exported elements referring to inaccessible types in jdk.accessibility Reviewed-by: serb, ssadetsky --- .../accessibility/util/AWTEventMonitor.java | 71 +++++++++---------- .../util/AccessibilityEventMonitor.java | 4 +- .../accessibility/util/SwingEventMonitor.java | 4 +- 3 files changed, 36 insertions(+), 43 deletions(-) diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java index cd3cf14164e..297779d39c8 100644 --- a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, 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 @@ -25,10 +25,8 @@ package com.sun.java.accessibility.util; -import java.util.*; import java.awt.*; import java.awt.event.*; -import javax.accessibility.*; import javax.swing.*; import javax.swing.event.*; import sun.awt.AWTPermissions; @@ -55,7 +53,7 @@ public class AWTEventMonitor { * @deprecated This field is unused; to get the component with focus use the * getComponentWithFocus method. */ - @Deprecated + @Deprecated(since="8", forRemoval=true) static protected Component componentWithFocus = null; static private Component componentWithFocus_private = null; @@ -69,7 +67,7 @@ public class AWTEventMonitor { * * @deprecated This field is unused. */ - @Deprecated + @Deprecated(since="8", forRemoval=true) static protected ComponentListener componentListener = null; static private ComponentListener componentListener_private = null; @@ -82,7 +80,7 @@ public class AWTEventMonitor { * * @deprecated This field is unused. */ - @Deprecated + @Deprecated(since="8", forRemoval=true) static protected ContainerListener containerListener = null; static private ContainerListener containerListener_private = null; @@ -95,7 +93,7 @@ public class AWTEventMonitor { * * @deprecated This field is unused. */ - @Deprecated + @Deprecated(since="8", forRemoval=true) static protected FocusListener focusListener = null; static private FocusListener focusListener_private = null; @@ -108,7 +106,7 @@ public class AWTEventMonitor { * * @deprecated This field is unused. */ - @Deprecated + @Deprecated(since="8", forRemoval=true) static protected KeyListener keyListener = null; static private KeyListener keyListener_private = null; @@ -121,7 +119,7 @@ public class AWTEventMonitor { * * @deprecated This field is unused. */ - @Deprecated + @Deprecated(since="8", forRemoval=true) static protected MouseListener mouseListener = null; static private MouseListener mouseListener_private = null; @@ -134,7 +132,7 @@ public class AWTEventMonitor { * * @deprecated This field is unused. */ - @Deprecated + @Deprecated(since="8", forRemoval=true) static protected MouseMotionListener mouseMotionListener = null; static private MouseMotionListener mouseMotionListener_private = null; @@ -147,7 +145,7 @@ public class AWTEventMonitor { * * @deprecated This field is unused. */ - @Deprecated + @Deprecated(since="8", forRemoval=true) static protected WindowListener windowListener = null; static private WindowListener windowListener_private = null; @@ -162,7 +160,7 @@ public class AWTEventMonitor { * * @deprecated This field is unused. */ - @Deprecated + @Deprecated(since="8", forRemoval=true) static protected ActionListener actionListener = null; static private ActionListener actionListener_private = null; @@ -175,7 +173,7 @@ public class AWTEventMonitor { * * @deprecated This field is unused. */ - @Deprecated + @Deprecated(since="8", forRemoval=true) static protected AdjustmentListener adjustmentListener = null; static private AdjustmentListener adjustmentListener_private = null; @@ -188,7 +186,7 @@ public class AWTEventMonitor { * * @deprecated This field is unused. */ - @Deprecated + @Deprecated(since="8", forRemoval=true) static protected ItemListener itemListener = null; static private ItemListener itemListener_private = null; @@ -201,7 +199,7 @@ public class AWTEventMonitor { * * @deprecated This field is unused. */ - @Deprecated + @Deprecated(since="8", forRemoval=true) static protected TextListener textListener = null; static private TextListener textListener_private = null; @@ -212,13 +210,8 @@ public class AWTEventMonitor { * This listener calls the other registered listeners when an event * occurs. By doing things this way, the actual number of listeners * installed on a component instance is drastically reduced. - * - * @deprecated This field is unused. */ - @Deprecated - static protected AWTEventsListener awtListener = new AWTEventsListener(); - - static private final AWTEventsListener awtListener_private = new AWTEventsListener(); + static private final AWTEventsListener awtListener = new AWTEventsListener(); /** * Returns the component that currently has keyboard focus. The return @@ -253,7 +246,7 @@ public class AWTEventMonitor { static public void addComponentListener(ComponentListener l) { if (componentListener_private == null) { checkInstallPermission(); - awtListener_private.installListeners(EventID.COMPONENT); + awtListener.installListeners(EventID.COMPONENT); } componentListener_private = AWTEventMulticaster.add(componentListener_private, l); } @@ -268,7 +261,7 @@ public class AWTEventMonitor { static public void removeComponentListener(ComponentListener l) { componentListener_private = AWTEventMulticaster.remove(componentListener_private, l); if (componentListener_private == null) { - awtListener_private.removeListeners(EventID.COMPONENT); + awtListener.removeListeners(EventID.COMPONENT); } } @@ -335,7 +328,7 @@ public class AWTEventMonitor { static public void addKeyListener(KeyListener l) { if (keyListener_private == null) { checkInstallPermission(); - awtListener_private.installListeners(EventID.KEY); + awtListener.installListeners(EventID.KEY); } keyListener_private = AWTEventMulticaster.add(keyListener_private, l); } @@ -350,7 +343,7 @@ public class AWTEventMonitor { static public void removeKeyListener(KeyListener l) { keyListener_private = AWTEventMulticaster.remove(keyListener_private, l); if (keyListener_private == null) { - awtListener_private.removeListeners(EventID.KEY); + awtListener.removeListeners(EventID.KEY); } } @@ -367,7 +360,7 @@ public class AWTEventMonitor { static public void addMouseListener(MouseListener l) { if (mouseListener_private == null) { checkInstallPermission(); - awtListener_private.installListeners(EventID.MOUSE); + awtListener.installListeners(EventID.MOUSE); } mouseListener_private = AWTEventMulticaster.add(mouseListener_private, l); } @@ -382,7 +375,7 @@ public class AWTEventMonitor { static public void removeMouseListener(MouseListener l) { mouseListener_private = AWTEventMulticaster.remove(mouseListener_private, l); if (mouseListener_private == null) { - awtListener_private.removeListeners(EventID.MOUSE); + awtListener.removeListeners(EventID.MOUSE); } } @@ -399,7 +392,7 @@ public class AWTEventMonitor { static public void addMouseMotionListener(MouseMotionListener l) { if (mouseMotionListener_private == null) { checkInstallPermission(); - awtListener_private.installListeners(EventID.MOTION); + awtListener.installListeners(EventID.MOTION); } mouseMotionListener_private = AWTEventMulticaster.add(mouseMotionListener_private, l); } @@ -414,7 +407,7 @@ public class AWTEventMonitor { static public void removeMouseMotionListener(MouseMotionListener l) { mouseMotionListener_private = AWTEventMulticaster.remove(mouseMotionListener_private, l); if (mouseMotionListener_private == null) { - awtListener_private.removeListeners(EventID.MOTION); + awtListener.removeListeners(EventID.MOTION); } } @@ -431,7 +424,7 @@ public class AWTEventMonitor { static public void addWindowListener(WindowListener l) { if (windowListener_private == null) { checkInstallPermission(); - awtListener_private.installListeners(EventID.WINDOW); + awtListener.installListeners(EventID.WINDOW); } windowListener_private = AWTEventMulticaster.add(windowListener_private, l); } @@ -446,7 +439,7 @@ public class AWTEventMonitor { static public void removeWindowListener(WindowListener l) { windowListener_private = AWTEventMulticaster.remove(windowListener_private, l); if (windowListener_private == null) { - awtListener_private.removeListeners(EventID.WINDOW); + awtListener.removeListeners(EventID.WINDOW); } } @@ -463,7 +456,7 @@ public class AWTEventMonitor { static public void addActionListener(ActionListener l) { if (actionListener_private == null) { checkInstallPermission(); - awtListener_private.installListeners(EventID.ACTION); + awtListener.installListeners(EventID.ACTION); } actionListener_private = AWTEventMulticaster.add(actionListener_private, l); } @@ -478,7 +471,7 @@ public class AWTEventMonitor { static public void removeActionListener(ActionListener l) { actionListener_private = AWTEventMulticaster.remove(actionListener_private, l); if (actionListener_private == null) { - awtListener_private.removeListeners(EventID.ACTION); + awtListener.removeListeners(EventID.ACTION); } } @@ -496,7 +489,7 @@ public class AWTEventMonitor { static public void addAdjustmentListener(AdjustmentListener l) { if (adjustmentListener_private == null) { checkInstallPermission(); - awtListener_private.installListeners(EventID.ADJUSTMENT); + awtListener.installListeners(EventID.ADJUSTMENT); } adjustmentListener_private = AWTEventMulticaster.add(adjustmentListener_private, l); } @@ -511,7 +504,7 @@ public class AWTEventMonitor { static public void removeAdjustmentListener(AdjustmentListener l) { adjustmentListener_private = AWTEventMulticaster.remove(adjustmentListener_private, l); if (adjustmentListener_private == null) { - awtListener_private.removeListeners(EventID.ADJUSTMENT); + awtListener.removeListeners(EventID.ADJUSTMENT); } } @@ -528,7 +521,7 @@ public class AWTEventMonitor { static public void addItemListener(ItemListener l) { if (itemListener_private == null) { checkInstallPermission(); - awtListener_private.installListeners(EventID.ITEM); + awtListener.installListeners(EventID.ITEM); } itemListener_private = AWTEventMulticaster.add(itemListener_private, l); } @@ -543,7 +536,7 @@ public class AWTEventMonitor { static public void removeItemListener(ItemListener l) { itemListener_private = AWTEventMulticaster.remove(itemListener_private, l); if (itemListener_private == null) { - awtListener_private.removeListeners(EventID.ITEM); + awtListener.removeListeners(EventID.ITEM); } } @@ -560,7 +553,7 @@ public class AWTEventMonitor { static public void addTextListener(TextListener l) { if (textListener_private == null) { checkInstallPermission(); - awtListener_private.installListeners(EventID.TEXT); + awtListener.installListeners(EventID.TEXT); } textListener_private = AWTEventMulticaster.add(textListener_private, l); } @@ -575,7 +568,7 @@ public class AWTEventMonitor { static public void removeTextListener(TextListener l) { textListener_private = AWTEventMulticaster.remove(textListener_private, l); if (textListener_private == null) { - awtListener_private.removeListeners(EventID.TEXT); + awtListener.removeListeners(EventID.TEXT); } } diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AccessibilityEventMonitor.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AccessibilityEventMonitor.java index 603ba035ae7..e26718d15b5 100644 --- a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AccessibilityEventMonitor.java +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AccessibilityEventMonitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, 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 @@ -63,7 +63,7 @@ public class AccessibilityEventMonitor { * occurs. By doing things this way, the actual number of listeners * installed on a component instance is drastically reduced. */ - static protected final AccessibilityEventListener accessibilityListener = + static private final AccessibilityEventListener accessibilityListener = new AccessibilityEventListener(); /** diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/SwingEventMonitor.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/SwingEventMonitor.java index bbb0fcb18b3..c5dcda4df3e 100644 --- a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/SwingEventMonitor.java +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/SwingEventMonitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, 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 @@ -71,7 +71,7 @@ public class SwingEventMonitor extends AWTEventMonitor { * occurs. By doing things this way, the actual number of listeners * installed on a component instance is drastically reduced. */ - static protected final SwingEventListener swingListener = new SwingEventListener(); + static private final SwingEventListener swingListener = new SwingEventListener(); /** * Adds the specified listener to receive all {@link EventID#ANCESTOR ANCESTOR} From 26282a374ced7a937c066a1a3a63875c10f4a917 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Thu, 17 Nov 2016 02:31:04 +0300 Subject: [PATCH 052/235] 8169202: [macos] Font substitution does not work for supplementary characters Reviewed-by: serb, prr --- .../native/libawt_lwawt/font/CGGlyphImages.m | 16 ++-- .../libawt_lwawt/font/CoreTextSupport.h | 2 + .../libawt_lwawt/font/CoreTextSupport.m | 32 +++++-- .../font/Fallback/SurrogatesFallbackTest.java | 88 +++++++++++++++++++ 4 files changed, 124 insertions(+), 14 deletions(-) create mode 100644 jdk/test/java/awt/font/Fallback/SurrogatesFallbackTest.java diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m b/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m index 79cdf5bf7a3..1d9269fc57f 100644 --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m @@ -591,7 +591,7 @@ CGGI_CreateImageForGlyph static inline GlyphInfo * CGGI_CreateImageForUnicode (CGGI_GlyphCanvas *canvas, const AWTStrike *strike, - const CGGI_RenderingMode *mode, const UniChar uniChar) + const CGGI_RenderingMode *mode, const UnicodeScalarValue uniChar) { // save the state of the world CGContextSaveGState(canvas->context); @@ -668,7 +668,7 @@ CGGI_FillImagesForGlyphsWithSizedCanvas(CGGI_GlyphCanvas *canvas, const AWTStrike *strike, const CGGI_RenderingMode *mode, jlong glyphInfos[], - const UniChar uniChars[], + const UnicodeScalarValue uniChars[], const CGGlyph glyphs[], const CFIndex len) { @@ -720,7 +720,7 @@ static NSString *threadLocalLCDCanvasKey = static inline void CGGI_FillImagesForGlyphs(jlong *glyphInfos, const AWTStrike *strike, const CGGI_RenderingMode *mode, - const UniChar uniChars[], const CGGlyph glyphs[], + const UnicodeScalarValue uniChars[], const CGGlyph glyphs[], const size_t maxWidth, const size_t maxHeight, const CFIndex len) { @@ -767,7 +767,7 @@ CGGI_FillImagesForGlyphs(jlong *glyphInfos, const AWTStrike *strike, static inline void CGGI_CreateGlyphInfos(jlong *glyphInfos, const AWTStrike *strike, const CGGI_RenderingMode *mode, - const UniChar uniChars[], const CGGlyph glyphs[], + const UnicodeScalarValue uniChars[], const CGGlyph glyphs[], CGSize advances[], CGRect bboxes[], const CFIndex len) { AWTFont *font = strike->fAWTFont; @@ -817,7 +817,7 @@ CGGI_CreateGlyphsAndScanForComplexities(jlong *glyphInfos, const AWTStrike *strike, const CGGI_RenderingMode *mode, jint rawGlyphCodes[], - UniChar uniChars[], CGGlyph glyphs[], + UnicodeScalarValue uniChars[], CGGlyph glyphs[], CGSize advances[], CGRect bboxes[], const CFIndex len) { @@ -860,7 +860,7 @@ CGGlyphImages_GetGlyphImagePtrs(jlong glyphInfos[], CGRect bboxes[len]; CGSize advances[len]; CGGlyph glyphs[len]; - UniChar uniChars[len]; + UnicodeScalarValue uniChars[len]; CGGI_CreateGlyphsAndScanForComplexities(glyphInfos, strike, &mode, rawGlyphCodes, uniChars, glyphs, @@ -871,7 +871,7 @@ CGGlyphImages_GetGlyphImagePtrs(jlong glyphInfos[], // just do one malloc, and carve it up for all the buffers void *buffer = malloc(sizeof(CGRect) * sizeof(CGSize) * - sizeof(CGGlyph) * sizeof(UniChar) * len); + sizeof(CGGlyph) * sizeof(UnicodeScalarValue) * len); if (buffer == NULL) { [[NSException exceptionWithName:NSMallocException reason:@"Failed to allocate memory for the temporary glyph strike and measurement buffers." userInfo:nil] raise]; @@ -880,7 +880,7 @@ CGGlyphImages_GetGlyphImagePtrs(jlong glyphInfos[], CGRect *bboxes = (CGRect *)(buffer); CGSize *advances = (CGSize *)(bboxes + sizeof(CGRect) * len); CGGlyph *glyphs = (CGGlyph *)(advances + sizeof(CGGlyph) * len); - UniChar *uniChars = (UniChar *)(glyphs + sizeof(UniChar) * len); + UnicodeScalarValue *uniChars = (UnicodeScalarValue *)(glyphs + sizeof(UnicodeScalarValue) * len); CGGI_CreateGlyphsAndScanForComplexities(glyphInfos, strike, &mode, rawGlyphCodes, uniChars, glyphs, diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.h b/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.h index a0ede94846c..cbd3dc5923b 100644 --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.h +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.h @@ -32,7 +32,9 @@ #pragma mark --- CoreText Support --- #define HI_SURROGATE_START 0xD800 +#define HI_SURROGATE_END 0xDBFF #define LO_SURROGATE_START 0xDC00 +#define LO_SURROGATE_END 0xDFFF /* * Transform Unicode characters into glyphs. diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.m b/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.m index 1bcd9f55102..5663b3084ac 100644 --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.m +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.m @@ -103,24 +103,34 @@ void CTS_GetGlyphsAsIntsForCharacters size_t i; for (i = 0; i < count; i++) { + UniChar unicode = unicodes[i]; + UniChar nextUnicode = (i+1) < count ? unicodes[i+1] : 0; + bool surrogatePair = unicode >= HI_SURROGATE_START && unicode <= HI_SURROGATE_END + && nextUnicode >= LO_SURROGATE_START && nextUnicode <= LO_SURROGATE_END; + CGGlyph glyph = glyphs[i]; if (glyph > 0) { glyphsAsInts[i] = glyph; + if (surrogatePair) i++; continue; } - UniChar unicode = unicodes[i]; - const CTFontRef fallback = JRSFontCreateFallbackFontForCharacters((CTFontRef)font->fFont, &unicode, 1); + const CTFontRef fallback = JRSFontCreateFallbackFontForCharacters((CTFontRef)font->fFont, &unicodes[i], + surrogatePair ? 2 : 1); if (fallback) { - CTFontGetGlyphsForCharacters(fallback, &unicode, &glyph, 1); + CTFontGetGlyphsForCharacters(fallback, &unicodes[i], &glyphs[i], surrogatePair ? 2 : 1); + glyph = glyphs[i]; CFRelease(fallback); } if (glyph > 0) { - glyphsAsInts[i] = -unicode; // set the glyph code to the negative unicode value + int codePoint = surrogatePair ? (((int)(unicode - HI_SURROGATE_START)) << 10) + + nextUnicode - LO_SURROGATE_START + 0x10000 : unicode; + glyphsAsInts[i] = -codePoint; // set the glyph code to the negative unicode value } else { glyphsAsInts[i] = 0; // CoreText couldn't find a glyph for this character either } + if (surrogatePair) i++; } } @@ -158,8 +168,18 @@ CTFontRef CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode return (CTFontRef)font->fFont; } - UTF16Char character = -glyphCode; - return CTS_CopyCTFallbackFontAndGlyphForUnicode(font, &character, glyphRef, 1); + int codePoint = -glyphCode; + if (codePoint >= 0x10000) { + UTF16Char chars[2]; + CGGlyph glyphs[2]; + CTS_BreakupUnicodeIntoSurrogatePairs(codePoint, chars); + CTFontRef result = CTS_CopyCTFallbackFontAndGlyphForUnicode(font, chars, glyphs, 2); + *glyphRef = glyphs[0]; + return result; + } else { + UTF16Char character = codePoint; + return CTS_CopyCTFallbackFontAndGlyphForUnicode(font, &character, glyphRef, 1); + } } // Breakup a 32 bit unicode value into the component surrogate pairs diff --git a/jdk/test/java/awt/font/Fallback/SurrogatesFallbackTest.java b/jdk/test/java/awt/font/Fallback/SurrogatesFallbackTest.java new file mode 100644 index 00000000000..9a87243d898 --- /dev/null +++ b/jdk/test/java/awt/font/Fallback/SurrogatesFallbackTest.java @@ -0,0 +1,88 @@ +/* + * Copyright 2016 JetBrains s.r.o. + * 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 8169202 + * @summary verify font fallback for surrogate pairs on macOS + * @requires os.family == "mac" + */ + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.font.GlyphVector; +import java.awt.image.BufferedImage; +import java.util.function.Consumer; + +public class SurrogatesFallbackTest { + private static final int CHARACTER = 0x1d400; // MATHEMATICAL BOLD CAPITAL A + private static final Font FONT = new Font("Menlo", // expected to fallback to STIXGeneral for the character above + Font.PLAIN, + 12); + private static final int IMAGE_WIDTH = 20; + private static final int IMAGE_HEIGHT = 20; + private static final int GLYPH_X = 5; + private static final int GLYPH_Y = 15; + + public static void main(String[] args) { + BufferedImage noGlyph = createImage(g -> {}); + BufferedImage missingGlyph = createImage(g -> { + GlyphVector gv = FONT.createGlyphVector(g.getFontRenderContext(), new int[]{FONT.getMissingGlyphCode()}); + g.drawGlyphVector(gv, GLYPH_X, GLYPH_Y); + }); + BufferedImage surrogateCharGlyph = createImage(g -> { + g.setFont(FONT); + g.drawString(new String(Character.toChars(CHARACTER)), GLYPH_X, GLYPH_Y); + }); + + if (imagesAreEqual(surrogateCharGlyph, noGlyph)) { + throw new RuntimeException("Character was not rendered"); + } + if (imagesAreEqual(surrogateCharGlyph, missingGlyph)) { + throw new RuntimeException("Character is rendered as missing"); + } + } + + private static BufferedImage createImage(Consumer drawing) { + BufferedImage image = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); + Graphics2D g = image.createGraphics(); + g.setColor(Color.white); + g.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT); + g.setColor(Color.black); + drawing.accept(g); + g.dispose(); + return image; + } + + private static boolean imagesAreEqual(BufferedImage i1, BufferedImage i2) { + if (i1.getWidth() != i2.getWidth() || i1.getHeight() != i2.getHeight()) return false; + for (int i = 0; i < i1.getWidth(); i++) { + for (int j = 0; j < i1.getHeight(); j++) { + if (i1.getRGB(i, j) != i2.getRGB(i, j)) { + return false; + } + } + } + return true; + } +} + From 6d895b494d8f52c90bd182e339e1c3192c4f5692 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Thu, 17 Nov 2016 11:48:37 +0530 Subject: [PATCH 053/235] 8168657: [PIT] Still, on Windows test always fails: java/awt/SplashScreen/MultiResolutionSplash/unix/UnixMultiResolutionSplashTest.java Reviewed-by: serb, rchamyal --- .../unix/UnixMultiResolutionSplashTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/unix/UnixMultiResolutionSplashTest.java b/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/unix/UnixMultiResolutionSplashTest.java index 26c4f728599..a4c026b7931 100644 --- a/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/unix/UnixMultiResolutionSplashTest.java +++ b/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/unix/UnixMultiResolutionSplashTest.java @@ -44,9 +44,11 @@ import java.util.Map; import javax.imageio.ImageIO; /** - * @test @bug 8145174 8151787 + * @test + * @bug 8145174 8151787 8168657 * @summary HiDPI splash screen support on Linux * @modules java.desktop/sun.java2d + * @requires (os.family == "linux") * @run main UnixMultiResolutionSplashTest */ public class UnixMultiResolutionSplashTest { From bd215e318bde236660b6d79934d613b34fd32139 Mon Sep 17 00:00:00 2001 From: Ambarish Rapte Date: Thu, 17 Nov 2016 11:57:56 +0530 Subject: [PATCH 054/235] 8169840: [TESTBUG] DisposeDialogNotActivateOwnerTest: Test clashes with another test with a similar name Reviewed-by: serb, aghaisas --- .../DisposeDialogNotActivateOwnerTest.html | 44 ------------------- 1 file changed, 44 deletions(-) delete mode 100644 jdk/test/java/awt/Focus/DisposedWindow/DisposeDialogNotActivateOwnerTest/DisposeDialogNotActivateOwnerTest.html diff --git a/jdk/test/java/awt/Focus/DisposedWindow/DisposeDialogNotActivateOwnerTest/DisposeDialogNotActivateOwnerTest.html b/jdk/test/java/awt/Focus/DisposedWindow/DisposeDialogNotActivateOwnerTest/DisposeDialogNotActivateOwnerTest.html deleted file mode 100644 index 28ae8dfea74..00000000000 --- a/jdk/test/java/awt/Focus/DisposedWindow/DisposeDialogNotActivateOwnerTest/DisposeDialogNotActivateOwnerTest.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - -DisposeDialogNotActivateOwnerTest - - - -

DisposeDialogNotActivateOwnerTest
Bug ID: 6386592

- -

See the dialog box (usually in upper left corner) for instructions

- - - - From d1743ce9482ff244fc23e1053c66d04dfb2991af Mon Sep 17 00:00:00 2001 From: Ambarish Rapte Date: Thu, 17 Nov 2016 14:14:40 +0530 Subject: [PATCH 055/235] 6614519: [Doc] Description java.awt.dnd.DragSourceContext.getCursor() should be clarified Reviewed-by: serb, ssadetsky --- .../share/classes/java/awt/dnd/DragSourceContext.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/jdk/src/java.desktop/share/classes/java/awt/dnd/DragSourceContext.java b/jdk/src/java.desktop/share/classes/java/awt/dnd/DragSourceContext.java index 7d858548ddb..63ceb3f1706 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/dnd/DragSourceContext.java +++ b/jdk/src/java.desktop/share/classes/java/awt/dnd/DragSourceContext.java @@ -279,7 +279,7 @@ public class DragSourceContext } /** - * Sets the cursor for this drag operation to the specified + * Sets the custom cursor for this drag operation to the specified * {@code Cursor}. If the specified {@code Cursor} * is {@code null}, the default drag cursor behavior is * activated for this drag operation, otherwise it is deactivated. @@ -298,9 +298,11 @@ public class DragSourceContext } /** - * Returns the current drag {@code Cursor}. + * Returns the current custom drag {@code Cursor}. * - * @return the current drag {@code Cursor} + * @return the current custom drag {@code Cursor}, if it was set + * otherwise returns {@code null}. + * @see #setCursor */ public Cursor getCursor() { return cursor; } From b5aa3c60c0dbb26cd6a9f583666bcc1d7e6e5298 Mon Sep 17 00:00:00 2001 From: Rahul Raghavan Date: Thu, 17 Nov 2016 01:17:26 -0800 Subject: [PATCH 056/235] 8159035: com/sun/crypto/provider/Cipher/CTS/CTSMode.java test crashed due to unhandled case of cipher length value as 0 Handled 0 length input case in Java wrapper method Reviewed-by: alanb, ascarpino, kvn, sherman, thartmann --- .../com/sun/crypto/provider/CipherBlockChaining.java | 10 ++++++---- .../classes/com/sun/crypto/provider/CounterMode.java | 10 ++++++---- .../java.base/share/classes/sun/nio/cs/ISO_8859_1.java | 7 +++---- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java b/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java index f903754fb48..4e93d6fe03a 100644 --- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java +++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java @@ -142,6 +142,9 @@ class CipherBlockChaining extends FeedbackCipher { */ int encrypt(byte[] plain, int plainOffset, int plainLen, byte[] cipher, int cipherOffset) { + if (plainLen <= 0) { + return plainLen; + } cryptBlockSizeCheck(plainLen); cryptNullAndBoundsCheck(plain, plainOffset, plainLen); cryptNullAndBoundsCheck(cipher, cipherOffset, plainLen); @@ -190,6 +193,9 @@ class CipherBlockChaining extends FeedbackCipher { */ int decrypt(byte[] cipher, int cipherOffset, int cipherLen, byte[] plain, int plainOffset) { + if (cipherLen <= 0) { + return cipherLen; + } cryptBlockSizeCheck(cipherLen); cryptNullAndBoundsCheck(cipher, cipherOffset, cipherLen); cryptNullAndBoundsCheck(plain, plainOffset, cipherLen); @@ -220,10 +226,6 @@ class CipherBlockChaining extends FeedbackCipher { } private static void cryptNullAndBoundsCheck(byte[] array, int offset, int len) { - if (len <= 0) { - return; // not an error because cryptImpl/decryptImpl won't execute if len <= 0 - } - Objects.requireNonNull(array); if (offset < 0 || offset >= array.length) { diff --git a/jdk/src/java.base/share/classes/com/sun/crypto/provider/CounterMode.java b/jdk/src/java.base/share/classes/com/sun/crypto/provider/CounterMode.java index da6c10a7956..a1c33ae1593 100644 --- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/CounterMode.java +++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/CounterMode.java @@ -172,10 +172,12 @@ final class CounterMode extends FeedbackCipher { * are encrypted on demand. */ private int crypt(byte[] in, int inOff, int len, byte[] out, int outOff) { - - Objects.checkFromIndexSize(inOff, len, in.length); - Objects.checkFromIndexSize(outOff, len, out.length); - return implCrypt(in, inOff, len, out, outOff); + if (len == 0) { + return 0; + } + Objects.checkFromIndexSize(inOff, len, in.length); + Objects.checkFromIndexSize(outOff, len, out.length); + return implCrypt(in, inOff, len, out, outOff); } // Implementation of crpyt() method. Possibly replaced with a compiler intrinsic. diff --git a/jdk/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java b/jdk/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java index b5d93a8f677..f1dadedaf53 100644 --- a/jdk/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java +++ b/jdk/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java @@ -157,6 +157,9 @@ class ISO_8859_1 // Method possible replaced with a compiler intrinsic. private static int encodeISOArray(char[] sa, int sp, byte[] da, int dp, int len) { + if (len <= 0) { + return 0; + } encodeISOArrayCheck(sa, sp, da, dp, len); return implEncodeISOArray(sa, sp, da, dp, len); } @@ -177,10 +180,6 @@ class ISO_8859_1 private static void encodeISOArrayCheck(char[] sa, int sp, byte[] da, int dp, int len) { - if (len <= 0) { - return; // not an error because encodeISOArrayImpl won't execute if len <= 0 - } - Objects.requireNonNull(sa); Objects.requireNonNull(da); From 44f0e6e48205e7f10f1481a460a1fdfe015126f3 Mon Sep 17 00:00:00 2001 From: Harsha Wardhana B Date: Mon, 21 Nov 2016 12:13:39 +0530 Subject: [PATCH 057/235] 8169575: com/sun/management/DiagnosticCommandMBean/DcmdMBeanPermissionsTest.java failing with jtreg tip Reviewed-by: rriggs, fparain --- .../DiagnosticCommandMBean/DcmdMBeanPermissionsTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jdk/test/com/sun/management/DiagnosticCommandMBean/DcmdMBeanPermissionsTest.java b/jdk/test/com/sun/management/DiagnosticCommandMBean/DcmdMBeanPermissionsTest.java index 368731e9d85..748e49a0915 100644 --- a/jdk/test/com/sun/management/DiagnosticCommandMBean/DcmdMBeanPermissionsTest.java +++ b/jdk/test/com/sun/management/DiagnosticCommandMBean/DcmdMBeanPermissionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, 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 @@ -226,9 +226,10 @@ public class DcmdMBeanPermissionsTest { sm.grantPermission(new RuntimePermission("createClassLoader")); sm.grantPermission(new ReflectPermission("suppressAccessChecks")); sm.grantPermission(new java.util.logging.LoggingPermission("control", "")); - sm.grantPermission(new java.lang.RuntimePermission("exitVM.97")); + sm.grantPermission(new java.lang.RuntimePermission("exitVM.*")); sm.grantPermission(new java.lang.RuntimePermission("modifyThreadGroup")); sm.grantPermission(new java.lang.RuntimePermission("modifyThread")); + sm.grantPermission(new java.security.SecurityPermission("getProperty.jdk.jar.disabledAlgorithms")); for(MBeanOperationInfo opInfo : info.getOperations()) { Permission opPermission = new MBeanPermission(info.getClassName(), opInfo.getName(), From 9ebdadb0f06b82cd5c11910b7c6bf696fd23e9bd Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Mon, 21 Nov 2016 17:46:48 +0300 Subject: [PATCH 058/235] 8169719: WrappedPlainView.modelToView() should return Rectangle2D Reviewed-by: prr, serb, ssadetsky --- .../share/classes/javax/swing/text/WrappedPlainView.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/jdk/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java b/jdk/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java index 6bb02264dd3..dde3437adf4 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java @@ -26,6 +26,7 @@ package javax.swing.text; import java.awt.*; import java.awt.font.FontRenderContext; +import java.awt.geom.Rectangle2D; import java.lang.ref.SoftReference; import java.security.AccessController; import java.security.PrivilegedAction; @@ -750,7 +751,6 @@ public class WrappedPlainView extends BoxView implements TabExpander { * valid location in the associated document * @see View#modelToView */ - @SuppressWarnings("deprecation") public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException { Rectangle alloc = a.getBounds(); @@ -777,9 +777,11 @@ public class WrappedPlainView extends BoxView implements TabExpander { if (pos > p0) { Segment segment = SegmentCache.getSharedSegment(); loadText(segment, p0, pos); - alloc.x += Utilities.getTabbedTextWidth(segment, metrics, - alloc.x, WrappedPlainView.this, p0); + float x = alloc.x; + x += Utilities.getTabbedTextWidth(segment, metrics, x, + WrappedPlainView.this, p0); SegmentCache.releaseSharedSegment(segment); + return new Rectangle2D.Float(x, alloc.y, alloc.width, alloc.height); } return alloc; } From c71d7e10e6ae84a6eb4333350a5a928d7e18e71e Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Mon, 21 Nov 2016 15:04:37 -0800 Subject: [PATCH 059/235] 8170142: Broken links in TIFF metadata format and usage notes Change href attributes to the correct destinations Reviewed-by: prr --- .../javax/imageio/metadata/doc-files/tiff_metadata.html | 6 +++--- .../javax/imageio/plugins/tiff/BaselineTIFFTagSet.java | 2 +- .../classes/javax/imageio/plugins/tiff/FaxTIFFTagSet.java | 2 +- .../classes/javax/imageio/plugins/tiff/GeoTIFFTagSet.java | 5 +---- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/jdk/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/tiff_metadata.html b/jdk/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/tiff_metadata.html index 2fc49cfec0f..045a1025f08 100644 --- a/jdk/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/tiff_metadata.html +++ b/jdk/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/tiff_metadata.html @@ -534,7 +534,7 @@ Technical Note #2 ZLib "Deflate/Inflate" compression (see note following this table) - + Adobe Photoshop® TIFF Technical Notes (PDF) @@ -545,9 +545,9 @@ Adobe Photoshop® TIFF Technical Notes (PDF) Deflate "Zip-in-TIFF" compression (see note following this table) - + ZLIB Compressed Data Format Specification, - + DEFLATE Compressed Data Format Specification diff --git a/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/BaselineTIFFTagSet.java b/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/BaselineTIFFTagSet.java index 8c9ce8eaffa..d6181990e3f 100644 --- a/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/BaselineTIFFTagSet.java +++ b/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/BaselineTIFFTagSet.java @@ -224,7 +224,7 @@ public final class BaselineTIFFTagSet extends TIFFTagSet { * A value to be used with the "Compression" tag. * * @see #TAG_COMPRESSION - * @see DEFLATE specification + * @see DEFLATE specification * @see TIFF Specification Supplement 2 */ public static final int COMPRESSION_DEFLATE = 32946; diff --git a/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/FaxTIFFTagSet.java b/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/FaxTIFFTagSet.java index 3ecfe500673..07888435588 100644 --- a/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/FaxTIFFTagSet.java +++ b/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/FaxTIFFTagSet.java @@ -29,7 +29,7 @@ import java.util.List; /** * A class representing the extra tags found in a - * TIFF-F (RFC 2036) file. + * TIFF-F (RFC 2036) file. * * @since 9 */ diff --git a/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/GeoTIFFTagSet.java b/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/GeoTIFFTagSet.java index 4f77c2926bf..18962ed3816 100644 --- a/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/GeoTIFFTagSet.java +++ b/jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/GeoTIFFTagSet.java @@ -30,10 +30,7 @@ import java.util.List; /** * A class representing the tags found in a GeoTIFF IFD. GeoTIFF is a * standard for annotating georeferenced or geocoded raster imagery. - * The GeoTIFF specification may be found at - * {@code http://www.remotesensing.org/geotiff/spec/geotiffhome.html} - * . This class does not handle the GeoKeys referenced + * This class does not handle the GeoKeys referenced * from a GeoKeyDirectoryTag as those are not TIFF tags per se. * *

The definitions of the data types referenced by the field From 9439c78ffa8f87f26a4c12e0a2df36f4d1fdbb9f Mon Sep 17 00:00:00 2001 From: Kirill Zhaldybin Date: Wed, 23 Nov 2016 12:01:57 +0300 Subject: [PATCH 060/235] 8168492: Convert CollectedHeap_test to GTest Reviewed-by: iignatyev, tschatzl --- .../src/share/vm/gc/shared/collectedHeap.cpp | 31 ----------- .../src/share/vm/gc/shared/collectedHeap.hpp | 3 -- .../share/vm/utilities/internalVMTests.cpp | 1 - .../native/gc/shared/test_collectedHeap.cpp | 53 +++++++++++++++++++ 4 files changed, 53 insertions(+), 35 deletions(-) create mode 100644 hotspot/test/native/gc/shared/test_collectedHeap.cpp diff --git a/hotspot/src/share/vm/gc/shared/collectedHeap.cpp b/hotspot/src/share/vm/gc/shared/collectedHeap.cpp index 1ad500c890a..4f2c46913db 100644 --- a/hotspot/src/share/vm/gc/shared/collectedHeap.cpp +++ b/hotspot/src/share/vm/gc/shared/collectedHeap.cpp @@ -601,34 +601,3 @@ void CollectedHeap::initialize_reserved_region(HeapWord *start, HeapWord *end) { _reserved.set_start(start); _reserved.set_end(end); } - -/////////////// Unit tests /////////////// - -#ifndef PRODUCT -void CollectedHeap::test_is_in() { - CollectedHeap* heap = Universe::heap(); - - uintptr_t epsilon = (uintptr_t) MinObjAlignment; - uintptr_t heap_start = (uintptr_t) heap->_reserved.start(); - uintptr_t heap_end = (uintptr_t) heap->_reserved.end(); - - // Test that NULL is not in the heap. - assert(!heap->is_in(NULL), "NULL is unexpectedly in the heap"); - - // Test that a pointer to before the heap start is reported as outside the heap. - assert(heap_start >= ((uintptr_t)NULL + epsilon), "sanity"); - void* before_heap = (void*)(heap_start - epsilon); - assert(!heap->is_in(before_heap), - "before_heap: " PTR_FORMAT " is unexpectedly in the heap", p2i(before_heap)); - - // Test that a pointer to after the heap end is reported as outside the heap. - assert(heap_end <= ((uintptr_t)-1 - epsilon), "sanity"); - void* after_heap = (void*)(heap_end + epsilon); - assert(!heap->is_in(after_heap), - "after_heap: " PTR_FORMAT " is unexpectedly in the heap", p2i(after_heap)); -} - -void CollectedHeap_test() { - CollectedHeap::test_is_in(); -} -#endif diff --git a/hotspot/src/share/vm/gc/shared/collectedHeap.hpp b/hotspot/src/share/vm/gc/shared/collectedHeap.hpp index b13fa976595..774f329a5c6 100644 --- a/hotspot/src/share/vm/gc/shared/collectedHeap.hpp +++ b/hotspot/src/share/vm/gc/shared/collectedHeap.hpp @@ -612,9 +612,6 @@ class CollectedHeap : public CHeapObj { return false; } - /////////////// Unit tests /////////////// - - NOT_PRODUCT(static void test_is_in();) }; // Class to set and reset the GC cause for a CollectedHeap. diff --git a/hotspot/src/share/vm/utilities/internalVMTests.cpp b/hotspot/src/share/vm/utilities/internalVMTests.cpp index 2f401ed28b4..26a551d1676 100644 --- a/hotspot/src/share/vm/utilities/internalVMTests.cpp +++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp @@ -49,7 +49,6 @@ void InternalVMTests::run() { run_unit_test(TestVirtualSpaceNode_test); run_unit_test(TestGlobalDefinitions_test); run_unit_test(GCTimer_test); - run_unit_test(CollectedHeap_test); run_unit_test(ObjectMonitor_test); run_unit_test(DirectivesParser_test); #if INCLUDE_VM_STRUCTS diff --git a/hotspot/test/native/gc/shared/test_collectedHeap.cpp b/hotspot/test/native/gc/shared/test_collectedHeap.cpp new file mode 100644 index 00000000000..17c1a00c1a0 --- /dev/null +++ b/hotspot/test/native/gc/shared/test_collectedHeap.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2001, 2016, 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 "gc/shared/collectedHeap.hpp" +#include "unittest.hpp" + +TEST_VM(CollectedHeap, is_in) { + CollectedHeap* heap = Universe::heap(); + + uintptr_t epsilon = (uintptr_t) MinObjAlignment; + uintptr_t heap_start = (uintptr_t) heap->reserved_region().start(); + uintptr_t heap_end = (uintptr_t) heap->reserved_region().end(); + + // Test that NULL is not in the heap. + ASSERT_FALSE(heap->is_in(NULL)) << "NULL is unexpectedly in the heap"; + + // Test that a pointer to before the heap start is reported as outside the heap. + ASSERT_GE(heap_start, ((uintptr_t) NULL + epsilon)) + << "Sanity check - heap should not start at 0"; + + void* before_heap = (void*) (heap_start - epsilon); + ASSERT_FALSE(heap->is_in(before_heap)) << "before_heap: " << p2i(before_heap) + << " is unexpectedly in the heap"; + + // Test that a pointer to after the heap end is reported as outside the heap. + ASSERT_LE(heap_end, ((uintptr_t)-1 - epsilon)) + << "Sanity check - heap should not end at the end of address space"; + + void* after_heap = (void*) (heap_end + epsilon); + ASSERT_FALSE(heap->is_in(after_heap)) << "after_heap: " << p2i(after_heap) + << " is unexpectedly in the heap"; +} From 5eecf3f1e65ea8ea97830943f4802e53db86df83 Mon Sep 17 00:00:00 2001 From: Thomas Stuefe Date: Wed, 23 Nov 2016 14:33:45 +0100 Subject: [PATCH 061/235] 8167650: NMT should check for invalid MEMFLAGS Reviewed-by: dholmes, mockner, cjplummer --- hotspot/src/share/vm/services/nmtCommon.hpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/services/nmtCommon.hpp b/hotspot/src/share/vm/services/nmtCommon.hpp index f057484074f..2864ff2cfa0 100644 --- a/hotspot/src/share/vm/services/nmtCommon.hpp +++ b/hotspot/src/share/vm/services/nmtCommon.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, 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 @@ -55,7 +55,9 @@ class NMTUtil : AllStatic { public: // Map memory type to index static inline int flag_to_index(MEMFLAGS flag) { - return (flag & 0xff); + const int index = flag & 0xff; + assert(index >= 0 && index < (int)mt_number_of_types, "Index out of bounds"); + return index; } // Map memory type to human readable name @@ -65,6 +67,7 @@ class NMTUtil : AllStatic { // Map an index to memory type static MEMFLAGS index_to_flag(int index) { + assert(index >= 0 && index < (int) mt_number_of_types, "Index out of bounds"); return (MEMFLAGS)index; } From fe786e80eeb3eb0e97fcc0cdce22733496afde21 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Wed, 23 Nov 2016 14:36:32 +0100 Subject: [PATCH 062/235] =?UTF-8?q?8169931:=208k=20class=20metaspace=20chu?= =?UTF-8?q?nks=20misallocated=20from=204k=20chunk=20freelist=E2=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: mgerdin, coleenp, ehelin, stuefe --- hotspot/src/share/vm/memory/metaspace.cpp | 73 ++++++++++++++----- .../test/native/memory/test_chunkManager.cpp | 39 ++++++++++ 2 files changed, 94 insertions(+), 18 deletions(-) create mode 100644 hotspot/test/native/memory/test_chunkManager.cpp diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index d5843df1077..b0263dac9a0 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -153,7 +153,7 @@ class ChunkManager : public CHeapObj { // Map a size to a list index assuming that there are lists // for special, small, medium, and humongous chunks. - static ChunkIndex list_index(size_t size); + ChunkIndex list_index(size_t size); // Remove the chunk from its freelist. It is // expected to be on one of the _free_chunks[] lists. @@ -1787,7 +1787,11 @@ void ChunkManager::locked_print_sum_free_chunks(outputStream* st) { st->print_cr("Sum free chunk total " SIZE_FORMAT " count " SIZE_FORMAT, sum_free_chunks(), sum_free_chunks_count()); } + ChunkList* ChunkManager::free_chunks(ChunkIndex index) { + assert(index == SpecializedIndex || index == SmallIndex || index == MediumIndex, + "Bad index: %d", (int)index); + return &_free_chunks[index]; } @@ -1891,7 +1895,7 @@ Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) { } assert((word_size <= chunk->word_size()) || - list_index(chunk->word_size() == HumongousIndex), + (list_index(chunk->word_size()) == HumongousIndex), "Non-humongous variable sized chunk"); Log(gc, metaspace, freelist) log; if (log.is_debug()) { @@ -2342,22 +2346,18 @@ const char* SpaceManager::chunk_size_name(ChunkIndex index) const { } ChunkIndex ChunkManager::list_index(size_t size) { - switch (size) { - case SpecializedChunk: - assert(SpecializedChunk == ClassSpecializedChunk, - "Need branch for ClassSpecializedChunk"); - return SpecializedIndex; - case SmallChunk: - case ClassSmallChunk: - return SmallIndex; - case MediumChunk: - case ClassMediumChunk: - return MediumIndex; - default: - assert(size > MediumChunk || size > ClassMediumChunk, - "Not a humongous chunk"); - return HumongousIndex; + if (free_chunks(SpecializedIndex)->size() == size) { + return SpecializedIndex; } + if (free_chunks(SmallIndex)->size() == size) { + return SmallIndex; + } + if (free_chunks(MediumIndex)->size() == size) { + return MediumIndex; + } + + assert(size > free_chunks(MediumIndex)->size(), "Not a humongous chunk"); + return HumongousIndex; } void SpaceManager::deallocate(MetaWord* p, size_t word_size) { @@ -2381,7 +2381,7 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) { // Find the correct list and and set the current // chunk for that list. - ChunkIndex index = ChunkManager::list_index(new_chunk->word_size()); + ChunkIndex index = chunk_manager()->list_index(new_chunk->word_size()); if (index != HumongousIndex) { retire_current_chunk(); @@ -4017,4 +4017,41 @@ void TestVirtualSpaceNode_test() { TestVirtualSpaceNodeTest::test(); TestVirtualSpaceNodeTest::test_is_available(); } + +// The following test is placed here instead of a gtest / unittest file +// because the ChunkManager class is only available in this file. +void ChunkManager_test_list_index() { + ChunkManager manager(ClassSpecializedChunk, ClassSmallChunk, ClassMediumChunk); + + // Test previous bug where a query for a humongous class metachunk, + // incorrectly matched the non-class medium metachunk size. + { + assert(MediumChunk > ClassMediumChunk, "Precondition for test"); + + ChunkIndex index = manager.list_index(MediumChunk); + + assert(index == HumongousIndex, + "Requested size is larger than ClassMediumChunk," + " so should return HumongousIndex. Got index: %d", (int)index); + } + + // Check the specified sizes as well. + { + ChunkIndex index = manager.list_index(ClassSpecializedChunk); + assert(index == SpecializedIndex, "Wrong index returned. Got index: %d", (int)index); + } + { + ChunkIndex index = manager.list_index(ClassSmallChunk); + assert(index == SmallIndex, "Wrong index returned. Got index: %d", (int)index); + } + { + ChunkIndex index = manager.list_index(ClassMediumChunk); + assert(index == MediumIndex, "Wrong index returned. Got index: %d", (int)index); + } + { + ChunkIndex index = manager.list_index(ClassMediumChunk + 1); + assert(index == HumongousIndex, "Wrong index returned. Got index: %d", (int)index); + } +} + #endif diff --git a/hotspot/test/native/memory/test_chunkManager.cpp b/hotspot/test/native/memory/test_chunkManager.cpp new file mode 100644 index 00000000000..6aa5b5e392b --- /dev/null +++ b/hotspot/test/native/memory/test_chunkManager.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, 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" + +// The test function is only available in debug builds +#ifdef ASSERT + +#include "unittest.hpp" + +void ChunkManager_test_list_index(); + +TEST(ChunkManager, list_index) { + // The ChunkManager is only available in metaspace.cpp, + // so the test code is located in that file. + ChunkManager_test_list_index(); +} + +#endif // ASSERT From 557d68a5100bf4d05cdf5474d76652ef7a0c1571 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Thu, 24 Nov 2016 10:05:47 +0100 Subject: [PATCH 063/235] 8169703: G1 crashes with guarantee(pretouch_gang != NULL) failed: No pretouch gang specified Allow use of AlwaysPreTouch without passing a WorkGang. Reviewed-by: kbarrett, dfazunen, ddmitriev --- .../src/share/vm/gc/g1/g1CollectedHeap.cpp | 5 +- .../vm/gc/g1/g1PageBasedVirtualSpace.cpp | 32 ++++--- .../src/share/vm/gc/g1/heapRegionManager.cpp | 6 +- .../src/share/vm/gc/g1/heapRegionManager.hpp | 6 +- .../gc/g1/TestParallelAlwaysPreTouch.java | 46 ++++++++++ .../gc/g1/TestSharedArchiveWithPreTouch.java | 84 +++++++++++++++++++ 6 files changed, 157 insertions(+), 22 deletions(-) create mode 100644 hotspot/test/gc/g1/TestParallelAlwaysPreTouch.java create mode 100644 hotspot/test/gc/g1/TestSharedArchiveWithPreTouch.java diff --git a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp index 3bcd4675c23..fce91a80ad3 100644 --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp @@ -428,8 +428,7 @@ HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size, AllocationCo log_debug(gc, ergo, heap)("Attempt heap expansion (humongous allocation request failed). Allocation request: " SIZE_FORMAT "B", word_size * HeapWordSize); - - _hrm.expand_at(first, obj_regions); + _hrm.expand_at(first, obj_regions, workers()); g1_policy()->record_new_heap_size(num_regions()); #ifdef ASSERT @@ -741,7 +740,7 @@ bool G1CollectedHeap::alloc_archive_regions(MemRegion* ranges, size_t count) { // Perform the actual region allocation, exiting if it fails. // Then note how much new space we have allocated. - if (!_hrm.allocate_containing_regions(curr_range, &commits)) { + if (!_hrm.allocate_containing_regions(curr_range, &commits, workers())) { return false; } increase_used(word_size * HeapWordSize); diff --git a/hotspot/src/share/vm/gc/g1/g1PageBasedVirtualSpace.cpp b/hotspot/src/share/vm/gc/g1/g1PageBasedVirtualSpace.cpp index 254baeab68e..0a2a4626dfa 100644 --- a/hotspot/src/share/vm/gc/g1/g1PageBasedVirtualSpace.cpp +++ b/hotspot/src/share/vm/gc/g1/g1PageBasedVirtualSpace.cpp @@ -235,11 +235,12 @@ private: public: G1PretouchTask(char* start_address, char* end_address, size_t page_size) : AbstractGangTask("G1 PreTouch", - Universe::is_fully_initialized() ? GCId::current_raw() : - // During VM initialization there is - // no GC cycle that this task can be - // associated with. - GCId::undefined()), + Universe::is_fully_initialized() && + Thread::current()->is_Named_thread() ? GCId::current_raw() : + // During VM initialization there is + // no GC cycle that this task can be + // associated with. + GCId::undefined()), _cur_addr(start_address), _start_addr(start_address), _end_addr(end_address), @@ -262,15 +263,20 @@ public: }; void G1PageBasedVirtualSpace::pretouch(size_t start_page, size_t size_in_pages, WorkGang* pretouch_gang) { - guarantee(pretouch_gang != NULL, "No pretouch gang specified."); - - size_t num_chunks = MAX2((size_t)1, size_in_pages * _page_size / MAX2(G1PretouchTask::chunk_size(), _page_size)); - - uint num_workers = MIN2((uint)num_chunks, pretouch_gang->active_workers()); G1PretouchTask cl(page_start(start_page), bounded_end_addr(start_page + size_in_pages), _page_size); - log_debug(gc, heap)("Running %s with %u workers for " SIZE_FORMAT " work units pre-touching " SIZE_FORMAT "B.", - cl.name(), num_workers, num_chunks, size_in_pages * _page_size); - pretouch_gang->run_task(&cl, num_workers); + + if (pretouch_gang != NULL) { + size_t num_chunks = MAX2((size_t)1, size_in_pages * _page_size / MAX2(G1PretouchTask::chunk_size(), _page_size)); + + uint num_workers = MIN2((uint)num_chunks, pretouch_gang->active_workers()); + log_debug(gc, heap)("Running %s with %u workers for " SIZE_FORMAT " work units pre-touching " SIZE_FORMAT "B.", + cl.name(), num_workers, num_chunks, size_in_pages * _page_size); + pretouch_gang->run_task(&cl, num_workers); + } else { + log_debug(gc, heap)("Running %s pre-touching " SIZE_FORMAT "B.", + cl.name(), size_in_pages * _page_size); + cl.work(0); + } } bool G1PageBasedVirtualSpace::contains(const void* p) const { diff --git a/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp b/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp index 7854671bf48..91e4297eb67 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp +++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp @@ -286,7 +286,7 @@ uint HeapRegionManager::find_highest_free(bool* expanded) { while (true) { HeapRegion *hr = _regions.get_by_index(curr); if (hr == NULL) { - uint res = expand_at(curr, 1); + uint res = expand_at(curr, 1, NULL); if (res == 1) { *expanded = true; return curr; @@ -304,7 +304,7 @@ uint HeapRegionManager::find_highest_free(bool* expanded) { } } -bool HeapRegionManager::allocate_containing_regions(MemRegion range, size_t* commit_count) { +bool HeapRegionManager::allocate_containing_regions(MemRegion range, size_t* commit_count, WorkGang* pretouch_workers) { size_t commits = 0; uint start_index = (uint)_regions.get_index_by_address(range.start()); uint last_index = (uint)_regions.get_index_by_address(range.last()); @@ -314,7 +314,7 @@ bool HeapRegionManager::allocate_containing_regions(MemRegion range, size_t* com for (uint curr_index = start_index; curr_index <= last_index; curr_index++) { if (!is_available(curr_index)) { commits++; - expand_at(curr_index, 1); + expand_at(curr_index, 1, pretouch_workers); } HeapRegion* curr_region = _regions.get_by_index(curr_index); if (!curr_region->is_free()) { diff --git a/hotspot/src/share/vm/gc/g1/heapRegionManager.hpp b/hotspot/src/share/vm/gc/g1/heapRegionManager.hpp index 4f8863861f2..515553dce86 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegionManager.hpp +++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.hpp @@ -210,12 +210,12 @@ public: // HeapRegions, or re-use existing ones. Returns the number of regions the // sequence was expanded by. If a HeapRegion allocation fails, the resulting // number of regions might be smaller than what's desired. - uint expand_by(uint num_regions, WorkGang* pretouch_workers = NULL); + uint expand_by(uint num_regions, WorkGang* pretouch_workers); // Makes sure that the regions from start to start+num_regions-1 are available // for allocation. Returns the number of regions that were committed to achieve // this. - uint expand_at(uint start, uint num_regions, WorkGang* pretouch_workers = NULL); + uint expand_at(uint start, uint num_regions, WorkGang* pretouch_workers); // Find a contiguous set of empty regions of length num. Returns the start index of // that set, or G1_NO_HRM_INDEX. @@ -234,7 +234,7 @@ public: // Allocate the regions that contain the address range specified, committing the // regions if necessary. Return false if any of the regions is already committed // and not free, and return the number of regions newly committed in commit_count. - bool allocate_containing_regions(MemRegion range, size_t* commit_count); + bool allocate_containing_regions(MemRegion range, size_t* commit_count, WorkGang* pretouch_workers); // Apply blk->doHeapRegion() on all committed regions in address order, // terminating the iteration early if doHeapRegion() returns true. diff --git a/hotspot/test/gc/g1/TestParallelAlwaysPreTouch.java b/hotspot/test/gc/g1/TestParallelAlwaysPreTouch.java new file mode 100644 index 00000000000..75c90d0b699 --- /dev/null +++ b/hotspot/test/gc/g1/TestParallelAlwaysPreTouch.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016, 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 8169703 + * @summary Regression test to ensure AlwaysPreTouch with multiple threads works at mutator time. + * Allocates a few humongous objects that will be allocated by expanding the heap, causing concurrent parallel + * pre-touch. + * @requires vm.gc.G1 + * @key gc + * @key regression + * @run main/othervm -XX:+UseG1GC -Xms10M -Xmx100m -XX:G1HeapRegionSize=1M -XX:+AlwaysPreTouch -XX:PreTouchParallelChunkSize=512k -Xlog:gc+ergo+heap=debug,gc+heap=debug,gc=debug TestParallelAlwaysPreTouch + */ + +public class TestParallelAlwaysPreTouch { + public static void main(String[] args) throws Exception { + final int M = 1024 * 1024; // Something guaranteed to be larger than a region to be counted as humongous. + + for (int i = 0; i < 10; i++) { + Object[] obj = new Object[M]; + System.out.println(obj); + } + } +} + diff --git a/hotspot/test/gc/g1/TestSharedArchiveWithPreTouch.java b/hotspot/test/gc/g1/TestSharedArchiveWithPreTouch.java new file mode 100644 index 00000000000..183c7c8acf4 --- /dev/null +++ b/hotspot/test/gc/g1/TestSharedArchiveWithPreTouch.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2016, 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 8169703 + * @summary Verifies that dumping and loading a CDS archive succeeds with AlwaysPreTouch + * @requires vm.gc.G1 + * @key gc + * @key regression + * @library /test/lib + * @modules java.base/jdk.internal.misc + * java.management + * @run main TestSharedArchiveWithPreTouch + */ + +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; + +import jdk.test.lib.Platform; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; + +public class TestSharedArchiveWithPreTouch { + public static void main(String[] args) throws Exception { + final String ArchiveFileName = "./SharedArchiveWithPreTouch.jsa"; + + final List BaseOptions = Arrays.asList(new String[] {"-XX:+UseG1GC", "-XX:+AlwaysPreTouch", + "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=" + ArchiveFileName }); + + ProcessBuilder pb; + + List dump_args = new ArrayList(BaseOptions); + + if (Platform.is64bit()) { + dump_args.addAll(0, Arrays.asList(new String[] { "-XX:+UseCompressedClassPointers", "-XX:+UseCompressedOops" })); + } + dump_args.addAll(Arrays.asList(new String[] { "-Xshare:dump" })); + + pb = ProcessTools.createJavaProcessBuilder(dump_args.toArray(new String[0])); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + try { + output.shouldContain("Loading classes to share"); + output.shouldHaveExitValue(0); + + List load_args = new ArrayList(BaseOptions); + + if (Platform.is64bit()) { + load_args.addAll(0, Arrays.asList(new String[] { "-XX:+UseCompressedClassPointers", "-XX:+UseCompressedOops" })); + } + load_args.addAll(Arrays.asList(new String[] { "-Xshare:on", "-version" })); + + pb = ProcessTools.createJavaProcessBuilder(load_args.toArray(new String[0])); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("sharing"); + output.shouldHaveExitValue(0); + } catch (RuntimeException e) { + // Report 'passed' if CDS was turned off. + output.shouldContain("Unable to use shared archive"); + output.shouldHaveExitValue(1); + } + } +} From 06bd79afed721ea3aeb8c5ed89268a8c4e9608c5 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Thu, 24 Nov 2016 11:27:57 +0100 Subject: [PATCH 064/235] 8057003: Large reference arrays cause extremely long synchronization times Slice large object arrays into parts so that the synchronization of marking threads with an STW pause request does not take long. Reviewed-by: ehelin, pliden --- .../src/share/vm/gc/g1/g1ConcurrentMark.cpp | 17 ++-- .../src/share/vm/gc/g1/g1ConcurrentMark.hpp | 9 +- .../vm/gc/g1/g1ConcurrentMark.inline.hpp | 28 ++++-- .../g1/g1ConcurrentMarkObjArrayProcessor.cpp | 87 +++++++++++++++++++ .../g1/g1ConcurrentMarkObjArrayProcessor.hpp | 70 +++++++++++++++ ...ConcurrentMarkObjArrayProcessor.inline.hpp | 36 ++++++++ hotspot/src/share/vm/runtime/globals.hpp | 2 +- 7 files changed, 227 insertions(+), 22 deletions(-) create mode 100644 hotspot/src/share/vm/gc/g1/g1ConcurrentMarkObjArrayProcessor.cpp create mode 100644 hotspot/src/share/vm/gc/g1/g1ConcurrentMarkObjArrayProcessor.hpp create mode 100644 hotspot/src/share/vm/gc/g1/g1ConcurrentMarkObjArrayProcessor.inline.hpp diff --git a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp index 52a9f4817ab..bf507f20c39 100644 --- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp +++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp @@ -2009,10 +2009,10 @@ public: { } void operator()(oop obj) const { - guarantee(obj->is_oop(), + guarantee(G1CMObjArrayProcessor::is_array_slice(obj) || obj->is_oop(), "Non-oop " PTR_FORMAT ", phase: %s, info: %d", p2i(obj), _phase, _info); - guarantee(!_g1h->obj_in_cs(obj), + guarantee(G1CMObjArrayProcessor::is_array_slice(obj) || !_g1h->obj_in_cs(obj), "obj: " PTR_FORMAT " in CSet, phase: %s, info: %d", p2i(obj), _phase, _info); } @@ -2436,6 +2436,7 @@ bool G1CMTask::get_entries_from_global_stack() { if (elem == NULL) { break; } + assert(G1CMObjArrayProcessor::is_array_slice(elem) || elem->is_oop(), "Element " PTR_FORMAT " must be an array slice or oop", p2i(elem)); bool success = _task_queue->push(elem); // We only call this when the local queue is empty or under a // given target limit. So, we do not expect this push to fail. @@ -2448,7 +2449,9 @@ bool G1CMTask::get_entries_from_global_stack() { } void G1CMTask::drain_local_queue(bool partially) { - if (has_aborted()) return; + if (has_aborted()) { + return; + } // Decide what the target size is, depending whether we're going to // drain it partially (so that other tasks can steal if they run out @@ -2464,12 +2467,7 @@ void G1CMTask::drain_local_queue(bool partially) { oop obj; bool ret = _task_queue->pop_local(obj); while (ret) { - assert(_g1h->is_in_g1_reserved((HeapWord*) obj), "invariant" ); - assert(!_g1h->is_on_master_free_list( - _g1h->heap_region_containing((HeapWord*) obj)), "invariant"); - scan_object(obj); - if (_task_queue->size() <= target_size || has_aborted()) { ret = false; } else { @@ -2880,8 +2878,6 @@ void G1CMTask::do_marking_step(double time_target_ms, while (!has_aborted()) { oop obj; if (_cm->try_stealing(_worker_id, &_hash_seed, obj)) { - assert(_nextMarkBitMap->isMarked((HeapWord*) obj), - "any stolen object should be marked"); scan_object(obj); // And since we're towards the end, let's totally drain the @@ -3003,6 +2999,7 @@ G1CMTask::G1CMTask(uint worker_id, G1CMTaskQueueSet* task_queues) : _g1h(G1CollectedHeap::heap()), _worker_id(worker_id), _cm(cm), + _objArray_processor(this), _claimed(false), _nextMarkBitMap(NULL), _hash_seed(17), _task_queue(task_queue), diff --git a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp index 68cc2b42bb8..277e9fe2596 100644 --- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp +++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp @@ -26,6 +26,7 @@ #define SHARE_VM_GC_G1_G1CONCURRENTMARK_HPP #include "classfile/javaClasses.hpp" +#include "gc/g1/g1ConcurrentMarkObjArrayProcessor.hpp" #include "gc/g1/g1RegionToSpaceMapper.hpp" #include "gc/g1/heapRegionSet.hpp" #include "gc/shared/taskqueue.hpp" @@ -706,11 +707,13 @@ private: words_scanned_period = 12*1024, // The regular clock call is called once the number of visited // references reaches this limit - refs_reached_period = 384, + refs_reached_period = 1024, // Initial value for the hash seed, used in the work stealing code init_hash_seed = 17 }; + G1CMObjArrayProcessor _objArray_processor; + uint _worker_id; G1CollectedHeap* _g1h; G1ConcurrentMark* _cm; @@ -826,8 +829,10 @@ private: bool is_below_finger(oop obj, HeapWord* global_finger) const; template void process_grey_object(oop obj); - public: + // Apply the closure on the given area of the objArray. Return the number of words + // scanned. + inline size_t scan_objArray(objArrayOop obj, MemRegion mr); // It resets the task; it should be called right at the beginning of // a marking phase. void reset(G1CMBitMap* _nextMarkBitMap); diff --git a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp index af42c85920c..13bd0b56167 100644 --- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp +++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp @@ -27,6 +27,7 @@ #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1ConcurrentMark.hpp" +#include "gc/g1/g1ConcurrentMarkObjArrayProcessor.inline.hpp" #include "gc/g1/suspendibleThreadSet.hpp" #include "gc/shared/taskqueue.inline.hpp" @@ -117,11 +118,11 @@ inline void G1CMTask::scan_object(oop obj) { process_grey_object(obj); } inline void G1CMTask::push(oop obj) { HeapWord* objAddr = (HeapWord*) obj; - assert(_g1h->is_in_g1_reserved(objAddr), "invariant"); - assert(!_g1h->is_on_master_free_list( + assert(G1CMObjArrayProcessor::is_array_slice(obj) || _g1h->is_in_g1_reserved(objAddr), "invariant"); + assert(G1CMObjArrayProcessor::is_array_slice(obj) || !_g1h->is_on_master_free_list( _g1h->heap_region_containing((HeapWord*) objAddr)), "invariant"); - assert(!_g1h->is_obj_ill(obj), "invariant"); - assert(_nextMarkBitMap->isMarked(objAddr), "invariant"); + assert(G1CMObjArrayProcessor::is_array_slice(obj) || !_g1h->is_obj_ill(obj), "invariant"); + assert(G1CMObjArrayProcessor::is_array_slice(obj) || _nextMarkBitMap->isMarked(objAddr), "invariant"); if (!_task_queue->push(obj)) { // The local task queue looks full. We need to push some entries @@ -169,17 +170,26 @@ inline bool G1CMTask::is_below_finger(oop obj, HeapWord* global_finger) const { template inline void G1CMTask::process_grey_object(oop obj) { assert(scan || obj->is_typeArray(), "Skipping scan of grey non-typeArray"); - assert(_nextMarkBitMap->isMarked((HeapWord*) obj), "invariant"); - - size_t obj_size = obj->size(); - _words_scanned += obj_size; + assert(G1CMObjArrayProcessor::is_array_slice(obj) || _nextMarkBitMap->isMarked((HeapWord*) obj), + "Any stolen object should be a slice or marked"); if (scan) { - obj->oop_iterate(_cm_oop_closure); + if (G1CMObjArrayProcessor::is_array_slice(obj)) { + _words_scanned += _objArray_processor.process_slice(obj); + } else if (G1CMObjArrayProcessor::should_be_sliced(obj)) { + _words_scanned += _objArray_processor.process_obj(obj); + } else { + _words_scanned += obj->oop_iterate_size(_cm_oop_closure);; + } } check_limits(); } +inline size_t G1CMTask::scan_objArray(objArrayOop obj, MemRegion mr) { + obj->oop_iterate(_cm_oop_closure, mr); + return mr.word_size(); +} + inline void G1CMTask::make_reference_grey(oop obj) { if (_cm->par_mark(obj)) { // No OrderAccess:store_load() is needed. It is implicit in the diff --git a/hotspot/src/share/vm/gc/g1/g1ConcurrentMarkObjArrayProcessor.cpp b/hotspot/src/share/vm/gc/g1/g1ConcurrentMarkObjArrayProcessor.cpp new file mode 100644 index 00000000000..d74bbd79bc0 --- /dev/null +++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMarkObjArrayProcessor.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2016, 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 "gc/g1/g1ConcurrentMark.inline.hpp" +#include "gc/g1/g1ConcurrentMarkObjArrayProcessor.inline.hpp" + +oop G1CMObjArrayProcessor::encode_array_slice(HeapWord* addr) { + return oop((void*)((uintptr_t)addr | ArraySliceBit)); +} + +HeapWord* G1CMObjArrayProcessor::decode_array_slice(oop value) { + assert(is_array_slice(value), "Given value " PTR_FORMAT " is not an array slice", p2i(value)); + return (HeapWord*)((uintptr_t)(void*)value & ~ArraySliceBit); +} + +void G1CMObjArrayProcessor::push_array_slice(HeapWord* what) { + oop obj = encode_array_slice(what); + _task->push(obj); +} + +size_t G1CMObjArrayProcessor::process_array_slice(objArrayOop obj, HeapWord* start_from, size_t remaining) { + size_t words_to_scan = MIN2(remaining, ObjArrayMarkingStride); + + if (remaining > ObjArrayMarkingStride) { + push_array_slice(start_from + ObjArrayMarkingStride); + } + + // Then process current area. + MemRegion mr(start_from, words_to_scan); + return _task->scan_objArray(obj, mr); +} + +size_t G1CMObjArrayProcessor::process_obj(oop obj) { + assert(should_be_sliced(obj), "Must be an array object %d and large " SIZE_FORMAT, obj->is_objArray(), (size_t)obj->size()); + + return process_array_slice(objArrayOop(obj), (HeapWord*)obj, (size_t)objArrayOop(obj)->size()); +} + +size_t G1CMObjArrayProcessor::process_slice(oop obj) { + HeapWord* const decoded_address = decode_array_slice(obj); + + // Find the start address of the objArrayOop. + // Shortcut the BOT access if the given address is from a humongous object. The BOT + // slide is fast enough for "smaller" objects in non-humongous regions, but is slower + // than directly using heap region table. + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + HeapRegion* r = g1h->heap_region_containing(decoded_address); + + HeapWord* const start_address = r->is_humongous() ? + r->humongous_start_region()->bottom() : + g1h->block_start(decoded_address); + + assert(oop(start_address)->is_objArray(), "Address " PTR_FORMAT " does not refer to an object array ", p2i(start_address)); + assert(start_address < decoded_address, + "Object start address " PTR_FORMAT " must be smaller than decoded address " PTR_FORMAT, + p2i(start_address), + p2i(decoded_address)); + + objArrayOop objArray = objArrayOop(start_address); + + size_t already_scanned = decoded_address - start_address; + size_t remaining = objArray->size() - already_scanned; + + return process_array_slice(objArray, decoded_address, remaining); +} diff --git a/hotspot/src/share/vm/gc/g1/g1ConcurrentMarkObjArrayProcessor.hpp b/hotspot/src/share/vm/gc/g1/g1ConcurrentMarkObjArrayProcessor.hpp new file mode 100644 index 00000000000..9e16e98629c --- /dev/null +++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMarkObjArrayProcessor.hpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016, 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_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_HPP +#define SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_HPP + +#include "oops/oopsHierarchy.hpp" +#include "memory/allocation.hpp" + +class G1CMTask; + +// Helper class to mark through large objArrays during marking in an efficient way. +// Instead of pushing large object arrays, we push continuations onto the +// mark stack. These continuations are identified by having their LSB set. +// This allows incremental processing of large objects. +class G1CMObjArrayProcessor VALUE_OBJ_CLASS_SPEC { +private: + // The bit mask for the continuation indicator of elements on the mark stack. + static const size_t ArraySliceBit = 1; + + // Reference to the task for doing the actual work. + G1CMTask* _task; + + // Encodes the given address as a continuation "oop". + oop encode_array_slice(HeapWord* addr); + // Remove the continuation marker from the given oop from the mark stack. + HeapWord* decode_array_slice(oop value); + + // Push the continuation at the given address onto the mark stack. + void push_array_slice(HeapWord* addr); + + // Process (apply the closure) on the given continuation of the given objArray. + size_t process_array_slice(objArrayOop const obj, HeapWord* start_from, size_t remaining); +public: + static bool is_array_slice(void* obj) { return ((uintptr_t)obj & ArraySliceBit) != 0; } + + static bool should_be_sliced(oop obj); + + G1CMObjArrayProcessor(G1CMTask* task) : _task(task) { + } + + // Process the given continuation "oop". Returns the number of words scanned. + size_t process_slice(oop obj); + // Start processing the given objArrayOop by scanning the header and pushing its + // continuation. + size_t process_obj(oop obj); +}; + +#endif /* SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_HPP */ diff --git a/hotspot/src/share/vm/gc/g1/g1ConcurrentMarkObjArrayProcessor.inline.hpp b/hotspot/src/share/vm/gc/g1/g1ConcurrentMarkObjArrayProcessor.inline.hpp new file mode 100644 index 00000000000..8c8481b9deb --- /dev/null +++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMarkObjArrayProcessor.inline.hpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, 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_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_INLINE_HPP +#define SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_INLINE_HPP + +#include "oops/oop.inline.hpp" +#include "oops/oopsHierarchy.hpp" +#include "runtime/globals.hpp" + +inline bool G1CMObjArrayProcessor::should_be_sliced(oop obj) { + return obj->is_objArray() && ((size_t)((objArrayOop)obj)->size()) >= 2 * ObjArrayMarkingStride; +} + +#endif /* SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_INLINE_HPP */ diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 3afe94f685e..018bfdc1996 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -1988,7 +1988,7 @@ public: experimental(uintx, WorkStealingSpinToYieldRatio, 10, \ "Ratio of hard spins to calls to yield") \ \ - develop(uintx, ObjArrayMarkingStride, 512, \ + develop(uintx, ObjArrayMarkingStride, 2048, \ "Number of object array elements to push onto the marking stack " \ "before pushing a continuation entry") \ \ From 9a28eb07452f6d8ec44608f9d6f7cd7cb180b3b3 Mon Sep 17 00:00:00 2001 From: Leonid Mesnik Date: Thu, 24 Nov 2016 16:48:22 +0300 Subject: [PATCH 065/235] 8166898: G1SATBCardTableLoggingModRefBS::invalidate() incorrect with whole_heap == true Reviewed-by: tschatzl, kbarrett --- .../vm/gc/g1/g1SATBCardTableModRefBS.cpp | 57 ++++++++----------- .../vm/gc/g1/g1SATBCardTableModRefBS.hpp | 2 +- .../share/vm/gc/shared/cardTableModRefBS.cpp | 2 +- .../share/vm/gc/shared/cardTableModRefBS.hpp | 2 +- .../src/share/vm/gc/shared/cardTableRS.hpp | 4 +- .../share/vm/gc/shared/modRefBarrierSet.hpp | 6 +- 6 files changed, 32 insertions(+), 41 deletions(-) diff --git a/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp b/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp index 006a658f5d8..a597ab9d2b0 100644 --- a/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp +++ b/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp @@ -178,44 +178,37 @@ G1SATBCardTableLoggingModRefBS::write_ref_field_work(void* field, } void -G1SATBCardTableLoggingModRefBS::invalidate(MemRegion mr, bool whole_heap) { +G1SATBCardTableLoggingModRefBS::invalidate(MemRegion mr) { volatile jbyte* byte = byte_for(mr.start()); jbyte* last_byte = byte_for(mr.last()); Thread* thr = Thread::current(); - if (whole_heap) { - while (byte <= last_byte) { - *byte = dirty_card; - byte++; - } - } else { // skip all consecutive young cards - for (; byte <= last_byte && *byte == g1_young_gen; byte++); + for (; byte <= last_byte && *byte == g1_young_gen; byte++); - if (byte <= last_byte) { - OrderAccess::storeload(); - // Enqueue if necessary. - if (thr->is_Java_thread()) { - JavaThread* jt = (JavaThread*)thr; - for (; byte <= last_byte; byte++) { - if (*byte == g1_young_gen) { - continue; - } - if (*byte != dirty_card) { - *byte = dirty_card; - jt->dirty_card_queue().enqueue(byte); - } + if (byte <= last_byte) { + OrderAccess::storeload(); + // Enqueue if necessary. + if (thr->is_Java_thread()) { + JavaThread* jt = (JavaThread*)thr; + for (; byte <= last_byte; byte++) { + if (*byte == g1_young_gen) { + continue; } - } else { - MutexLockerEx x(Shared_DirtyCardQ_lock, - Mutex::_no_safepoint_check_flag); - for (; byte <= last_byte; byte++) { - if (*byte == g1_young_gen) { - continue; - } - if (*byte != dirty_card) { - *byte = dirty_card; - _dcqs.shared_dirty_card_queue()->enqueue(byte); - } + if (*byte != dirty_card) { + *byte = dirty_card; + jt->dirty_card_queue().enqueue(byte); + } + } + } else { + MutexLockerEx x(Shared_DirtyCardQ_lock, + Mutex::_no_safepoint_check_flag); + for (; byte <= last_byte; byte++) { + if (*byte == g1_young_gen) { + continue; + } + if (*byte != dirty_card) { + *byte = dirty_card; + _dcqs.shared_dirty_card_queue()->enqueue(byte); } } } diff --git a/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.hpp b/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.hpp index d07d6c507b0..0cd8970a89b 100644 --- a/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.hpp +++ b/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.hpp @@ -152,7 +152,7 @@ class G1SATBCardTableLoggingModRefBS: public G1SATBCardTableModRefBS { // NB: if you do a whole-heap invalidation, the "usual invariant" defined // above no longer applies. - void invalidate(MemRegion mr, bool whole_heap = false); + void invalidate(MemRegion mr); void write_region_work(MemRegion mr) { invalidate(mr); } void write_ref_array_work(MemRegion mr) { invalidate(mr); } diff --git a/hotspot/src/share/vm/gc/shared/cardTableModRefBS.cpp b/hotspot/src/share/vm/gc/shared/cardTableModRefBS.cpp index 9053dedba0f..0d781f3a860 100644 --- a/hotspot/src/share/vm/gc/shared/cardTableModRefBS.cpp +++ b/hotspot/src/share/vm/gc/shared/cardTableModRefBS.cpp @@ -380,7 +380,7 @@ void CardTableModRefBS::dirty_MemRegion(MemRegion mr) { } } -void CardTableModRefBS::invalidate(MemRegion mr, bool whole_heap) { +void CardTableModRefBS::invalidate(MemRegion mr) { assert((HeapWord*)align_size_down((uintptr_t)mr.start(), HeapWordSize) == mr.start(), "Unaligned start"); assert((HeapWord*)align_size_up ((uintptr_t)mr.end(), HeapWordSize) == mr.end(), "Unaligned end" ); for (int i = 0; i < _cur_covered_regions; i++) { diff --git a/hotspot/src/share/vm/gc/shared/cardTableModRefBS.hpp b/hotspot/src/share/vm/gc/shared/cardTableModRefBS.hpp index 89084ca8ac2..d1db7f314ad 100644 --- a/hotspot/src/share/vm/gc/shared/cardTableModRefBS.hpp +++ b/hotspot/src/share/vm/gc/shared/cardTableModRefBS.hpp @@ -260,7 +260,7 @@ public: } // ModRefBS functions. - virtual void invalidate(MemRegion mr, bool whole_heap = false); + virtual void invalidate(MemRegion mr); void clear(MemRegion mr); void dirty(MemRegion mr); diff --git a/hotspot/src/share/vm/gc/shared/cardTableRS.hpp b/hotspot/src/share/vm/gc/shared/cardTableRS.hpp index 2a11147b4cb..5139580b61f 100644 --- a/hotspot/src/share/vm/gc/shared/cardTableRS.hpp +++ b/hotspot/src/share/vm/gc/shared/cardTableRS.hpp @@ -159,8 +159,8 @@ public: void clear(MemRegion mr) { _ct_bs->clear(mr); } void clear_into_younger(Generation* old_gen); - void invalidate(MemRegion mr, bool whole_heap = false) { - _ct_bs->invalidate(mr, whole_heap); + void invalidate(MemRegion mr) { + _ct_bs->invalidate(mr); } void invalidate_or_clear(Generation* old_gen); diff --git a/hotspot/src/share/vm/gc/shared/modRefBarrierSet.hpp b/hotspot/src/share/vm/gc/shared/modRefBarrierSet.hpp index f82db2c5493..8b65f610d4f 100644 --- a/hotspot/src/share/vm/gc/shared/modRefBarrierSet.hpp +++ b/hotspot/src/share/vm/gc/shared/modRefBarrierSet.hpp @@ -86,10 +86,8 @@ public: assert(false, "can't call"); } - // Causes all refs in "mr" to be assumed to be modified. If "whole_heap" - // is true, the caller asserts that the entire heap is being invalidated, - // which may admit an optimized implementation for some barriers. - virtual void invalidate(MemRegion mr, bool whole_heap = false) = 0; + // Causes all refs in "mr" to be assumed to be modified. + virtual void invalidate(MemRegion mr) = 0; // The caller guarantees that "mr" contains no references. (Perhaps it's // objects have been moved elsewhere.) From e05aabe8ab9ded075cc4b48396d3c2a63b8adb18 Mon Sep 17 00:00:00 2001 From: Leonid Mesnik Date: Thu, 24 Nov 2016 16:52:34 +0300 Subject: [PATCH 066/235] 8166761: Compiler testing in tier2 should be optimized to finish in 20 minutes Reviewed-by: ctornqvi, kvn --- hotspot/test/TEST.groups | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index 9c247c76f24..652c19a5c1b 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -52,19 +52,19 @@ hotspot_all = \ / - + hotspot_compiler = \ compiler - + hotspot_gc = \ gc hotspot_runtime = \ runtime - + hotspot_serviceability = \ serviceability - + hotspot_misc = \ / \ -:hotspot_compiler \ @@ -330,6 +330,13 @@ hotspot_fast_compiler_3 = \ hotspot_fast_compiler_closed = \ sanity/ExecuteInternalVMTests.java +hotspot_not_fast_compiler = \ + :hotspot_compiler \ + -:hotspot_fast_compiler_1 \ + -:hotspot_fast_compiler_2 \ + -:hotspot_fast_compiler_3 \ + -:hotspot_fast_compiler_closed + hotspot_fast_gc_1 = \ gc/g1/ @@ -414,7 +421,7 @@ hotspot_jprt = \ :hotspot_fast_gc_gcold \ :hotspot_fast_runtime \ :hotspot_fast_serviceability - + hotspot_runtime_tier2 = \ runtime/ \ serviceability/ \ @@ -423,11 +430,11 @@ hotspot_runtime_tier2 = \ -:hotspot_fast_runtime \ -:hotspot_fast_serviceability \ -:hotspot_runtime_tier2_platform_agnostic - + hotspot_runtime_tier2_platform_agnostic = \ runtime/SelectionResolution \ -:hotspot_fast_runtime - + hotspot_runtime_tier3 = \ runtime/ \ serviceability/ \ @@ -440,7 +447,7 @@ hotspot_runtime_minimalvm = \ runtime/MinimalVM \ runtime/ErrorHandling \ runtime/logging - + #All tests that depends on nashorn extension. # needs_nashorn = \ From 63693b7bb6e8e097cdec6518b93cc7801f225095 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Thu, 24 Nov 2016 15:27:53 +0100 Subject: [PATCH 067/235] 8170284: Move fine granular hotspot make targets to top level Reviewed-by: tbell --- hotspot/make/BuildHotspot.gmk | 51 ----------------------------------- 1 file changed, 51 deletions(-) delete mode 100644 hotspot/make/BuildHotspot.gmk diff --git a/hotspot/make/BuildHotspot.gmk b/hotspot/make/BuildHotspot.gmk deleted file mode 100644 index 0ac43f6283c..00000000000 --- a/hotspot/make/BuildHotspot.gmk +++ /dev/null @@ -1,51 +0,0 @@ -# -# Copyright (c) 2015, 2016, 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. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# 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. -# - -# This must be the first rule -default: all - -include $(SPEC) -include MakeBase.gmk - -VARIANT_TARGETS := $(foreach v, $(JVM_VARIANTS), variant-$v) -VARIANT_GENSRC_TARGETS := $(addsuffix -gensrc, $(VARIANT_TARGETS)) -VARIANT_LIBS_TARGETS := $(addsuffix -libs, $(VARIANT_TARGETS)) - -$(VARIANT_GENSRC_TARGETS): variant-%-gensrc: - $(call LogWarn, Building JVM variant '$*' with features '$(JVM_FEATURES_$*)') - +$(MAKE) -f gensrc/GenerateSources.gmk JVM_VARIANT=$* - -$(VARIANT_LIBS_TARGETS): variant-%-libs: variant-%-gensrc - +$(MAKE) -f lib/CompileLibraries.gmk JVM_VARIANT=$* - -$(VARIANT_TARGETS): variant-%: variant-%-gensrc variant-%-libs - -jsig: - +$(MAKE) -f lib/CompileLibjsig.gmk - -all: $(VARIANT_TARGETS) jsig - -.PHONY: $(VARIANT_TARGETS) $(VARIANT_GENSRC_TARGETS) $(VARIANT_LIBS_TARGETS) \ - jsig all From 484e62c39f53b9c5b0229045f12e395cbf0cfbab Mon Sep 17 00:00:00 2001 From: Igor Ignatyev Date: Fri, 25 Nov 2016 11:59:40 +0300 Subject: [PATCH 068/235] 8170228: register closed @requires property setter Reviewed-by: vlivanov, dfazunen --- hotspot/test/TEST.ROOT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/test/TEST.ROOT b/hotspot/test/TEST.ROOT index 4fe2b2a0e51..393e1382967 100644 --- a/hotspot/test/TEST.ROOT +++ b/hotspot/test/TEST.ROOT @@ -34,7 +34,7 @@ groups=TEST.groups [closed/TEST.groups] # Source files for classes that will be used at the beginning of each test suite run, # to determine additional characteristics of the system for use with the @requires tag. # Note: compiled bootlibs code will be located in the folder 'bootClasses' -requires.extraPropDefns = ../../test/jtreg-ext/requires/VMProps.java +requires.extraPropDefns = ../../test/jtreg-ext/requires/VMProps.java [../../closed/test/jtreg-ext/requires/VMPropsExt.java] requires.extraPropDefns.bootlibs = ../../test/lib/sun requires.extraPropDefns.vmOpts = -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:bootClasses requires.properties= \ From 11802f94e80689b31eddb720b8d50e24b0aa40af Mon Sep 17 00:00:00 2001 From: Jesper Wilhelmsson Date: Fri, 25 Nov 2016 15:58:24 +0100 Subject: [PATCH 069/235] 8170355: [BACKOUT] 8k class metaspace chunks misallocated from 4k chunk freelist Reviewed-by: ehelin, stefank --- hotspot/src/share/vm/memory/metaspace.cpp | 73 +++++-------------- .../test/native/memory/test_chunkManager.cpp | 39 ---------- 2 files changed, 18 insertions(+), 94 deletions(-) delete mode 100644 hotspot/test/native/memory/test_chunkManager.cpp diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index b0263dac9a0..d5843df1077 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -153,7 +153,7 @@ class ChunkManager : public CHeapObj { // Map a size to a list index assuming that there are lists // for special, small, medium, and humongous chunks. - ChunkIndex list_index(size_t size); + static ChunkIndex list_index(size_t size); // Remove the chunk from its freelist. It is // expected to be on one of the _free_chunks[] lists. @@ -1787,11 +1787,7 @@ void ChunkManager::locked_print_sum_free_chunks(outputStream* st) { st->print_cr("Sum free chunk total " SIZE_FORMAT " count " SIZE_FORMAT, sum_free_chunks(), sum_free_chunks_count()); } - ChunkList* ChunkManager::free_chunks(ChunkIndex index) { - assert(index == SpecializedIndex || index == SmallIndex || index == MediumIndex, - "Bad index: %d", (int)index); - return &_free_chunks[index]; } @@ -1895,7 +1891,7 @@ Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) { } assert((word_size <= chunk->word_size()) || - (list_index(chunk->word_size()) == HumongousIndex), + list_index(chunk->word_size() == HumongousIndex), "Non-humongous variable sized chunk"); Log(gc, metaspace, freelist) log; if (log.is_debug()) { @@ -2346,18 +2342,22 @@ const char* SpaceManager::chunk_size_name(ChunkIndex index) const { } ChunkIndex ChunkManager::list_index(size_t size) { - if (free_chunks(SpecializedIndex)->size() == size) { - return SpecializedIndex; + switch (size) { + case SpecializedChunk: + assert(SpecializedChunk == ClassSpecializedChunk, + "Need branch for ClassSpecializedChunk"); + return SpecializedIndex; + case SmallChunk: + case ClassSmallChunk: + return SmallIndex; + case MediumChunk: + case ClassMediumChunk: + return MediumIndex; + default: + assert(size > MediumChunk || size > ClassMediumChunk, + "Not a humongous chunk"); + return HumongousIndex; } - if (free_chunks(SmallIndex)->size() == size) { - return SmallIndex; - } - if (free_chunks(MediumIndex)->size() == size) { - return MediumIndex; - } - - assert(size > free_chunks(MediumIndex)->size(), "Not a humongous chunk"); - return HumongousIndex; } void SpaceManager::deallocate(MetaWord* p, size_t word_size) { @@ -2381,7 +2381,7 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) { // Find the correct list and and set the current // chunk for that list. - ChunkIndex index = chunk_manager()->list_index(new_chunk->word_size()); + ChunkIndex index = ChunkManager::list_index(new_chunk->word_size()); if (index != HumongousIndex) { retire_current_chunk(); @@ -4017,41 +4017,4 @@ void TestVirtualSpaceNode_test() { TestVirtualSpaceNodeTest::test(); TestVirtualSpaceNodeTest::test_is_available(); } - -// The following test is placed here instead of a gtest / unittest file -// because the ChunkManager class is only available in this file. -void ChunkManager_test_list_index() { - ChunkManager manager(ClassSpecializedChunk, ClassSmallChunk, ClassMediumChunk); - - // Test previous bug where a query for a humongous class metachunk, - // incorrectly matched the non-class medium metachunk size. - { - assert(MediumChunk > ClassMediumChunk, "Precondition for test"); - - ChunkIndex index = manager.list_index(MediumChunk); - - assert(index == HumongousIndex, - "Requested size is larger than ClassMediumChunk," - " so should return HumongousIndex. Got index: %d", (int)index); - } - - // Check the specified sizes as well. - { - ChunkIndex index = manager.list_index(ClassSpecializedChunk); - assert(index == SpecializedIndex, "Wrong index returned. Got index: %d", (int)index); - } - { - ChunkIndex index = manager.list_index(ClassSmallChunk); - assert(index == SmallIndex, "Wrong index returned. Got index: %d", (int)index); - } - { - ChunkIndex index = manager.list_index(ClassMediumChunk); - assert(index == MediumIndex, "Wrong index returned. Got index: %d", (int)index); - } - { - ChunkIndex index = manager.list_index(ClassMediumChunk + 1); - assert(index == HumongousIndex, "Wrong index returned. Got index: %d", (int)index); - } -} - #endif diff --git a/hotspot/test/native/memory/test_chunkManager.cpp b/hotspot/test/native/memory/test_chunkManager.cpp deleted file mode 100644 index 6aa5b5e392b..00000000000 --- a/hotspot/test/native/memory/test_chunkManager.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2016, 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" - -// The test function is only available in debug builds -#ifdef ASSERT - -#include "unittest.hpp" - -void ChunkManager_test_list_index(); - -TEST(ChunkManager, list_index) { - // The ChunkManager is only available in metaspace.cpp, - // so the test code is located in that file. - ChunkManager_test_list_index(); -} - -#endif // ASSERT From 101d945f21fa333f61c1be72cbdc8585fa1c75ec Mon Sep 17 00:00:00 2001 From: Andrew Haley Date: Tue, 22 Nov 2016 08:46:49 -0800 Subject: [PATCH 070/235] 8170106: AArch64: Multiple JVMCI issues Reviewed-by: rschatz --- .../src/cpu/aarch64/vm/assembler_aarch64.hpp | 2 +- .../aarch64/vm/jvmciCodeInstaller_aarch64.cpp | 36 +++++++++++-------- .../cpu/aarch64/vm/macroAssembler_aarch64.cpp | 13 +++++++ .../cpu/aarch64/vm/macroAssembler_aarch64.hpp | 1 + .../src/cpu/aarch64/vm/register_aarch64.hpp | 9 +++-- .../cpu/aarch64/vm/sharedRuntime_aarch64.cpp | 1 + .../src/jdk/vm/ci/aarch64/AArch64.java | 4 +++ .../aarch64/AArch64HotSpotRegisterConfig.java | 18 +++++----- 8 files changed, 58 insertions(+), 26 deletions(-) diff --git a/hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp b/hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp index 8c7901e3aca..2f97a3e11d3 100644 --- a/hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp +++ b/hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp @@ -848,7 +848,7 @@ public: // architecture. In debug mode we shrink it in order to test // trampolines, but not so small that branches in the interpreter // are out of range. - static const unsigned long branch_range = NOT_DEBUG(128 * M) DEBUG_ONLY(2 * M); + static const unsigned long branch_range = INCLUDE_JVMCI ? 128 * M : NOT_DEBUG(128 * M) DEBUG_ONLY(2 * M); static bool reachable_from_branch_at(address branch, address target) { return uabs(target - branch) < branch_range; diff --git a/hotspot/src/cpu/aarch64/vm/jvmciCodeInstaller_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/jvmciCodeInstaller_aarch64.cpp index eb3cc447d74..f9cc50fe4d0 100644 --- a/hotspot/src/cpu/aarch64/vm/jvmciCodeInstaller_aarch64.cpp +++ b/hotspot/src/cpu/aarch64/vm/jvmciCodeInstaller_aarch64.cpp @@ -41,28 +41,34 @@ jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, Hand void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle constant, TRAPS) { address pc = _instructions->start() + pc_offset; +#ifdef ASSERT + { + NativeInstruction *insn = nativeInstruction_at(pc); + if (HotSpotObjectConstantImpl::compressed(constant)) { + // Mov narrow constant: movz n << 16, movk + assert(Instruction_aarch64::extract(insn->encoding(), 31, 21) == 0b11010010101 && + nativeInstruction_at(pc+4)->is_movk(), "wrong insn in patch"); + } else { + // Move wide constant: movz n, movk, movk. + assert(nativeInstruction_at(pc+4)->is_movk() + && nativeInstruction_at(pc+8)->is_movk(), "wrong insn in patch"); + } + } +#endif // ASSERT Handle obj = HotSpotObjectConstantImpl::object(constant); jobject value = JNIHandles::make_local(obj()); - if (HotSpotObjectConstantImpl::compressed(constant)) { - int oop_index = _oop_recorder->find_index(value); - RelocationHolder rspec = oop_Relocation::spec(oop_index); - _instructions->relocate(pc, rspec, 1); - Unimplemented(); - } else { - NativeMovConstReg* move = nativeMovConstReg_at(pc); - move->set_data((intptr_t) value); - int oop_index = _oop_recorder->find_index(value); - RelocationHolder rspec = oop_Relocation::spec(oop_index); - _instructions->relocate(pc, rspec); - } + MacroAssembler::patch_oop(pc, (address)obj()); + int oop_index = _oop_recorder->find_index(value); + RelocationHolder rspec = oop_Relocation::spec(oop_index); + _instructions->relocate(pc, rspec); } void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle constant, TRAPS) { address pc = _instructions->start() + pc_offset; if (HotSpotMetaspaceConstantImpl::compressed(constant)) { narrowKlass narrowOop = record_narrow_metadata_reference(_instructions, pc, constant, CHECK); + MacroAssembler::patch_narrow_klass(pc, narrowOop); TRACE_jvmci_3("relocating (narrow metaspace constant) at " PTR_FORMAT "/0x%x", p2i(pc), narrowOop); - Unimplemented(); } else { NativeMovConstReg* move = nativeMovConstReg_at(pc); void* reference = record_metadata_reference(_instructions, pc, constant, CHECK); @@ -167,8 +173,8 @@ VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, TRAPS) { if (jvmci_reg < RegisterImpl::number_of_registers) { return as_Register(jvmci_reg)->as_VMReg(); } else { - jint floatRegisterNumber = jvmci_reg - RegisterImpl::number_of_registers; - if (floatRegisterNumber < FloatRegisterImpl::number_of_registers) { + jint floatRegisterNumber = jvmci_reg - RegisterImpl::number_of_registers_for_jvmci; + if (floatRegisterNumber >= 0 && floatRegisterNumber < FloatRegisterImpl::number_of_registers) { return as_FloatRegister(floatRegisterNumber)->as_VMReg(); } JVMCI_ERROR_NULL("invalid register number: %d", jvmci_reg); diff --git a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp index 2a2034c2fae..76ffc9d701a 100644 --- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp +++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp @@ -185,6 +185,19 @@ int MacroAssembler::patch_oop(address insn_addr, address o) { return instructions * NativeInstruction::instruction_size; } +int MacroAssembler::patch_narrow_klass(address insn_addr, narrowKlass n) { + // Metatdata pointers are either narrow (32 bits) or wide (48 bits). + // We encode narrow ones by setting the upper 16 bits in the first + // instruction. + NativeInstruction *insn = nativeInstruction_at(insn_addr); + assert(Instruction_aarch64::extract(insn->encoding(), 31, 21) == 0b11010010101 && + nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch"); + + Instruction_aarch64::patch(insn_addr, 20, 5, n >> 16); + Instruction_aarch64::patch(insn_addr+4, 20, 5, n & 0xffff); + return 2 * NativeInstruction::instruction_size; +} + address MacroAssembler::target_addr_for_insn(address insn_addr, unsigned insn) { long offset = 0; if ((Instruction_aarch64::extract(insn, 29, 24) & 0b011011) == 0b00011000) { diff --git a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp index 6c84aa6a312..207292afa53 100644 --- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp +++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp @@ -590,6 +590,7 @@ public: #endif static int patch_oop(address insn_addr, address o); + static int patch_narrow_klass(address insn_addr, narrowKlass n); address emit_trampoline_stub(int insts_call_instruction_offset, address target); diff --git a/hotspot/src/cpu/aarch64/vm/register_aarch64.hpp b/hotspot/src/cpu/aarch64/vm/register_aarch64.hpp index 6e935f687b1..8cda52a0acb 100644 --- a/hotspot/src/cpu/aarch64/vm/register_aarch64.hpp +++ b/hotspot/src/cpu/aarch64/vm/register_aarch64.hpp @@ -42,8 +42,9 @@ inline Register as_Register(int encoding) { class RegisterImpl: public AbstractRegisterImpl { public: enum { - number_of_registers = 32, - number_of_byte_registers = 32 + number_of_registers = 32, + number_of_byte_registers = 32, + number_of_registers_for_jvmci = 34 // Including SP and ZR. }; // derived registers, offsets, and addresses @@ -103,6 +104,10 @@ CONSTANT_REGISTER_DECLARATION(Register, r28, (28)); CONSTANT_REGISTER_DECLARATION(Register, r29, (29)); CONSTANT_REGISTER_DECLARATION(Register, r30, (30)); + +// r31 is not a general purpose register, but represents either the +// stack pointer or the zero/discard register depending on the +// instruction. CONSTANT_REGISTER_DECLARATION(Register, r31_sp, (31)); CONSTANT_REGISTER_DECLARATION(Register, zr, (32)); CONSTANT_REGISTER_DECLARATION(Register, sp, (33)); diff --git a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp index 8f173648f32..c8bb3543642 100644 --- a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp +++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp @@ -2388,6 +2388,7 @@ void SharedRuntime::generate_deopt_blob() { __ movw(rcpool, (int32_t)Deoptimization::Unpack_reexecute); __ mov(c_rarg0, rthread); + __ movw(c_rarg2, rcpool); // exec mode __ lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap))); diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64/AArch64.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64/AArch64.java index a21f0844c61..8bfdb509753 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64/AArch64.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64/AArch64.java @@ -84,6 +84,10 @@ public class AArch64 extends Architecture { public static final Register lr = r30; + // Used by runtime code: cannot be compiler-allocated. + public static final Register rscratch1 = r8; + public static final Register rscratch2 = r9; + // @formatter:off public static final RegisterArray cpuRegisters = new RegisterArray( r0, r1, r2, r3, r4, r5, r6, r7, diff --git a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java index 24f4e02eca6..bb02b5319b3 100644 --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java @@ -25,18 +25,19 @@ package jdk.vm.ci.hotspot.aarch64; import static jdk.vm.ci.aarch64.AArch64.lr; import static jdk.vm.ci.aarch64.AArch64.r0; import static jdk.vm.ci.aarch64.AArch64.r1; -import static jdk.vm.ci.aarch64.AArch64.r12; import static jdk.vm.ci.aarch64.AArch64.r2; -import static jdk.vm.ci.aarch64.AArch64.r27; -import static jdk.vm.ci.aarch64.AArch64.r28; -import static jdk.vm.ci.aarch64.AArch64.r29; import static jdk.vm.ci.aarch64.AArch64.r3; -import static jdk.vm.ci.aarch64.AArch64.r31; import static jdk.vm.ci.aarch64.AArch64.r4; import static jdk.vm.ci.aarch64.AArch64.r5; import static jdk.vm.ci.aarch64.AArch64.r6; import static jdk.vm.ci.aarch64.AArch64.r7; -import static jdk.vm.ci.aarch64.AArch64.r9; +import static jdk.vm.ci.aarch64.AArch64.rscratch1; +import static jdk.vm.ci.aarch64.AArch64.rscratch2; +import static jdk.vm.ci.aarch64.AArch64.r12; +import static jdk.vm.ci.aarch64.AArch64.r27; +import static jdk.vm.ci.aarch64.AArch64.r28; +import static jdk.vm.ci.aarch64.AArch64.r29; +import static jdk.vm.ci.aarch64.AArch64.r31; import static jdk.vm.ci.aarch64.AArch64.sp; import static jdk.vm.ci.aarch64.AArch64.v0; import static jdk.vm.ci.aarch64.AArch64.v1; @@ -114,7 +115,7 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig { private final RegisterArray nativeGeneralParameterRegisters = new RegisterArray(r0, r1, r2, r3, r4, r5, r6, r7); private final RegisterArray simdParameterRegisters = new RegisterArray(v0, v1, v2, v3, v4, v5, v6, v7); - public static final Register inlineCacheRegister = r9; + public static final Register inlineCacheRegister = rscratch2; /** * Vtable stubs expect the metaspace Method in r12. @@ -125,7 +126,8 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig { public static final Register threadRegister = r28; public static final Register fp = r29; - private static final RegisterArray reservedRegisters = new RegisterArray(threadRegister, fp, lr, r31, zr, sp); + private static final RegisterArray reservedRegisters + = new RegisterArray(rscratch1, rscratch2, threadRegister, fp, lr, r31, zr, sp); private static RegisterArray initAllocatable(Architecture arch, boolean reserveForHeapBase) { RegisterArray allRegisters = arch.getAvailableValueRegisters(); From ba274b43ecc68801e20c2c8354fc501d85645364 Mon Sep 17 00:00:00 2001 From: Avik Niyogi Date: Wed, 23 Nov 2016 14:28:14 +0530 Subject: [PATCH 071/235] 8138771: java.awt.image.AbstractMultiResolutionImage needs customized spec for methods of Image which it implements Reviewed-by: flar, alexsch --- .../image/AbstractMultiResolutionImage.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/jdk/src/java.desktop/share/classes/java/awt/image/AbstractMultiResolutionImage.java b/jdk/src/java.desktop/share/classes/java/awt/image/AbstractMultiResolutionImage.java index 9d190a92e2c..89c43879ac3 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/image/AbstractMultiResolutionImage.java +++ b/jdk/src/java.desktop/share/classes/java/awt/image/AbstractMultiResolutionImage.java @@ -64,27 +64,71 @@ import java.awt.Image; public abstract class AbstractMultiResolutionImage extends java.awt.Image implements MultiResolutionImage { + /** + * This method simply delegates to the same method on the base image and + * it is equivalent to: {@code getBaseImage().getWidth(observer)}. + * + * @return the width of the base image, or -1 if the width is not yet known + * @see #getBaseImage() + * + * @since 9 + */ @Override public int getWidth(ImageObserver observer) { return getBaseImage().getWidth(observer); } + /** + * This method simply delegates to the same method on the base image and + * it is equivalent to: {@code getBaseImage().getHeight(observer)}. + * + * @return the height of the base image, or -1 if the height is not yet known + * @see #getBaseImage() + * + * @since 9 + */ @Override public int getHeight(ImageObserver observer) { return getBaseImage().getHeight(observer); } + /** + * This method simply delegates to the same method on the base image and + * it is equivalent to: {@code getBaseImage().getSource()}. + * + * @return the image producer that produces the pixels for the base image + * @see #getBaseImage() + * + * @since 9 + */ @Override public ImageProducer getSource() { return getBaseImage().getSource(); } + /** + * As per the contract of the base {@code Image#getGraphics()} method, + * this implementation will always throw {@code UnsupportedOperationException} + * since only off-screen images can return a {@code Graphics} object. + * + * @return throws {@code UnsupportedOperationException} + * @throws UnsupportedOperationException this method is not supported + */ @Override public Graphics getGraphics() { throw new UnsupportedOperationException("getGraphics() not supported" + " on Multi-Resolution Images"); } + /** + * This method simply delegates to the same method on the base image and + * it is equivalent to: {@code getBaseImage().getProperty(name, observer)}. + * + * @return the value of the named property in the base image + * @see #getBaseImage() + * + * @since 9 + */ @Override public Object getProperty(String name, ImageObserver observer) { return getBaseImage().getProperty(name, observer); From 7c98a302526442f6cd0ac5dc7ca6f7c0b679681f Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Thu, 24 Nov 2016 15:27:33 +0100 Subject: [PATCH 072/235] 8170284: Move fine granular hotspot make targets to top level Reviewed-by: tbell --- common/autoconf/bootcycle-spec.gmk.in | 3 - common/autoconf/buildjdk-spec.gmk.in | 2 +- common/autoconf/flags.m4 | 25 ++++--- common/autoconf/generated-configure.sh | 99 ++++++++++++-------------- common/autoconf/hotspot.m4 | 15 ++++ common/autoconf/source-dirs.m4 | 22 +----- common/autoconf/spec.gmk.in | 3 +- make/Help.gmk | 6 ++ make/Main.gmk | 64 ++++++++++++++--- 9 files changed, 139 insertions(+), 100 deletions(-) diff --git a/common/autoconf/bootcycle-spec.gmk.in b/common/autoconf/bootcycle-spec.gmk.in index e26450ae3fc..adde830e382 100644 --- a/common/autoconf/bootcycle-spec.gmk.in +++ b/common/autoconf/bootcycle-spec.gmk.in @@ -50,9 +50,6 @@ BOOT_JDK := $(JDK_IMAGE_DIR) # The bootcycle build has a different output directory OLD_BUILD_OUTPUT:=@BUILD_OUTPUT@ BUILD_OUTPUT:=$(OLD_BUILD_OUTPUT)/bootcycle-build -# The HOTSPOT_DIST dir is not defined relative to BUILD_OUTPUT in spec.gmk. Must not -# use space in this patsubst to avoid leading space in HOTSPOT_DIST. -HOTSPOT_DIST:=$(patsubst $(OLD_BUILD_OUTPUT)%,$(BUILD_OUTPUT)%,$(HOTSPOT_DIST)) SJAVAC_SERVER_DIR:=$(patsubst $(OLD_BUILD_OUTPUT)%, $(BUILD_OUTPUT)%, $(SJAVAC_SERVER_DIR)) JAVA_CMD:=$(BOOT_JDK)/bin/java diff --git a/common/autoconf/buildjdk-spec.gmk.in b/common/autoconf/buildjdk-spec.gmk.in index dba07605a22..f38635f3822 100644 --- a/common/autoconf/buildjdk-spec.gmk.in +++ b/common/autoconf/buildjdk-spec.gmk.in @@ -44,7 +44,6 @@ SYSROOT_LDFLAGS := @BUILD_SYSROOT_LDFLAGS@ # These directories should not be moved to BUILDJDK_OUTPUTDIR HOTSPOT_OUTPUTDIR := $(patsubst $(BUILD_OUTPUT)%,$(BUILDJDK_OUTPUTDIR)%,$(HOTSPOT_OUTPUTDIR)) -HOTSPOT_DIST := $(patsubst $(BUILD_OUTPUT)%,$(BUILDJDK_OUTPUTDIR)%,$(HOTSPOT_DIST)) SUPPORT_OUTPUTDIR := $(patsubst $(BUILD_OUTPUT)%,$(BUILDJDK_OUTPUTDIR)%,$(SUPPORT_OUTPUTDIR)) JDK_OUTPUTDIR := $(patsubst $(BUILD_OUTPUT)%,$(BUILDJDK_OUTPUTDIR)%,$(JDK_OUTPUTDIR)) IMAGES_OUTPUTDIR := $(patsubst $(BUILD_OUTPUT)%,$(BUILDJDK_OUTPUTDIR)%,$(IMAGES_OUTPUTDIR)) @@ -156,3 +155,4 @@ JVM_VARIANT_KERNEL := false JVM_VARIANT_ZERO := false JVM_VARIANT_ZEROSHARK := false JVM_VARIANT_CORE := false +JVM_VARIANT_MAIN := server diff --git a/common/autoconf/flags.m4 b/common/autoconf/flags.m4 index eb912119e70..5fe8696b481 100644 --- a/common/autoconf/flags.m4 +++ b/common/autoconf/flags.m4 @@ -1160,19 +1160,18 @@ AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER], -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)" if test "x$1" = "xTARGET"; then - # On some platforms (mac) the linker warns about non existing -L dirs. - # Add server first if available. Linking aginst client does not always produce the same results. - # Only add client/minimal dir if client/minimal is being built. - # Default to server for other variants. - if HOTSPOT_CHECK_JVM_VARIANT(server); then - $2JAVA_BASE_LDFLAGS="${$2JAVA_BASE_LDFLAGS} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/server" - elif HOTSPOT_CHECK_JVM_VARIANT(client); then - $2JAVA_BASE_LDFLAGS="${$2JAVA_BASE_LDFLAGS} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/client" - elif HOTSPOT_CHECK_JVM_VARIANT(minimal); then - $2JAVA_BASE_LDFLAGS="${$2JAVA_BASE_LDFLAGS} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/minimal" - else - $2JAVA_BASE_LDFLAGS="${$2JAVA_BASE_LDFLAGS} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/server" - fi + # On some platforms (mac) the linker warns about non existing -L dirs. + # For any of the variants server, client or minimal, the dir matches the + # variant name. The "main" variant should be used for linking. For the + # rest, the dir is just server. + if HOTSPOT_CHECK_JVM_VARIANT(server) || HOTSPOT_CHECK_JVM_VARIANT(client) \ + || HOTSPOT_CHECK_JVM_VARIANT(minimal); then + $2JAVA_BASE_LDFLAGS="${$2JAVA_BASE_LDFLAGS} \ + -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/$JVM_VARIANT_MAIN" + else + $2JAVA_BASE_LDFLAGS="${$2JAVA_BASE_LDFLAGS} \ + -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/server" + fi elif test "x$1" = "xBUILD"; then # When building a buildjdk, it's always only the server variant $2JAVA_BASE_LDFLAGS="${$2JAVA_BASE_LDFLAGS} \ diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 131556f50ad..c7a5bb9de6a 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -872,8 +872,6 @@ IMPORT_MODULES_CONF IMPORT_MODULES_LIBS IMPORT_MODULES_CMDS IMPORT_MODULES_CLASSES -BUILD_HOTSPOT -HOTSPOT_DIST BUILD_OUTPUT JDK_TOPDIR NASHORN_TOPDIR @@ -966,6 +964,7 @@ CONF_NAME SPEC SDKROOT XCODEBUILD +JVM_VARIANT_MAIN VALID_JVM_VARIANTS JVM_VARIANTS DEBUG_LEVEL @@ -2098,9 +2097,8 @@ Optional Packages: compatibility and is ignored --with-override-jdk Deprecated. Option is kept for backwards compatibility and is ignored - --with-import-hotspot import hotspot binaries from this jdk image or - hotspot build dist dir instead of building from - source + --with-import_hotspot Deprecated. Option is kept for backwards + compatibility and is ignored --with-import-modules import a set of prebuilt modules either as a zip file or an exploded directory --with-toolchain-type the toolchain type (or family) to use, use '--help' @@ -5093,7 +5091,7 @@ VS_SDK_PLATFORM_NAME_2013= #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1478524503 +DATE_WHEN_GENERATED=1479997584 ############################################################################### # @@ -16755,6 +16753,21 @@ $as_echo "$as_me: Unknown variant(s) specified: $INVALID_VARIANTS" >&6;} as_fn_error $? "You cannot build multiple variants with anything else than $VALID_MULTIPLE_JVM_VARIANTS." "$LINENO" 5 fi + # The "main" variant is the one used by other libs to link against during the + # build. + if test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = "xtrue"; then + MAIN_VARIANT_PRIO_ORDER="server client minimal" + for variant in $MAIN_VARIANT_PRIO_ORDER; do + if [[ " $JVM_VARIANTS " =~ " $variant " ]] ; then + JVM_VARIANT_MAIN="$variant" + break + fi + done + else + JVM_VARIANT_MAIN="$JVM_VARIANTS" + fi + + @@ -30996,33 +31009,17 @@ fi BUILD_OUTPUT="$OUTPUT_ROOT" - - HOTSPOT_DIST="$OUTPUT_ROOT/hotspot/dist" - BUILD_HOTSPOT=true + JDK_OUTPUTDIR="$OUTPUT_ROOT/jdk" -# Check whether --with-import-hotspot was given. +# Check whether --with-import_hotspot was given. if test "${with_import_hotspot+set}" = set; then : - withval=$with_import_hotspot; + withval=$with_import_hotspot; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-import_hotspot is deprecated and will be ignored." >&5 +$as_echo "$as_me: WARNING: Option --with-import_hotspot is deprecated and will be ignored." >&2;} fi - if test "x$with_import_hotspot" != x; then - CURDIR="$PWD" - cd "$with_import_hotspot" - HOTSPOT_DIST="`pwd`" - cd "$CURDIR" - if ! (test -d $HOTSPOT_DIST/lib && test -d $HOTSPOT_DIST/jre/lib); then - as_fn_error $? "You have to import hotspot from a full jdk image or hotspot build dist dir!" "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if hotspot should be imported" >&5 -$as_echo_n "checking if hotspot should be imported... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes from $HOTSPOT_DIST" >&5 -$as_echo "yes from $HOTSPOT_DIST" >&6; } - BUILD_HOTSPOT=false - fi - JDK_OUTPUTDIR="$OUTPUT_ROOT/jdk" @@ -50431,19 +50428,18 @@ $as_echo "$as_me: GCC >= 6 detected; adding ${NO_DELETE_NULL_POINTER_CHECKS_CFLA -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)" if test "xTARGET" = "xTARGET"; then - # On some platforms (mac) the linker warns about non existing -L dirs. - # Add server first if available. Linking aginst client does not always produce the same results. - # Only add client/minimal dir if client/minimal is being built. - # Default to server for other variants. - if [[ " $JVM_VARIANTS " =~ " server " ]] ; then - JAVA_BASE_LDFLAGS="${JAVA_BASE_LDFLAGS} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server" - elif [[ " $JVM_VARIANTS " =~ " client " ]] ; then - JAVA_BASE_LDFLAGS="${JAVA_BASE_LDFLAGS} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/client" - elif [[ " $JVM_VARIANTS " =~ " minimal " ]] ; then - JAVA_BASE_LDFLAGS="${JAVA_BASE_LDFLAGS} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/minimal" - else - JAVA_BASE_LDFLAGS="${JAVA_BASE_LDFLAGS} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server" - fi + # On some platforms (mac) the linker warns about non existing -L dirs. + # For any of the variants server, client or minimal, the dir matches the + # variant name. The "main" variant should be used for linking. For the + # rest, the dir is just server. + if [[ " $JVM_VARIANTS " =~ " server " ]] || [[ " $JVM_VARIANTS " =~ " client " ]] \ + || [[ " $JVM_VARIANTS " =~ " minimal " ]] ; then + JAVA_BASE_LDFLAGS="${JAVA_BASE_LDFLAGS} \ + -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/$JVM_VARIANT_MAIN" + else + JAVA_BASE_LDFLAGS="${JAVA_BASE_LDFLAGS} \ + -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server" + fi elif test "xTARGET" = "xBUILD"; then # When building a buildjdk, it's always only the server variant JAVA_BASE_LDFLAGS="${JAVA_BASE_LDFLAGS} \ @@ -51255,19 +51251,18 @@ $as_echo "$as_me: GCC >= 6 detected; adding ${NO_DELETE_NULL_POINTER_CHECKS_CFLA -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)" if test "xBUILD" = "xTARGET"; then - # On some platforms (mac) the linker warns about non existing -L dirs. - # Add server first if available. Linking aginst client does not always produce the same results. - # Only add client/minimal dir if client/minimal is being built. - # Default to server for other variants. - if [[ " $JVM_VARIANTS " =~ " server " ]] ; then - OPENJDK_BUILD_JAVA_BASE_LDFLAGS="${OPENJDK_BUILD_JAVA_BASE_LDFLAGS} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/server" - elif [[ " $JVM_VARIANTS " =~ " client " ]] ; then - OPENJDK_BUILD_JAVA_BASE_LDFLAGS="${OPENJDK_BUILD_JAVA_BASE_LDFLAGS} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/client" - elif [[ " $JVM_VARIANTS " =~ " minimal " ]] ; then - OPENJDK_BUILD_JAVA_BASE_LDFLAGS="${OPENJDK_BUILD_JAVA_BASE_LDFLAGS} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/minimal" - else - OPENJDK_BUILD_JAVA_BASE_LDFLAGS="${OPENJDK_BUILD_JAVA_BASE_LDFLAGS} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/server" - fi + # On some platforms (mac) the linker warns about non existing -L dirs. + # For any of the variants server, client or minimal, the dir matches the + # variant name. The "main" variant should be used for linking. For the + # rest, the dir is just server. + if [[ " $JVM_VARIANTS " =~ " server " ]] || [[ " $JVM_VARIANTS " =~ " client " ]] \ + || [[ " $JVM_VARIANTS " =~ " minimal " ]] ; then + OPENJDK_BUILD_JAVA_BASE_LDFLAGS="${OPENJDK_BUILD_JAVA_BASE_LDFLAGS} \ + -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/$JVM_VARIANT_MAIN" + else + OPENJDK_BUILD_JAVA_BASE_LDFLAGS="${OPENJDK_BUILD_JAVA_BASE_LDFLAGS} \ + -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/server" + fi elif test "xBUILD" = "xBUILD"; then # When building a buildjdk, it's always only the server variant OPENJDK_BUILD_JAVA_BASE_LDFLAGS="${OPENJDK_BUILD_JAVA_BASE_LDFLAGS} \ diff --git a/common/autoconf/hotspot.m4 b/common/autoconf/hotspot.m4 index cda292e3f87..e44a47ad084 100644 --- a/common/autoconf/hotspot.m4 +++ b/common/autoconf/hotspot.m4 @@ -111,8 +111,23 @@ AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_VARIANTS], AC_MSG_ERROR([You cannot build multiple variants with anything else than $VALID_MULTIPLE_JVM_VARIANTS.]) fi + # The "main" variant is the one used by other libs to link against during the + # build. + if test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = "xtrue"; then + MAIN_VARIANT_PRIO_ORDER="server client minimal" + for variant in $MAIN_VARIANT_PRIO_ORDER; do + if HOTSPOT_CHECK_JVM_VARIANT($variant); then + JVM_VARIANT_MAIN="$variant" + break + fi + done + else + JVM_VARIANT_MAIN="$JVM_VARIANTS" + fi + AC_SUBST(JVM_VARIANTS) AC_SUBST(VALID_JVM_VARIANTS) + AC_SUBST(JVM_VARIANT_MAIN) if HOTSPOT_CHECK_JVM_VARIANT(zero) || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then # zero behaves as a platform and rewrites these values. This is really weird. :( diff --git a/common/autoconf/source-dirs.m4 b/common/autoconf/source-dirs.m4 index 940707e81a0..fae398fb404 100644 --- a/common/autoconf/source-dirs.m4 +++ b/common/autoconf/source-dirs.m4 @@ -62,27 +62,9 @@ AC_DEFUN_ONCE([SRCDIRS_SETUP_OUTPUT_DIRS], [ BUILD_OUTPUT="$OUTPUT_ROOT" AC_SUBST(BUILD_OUTPUT) - - HOTSPOT_DIST="$OUTPUT_ROOT/hotspot/dist" - BUILD_HOTSPOT=true - AC_SUBST(HOTSPOT_DIST) - AC_SUBST(BUILD_HOTSPOT) - AC_ARG_WITH(import-hotspot, [AS_HELP_STRING([--with-import-hotspot], - [import hotspot binaries from this jdk image or hotspot build dist dir instead of building from source])]) - if test "x$with_import_hotspot" != x; then - CURDIR="$PWD" - cd "$with_import_hotspot" - HOTSPOT_DIST="`pwd`" - cd "$CURDIR" - if ! (test -d $HOTSPOT_DIST/lib && test -d $HOTSPOT_DIST/jre/lib); then - AC_MSG_ERROR([You have to import hotspot from a full jdk image or hotspot build dist dir!]) - fi - AC_MSG_CHECKING([if hotspot should be imported]) - AC_MSG_RESULT([yes from $HOTSPOT_DIST]) - BUILD_HOTSPOT=false - fi - JDK_OUTPUTDIR="$OUTPUT_ROOT/jdk" + + BASIC_DEPRECATED_ARG_WITH(import_hotspot) ]) ################################################################################ diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in index e2d7be936f6..c7ae75b9070 100644 --- a/common/autoconf/spec.gmk.in +++ b/common/autoconf/spec.gmk.in @@ -220,6 +220,7 @@ JDK_VARIANT:=@JDK_VARIANT@ # Which JVM variants to build (space-separated list) JVM_VARIANTS := @JVM_VARIANTS@ +JVM_VARIANT_MAIN := @JVM_VARIANT_MAIN@ # Lists of features per variant. Only relevant for the variants listed in # JVM_VARIANTS. @@ -273,8 +274,6 @@ JAVADOC_OUTPUTDIR = $(DOCS_IMAGE_DIR) CONFIGURESUPPORT_OUTPUTDIR:=@CONFIGURESUPPORT_OUTPUTDIR@ BUILDJDK_OUTPUTDIR=$(BUILD_OUTPUT)/buildjdk -HOTSPOT_DIST=@HOTSPOT_DIST@ - BUILD_HOTSPOT=@BUILD_HOTSPOT@ BUILD_FAILURE_HANDLER := @BUILD_FAILURE_HANDLER@ diff --git a/make/Help.gmk b/make/Help.gmk index 45a5820c52e..bd10fa2ccb7 100644 --- a/make/Help.gmk +++ b/make/Help.gmk @@ -66,6 +66,12 @@ help: $(info $(_) make clean-- # Remove all build results related to a certain) $(info $(_) # module and phase) $(info ) + $(info Targets for Hotspot) + $(info $(_) make hotspot # Build all of hotspot) + $(info $(_) make hotspot- # Build just the specified jvm variant) + $(info $(_) make hotspot-gensrc # Only build the gensrc part of hotspot) + $(info $(_) make hotspot-- # Build the specified phase for the specified module) + $(info ) $(info Targets for specific modules) $(info $(_) make # Build and everything it depends on) $(info $(_) make - # Compile the specified phase for the specified module) diff --git a/make/Main.gmk b/make/Main.gmk index 60c705d011d..b070dd743f1 100644 --- a/make/Main.gmk +++ b/make/Main.gmk @@ -236,15 +236,35 @@ ALL_TARGETS += $(LAUNCHER_TARGETS) ################################################################################ # Build hotspot target -ifeq ($(BUILD_HOTSPOT),true) - hotspot: - +($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f BuildHotspot.gmk) -endif +HOTSPOT_VARIANT_TARGETS := $(addprefix hotspot-, $(JVM_VARIANTS)) +HOTSPOT_VARIANT_GENSRC_TARGETS := $(addsuffix -gensrc, $(HOTSPOT_VARIANT_TARGETS)) +HOTSPOT_VARIANT_LIBS_TARGETS := $(addsuffix -libs, $(HOTSPOT_VARIANT_TARGETS)) + +define DeclareHotspotGensrcRecipe + hotspot-$1-gensrc: + $$(call LogInfo, Building JVM variant '$1' with features '$(JVM_FEATURES_$1)') + +($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) -f gensrc/GenerateSources.gmk \ + JVM_VARIANT=$1) +endef + +$(foreach v, $(JVM_VARIANTS), $(eval $(call DeclareHotspotGensrcRecipe,$v))) + +define DeclareHotspotLibsRecipe + hotspot-$1-libs: + +($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) -f lib/CompileLibraries.gmk \ + JVM_VARIANT=$1) +endef + +$(foreach v, $(JVM_VARIANTS), $(eval $(call DeclareHotspotLibsRecipe,$v))) + +hotspot-jsig: + +($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) -f lib/CompileLibjsig.gmk) hotspot-ide-project: +($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f ide/CreateVSProject.gmk) -ALL_TARGETS += hotspot hotspot-ide-project +ALL_TARGETS += $(HOTSPOT_VARIANT_TARGETS) $(HOTSPOT_VARIANT_GENSRC_TARGETS) \ + $(HOTSPOT_VARIANT_LIBS_TARGETS) hotspot-jsig hotspot-ide-project ################################################################################ # Build demos and samples targets @@ -547,11 +567,18 @@ else $(JAVA_TARGETS): interim-langtools + # Declare dependencies between hotspot-* targets + $(foreach v, $(JVM_VARIANTS), \ + $(eval hotspot-$v: hotspot-$v-gensrc hotspot-$v-libs) \ + $(eval hotspot-$v-libs: hotspot-$v-gensrc) \ + ) + hotspot-ide-project: hotspot exploded-image generate-exported-symbols: java.base-libs jdk.jdwp.agent-libs - $(LIBS_TARGETS): hotspot + # Building one JVM variant is enough to start building the other libs + $(LIBS_TARGETS): hotspot-$(JVM_VARIANT_MAIN)-libs $(LAUNCHER_TARGETS): java.base-libs @@ -617,6 +644,9 @@ else $(addsuffix -jmod, $(call FindAllUpgradeableModules)), $(JMOD_TARGETS)) endif + # Building java.base-jmod requires all of hotspot to be built. + java.base-jmod: hotspot + # Declare dependencies from -jmod to all other module targets # When creating a BUILDJDK, the java compilation has already been done by the # normal build and copied in. @@ -702,7 +732,7 @@ else docs-javadoc: $(GENSRC_TARGETS) rmic # The gensrc step for jdk.jdi creates an html file that is used by docs-copy. - docs-copy: hotspot jdk.jdi-gensrc + docs-copy: hotspot-$(JVM_VARIANT_MAIN)-gensrc jdk.jdi-gensrc docs-zip: docs-javadoc docs-copy @@ -725,7 +755,8 @@ else test-image-failure-handler: build-test-failure-handler - build-test-hotspot-jtreg-native: buildtools-jdk hotspot + build-test-hotspot-jtreg-native: buildtools-jdk \ + hotspot-$(JVM_VARIANT_MAIN)-libs build-test-jdk-jtreg-native: buildtools-jdk @@ -759,6 +790,16 @@ endif buildtools: buildtools-langtools interim-langtools interim-rmic \ buildtools-jdk +hotspot: $(HOTSPOT_VARIANT_TARGETS) hotspot-jsig + +hotspot-libs: hotspot-jsig + +# Create targets hotspot-libs and hotspot-gensrc. +$(foreach v, $(JVM_VARIANTS), \ + $(eval hotspot-libs: hotspot-$v-libs) \ + $(eval hotspot-gensrc: hotspot-$v-gensrc) \ +) + gensrc: $(GENSRC_TARGETS) gendata: $(GENDATA_TARGETS) @@ -788,6 +829,10 @@ $(foreach m, $(RMIC_MODULES), $(eval $m: $m-rmic)) $(foreach m, $(LIBS_MODULES), $(eval $m: $m-libs)) $(foreach m, $(LAUNCHER_MODULES), $(eval $m: $m-launchers)) $(foreach m, $(ALL_COPY_MODULES), $(eval $m: $m-copy)) + +# Building java.base includes building all of hotspot. +java.base: hotspot + demos: demos-jdk samples: samples-jdk @@ -843,7 +888,8 @@ all-images: product-images test-image docs-image # all-bundles packages all our deliverables as tar.gz bundles. all-bundles: product-bundles test-bundles docs-bundles -ALL_TARGETS += buildtools gensrc gendata copy java rmic libs launchers jmods \ +ALL_TARGETS += buildtools hotspot hotspot-libs hotspot-gensrc gensrc gendata \ + copy java rmic libs launchers jmods \ jdk.jdwp.agent-gensrc $(ALL_MODULES) demos samples \ exploded-image-base exploded-image \ create-buildjdk mac-bundles product-images docs-image test-image all-images \ From 1d62b594447307e123f1bdbffce4e8e5c174067c Mon Sep 17 00:00:00 2001 From: Igor Ignatyev Date: Wed, 23 Nov 2016 12:25:21 +0300 Subject: [PATCH 073/235] 8170228: register closed @requires property setter Reviewed-by: vlivanov, dfazunen --- test/jtreg-ext/requires/VMProps.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/jtreg-ext/requires/VMProps.java b/test/jtreg-ext/requires/VMProps.java index 5c088b6008a..ab44e466ad4 100644 --- a/test/jtreg-ext/requires/VMProps.java +++ b/test/jtreg-ext/requires/VMProps.java @@ -25,6 +25,7 @@ package requires; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -62,7 +63,7 @@ public class VMProps implements Callable> { map.put("vm.debug", vmDebug()); vmGC(map); // vm.gc.X = true/false - dump(map); + VMProps.dump(map); return map; } @@ -180,7 +181,7 @@ public class VMProps implements Callable> { * * @param map */ - protected void dump(Map map) { + protected static void dump(Map map) { String dumpFileName = System.getProperty("vmprops.dump"); if (dumpFileName == null) { return; @@ -188,7 +189,7 @@ public class VMProps implements Callable> { List lines = new ArrayList<>(); map.forEach((k, v) -> lines.add(k + ":" + v)); try { - Files.write(Paths.get(dumpFileName), lines); + Files.write(Paths.get(dumpFileName), lines, StandardOpenOption.APPEND); } catch (IOException e) { throw new RuntimeException("Failed to dump properties into '" + dumpFileName + "'", e); From 4aaf8f63ba2990fa66c4d277e6227526bdee57c0 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Wed, 23 Nov 2016 14:36:32 +0100 Subject: [PATCH 074/235] 8170358: [REDO] 8k class metaspace chunks misallocated from 4k chunk freelist Reviewed-by: mgerdin, coleenp, ehelin, stuefe --- hotspot/src/share/vm/memory/metaspace.cpp | 73 ++++++++++++++----- .../test/native/memory/test_chunkManager.cpp | 39 ++++++++++ 2 files changed, 94 insertions(+), 18 deletions(-) create mode 100644 hotspot/test/native/memory/test_chunkManager.cpp diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 3cfbf6dcb75..5754138b3f8 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -153,7 +153,7 @@ class ChunkManager : public CHeapObj { // Map a size to a list index assuming that there are lists // for special, small, medium, and humongous chunks. - static ChunkIndex list_index(size_t size); + ChunkIndex list_index(size_t size); // Remove the chunk from its freelist. It is // expected to be on one of the _free_chunks[] lists. @@ -1794,7 +1794,11 @@ void ChunkManager::locked_print_sum_free_chunks(outputStream* st) { st->print_cr("Sum free chunk total " SIZE_FORMAT " count " SIZE_FORMAT, sum_free_chunks(), sum_free_chunks_count()); } + ChunkList* ChunkManager::free_chunks(ChunkIndex index) { + assert(index == SpecializedIndex || index == SmallIndex || index == MediumIndex, + "Bad index: %d", (int)index); + return &_free_chunks[index]; } @@ -1898,7 +1902,7 @@ Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) { } assert((word_size <= chunk->word_size()) || - list_index(chunk->word_size() == HumongousIndex), + (list_index(chunk->word_size()) == HumongousIndex), "Non-humongous variable sized chunk"); Log(gc, metaspace, freelist) log; if (log.is_debug()) { @@ -2371,22 +2375,18 @@ const char* SpaceManager::chunk_size_name(ChunkIndex index) const { } ChunkIndex ChunkManager::list_index(size_t size) { - switch (size) { - case SpecializedChunk: - assert(SpecializedChunk == ClassSpecializedChunk, - "Need branch for ClassSpecializedChunk"); - return SpecializedIndex; - case SmallChunk: - case ClassSmallChunk: - return SmallIndex; - case MediumChunk: - case ClassMediumChunk: - return MediumIndex; - default: - assert(size > MediumChunk || size > ClassMediumChunk, - "Not a humongous chunk"); - return HumongousIndex; + if (free_chunks(SpecializedIndex)->size() == size) { + return SpecializedIndex; } + if (free_chunks(SmallIndex)->size() == size) { + return SmallIndex; + } + if (free_chunks(MediumIndex)->size() == size) { + return MediumIndex; + } + + assert(size > free_chunks(MediumIndex)->size(), "Not a humongous chunk"); + return HumongousIndex; } void SpaceManager::deallocate(MetaWord* p, size_t word_size) { @@ -2410,7 +2410,7 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) { // Find the correct list and and set the current // chunk for that list. - ChunkIndex index = ChunkManager::list_index(new_chunk->word_size()); + ChunkIndex index = chunk_manager()->list_index(new_chunk->word_size()); if (index != HumongousIndex) { retire_current_chunk(); @@ -4032,6 +4032,43 @@ void TestVirtualSpaceNode_test() { TestVirtualSpaceNodeTest::test_is_available(); } +// The following test is placed here instead of a gtest / unittest file +// because the ChunkManager class is only available in this file. +void ChunkManager_test_list_index() { + ChunkManager manager(ClassSpecializedChunk, ClassSmallChunk, ClassMediumChunk); + + // Test previous bug where a query for a humongous class metachunk, + // incorrectly matched the non-class medium metachunk size. + { + assert(MediumChunk > ClassMediumChunk, "Precondition for test"); + + ChunkIndex index = manager.list_index(MediumChunk); + + assert(index == HumongousIndex, + "Requested size is larger than ClassMediumChunk," + " so should return HumongousIndex. Got index: %d", (int)index); + } + + // Check the specified sizes as well. + { + ChunkIndex index = manager.list_index(ClassSpecializedChunk); + assert(index == SpecializedIndex, "Wrong index returned. Got index: %d", (int)index); + } + { + ChunkIndex index = manager.list_index(ClassSmallChunk); + assert(index == SmallIndex, "Wrong index returned. Got index: %d", (int)index); + } + { + ChunkIndex index = manager.list_index(ClassMediumChunk); + assert(index == MediumIndex, "Wrong index returned. Got index: %d", (int)index); + } + { + ChunkIndex index = manager.list_index(ClassMediumChunk + 1); + assert(index == HumongousIndex, "Wrong index returned. Got index: %d", (int)index); + } +} + + // The following test is placed here instead of a gtest / unittest file // because the ChunkManager class is only available in this file. class SpaceManagerTest : AllStatic { diff --git a/hotspot/test/native/memory/test_chunkManager.cpp b/hotspot/test/native/memory/test_chunkManager.cpp new file mode 100644 index 00000000000..6aa5b5e392b --- /dev/null +++ b/hotspot/test/native/memory/test_chunkManager.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, 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" + +// The test function is only available in debug builds +#ifdef ASSERT + +#include "unittest.hpp" + +void ChunkManager_test_list_index(); + +TEST(ChunkManager, list_index) { + // The ChunkManager is only available in metaspace.cpp, + // so the test code is located in that file. + ChunkManager_test_list_index(); +} + +#endif // ASSERT From 9d87230fccfa54c409643c67c3cd2fbb2cfb15d0 Mon Sep 17 00:00:00 2001 From: Anton Tarasov Date: Wed, 23 Nov 2016 18:48:02 +0300 Subject: [PATCH 075/235] 8140525: AwtFrame::WmShowWindow() may steal focus Reviewed-by: serb, ssadetsky --- .../java.desktop/windows/native/libawt/windows/awt_Frame.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp index 6c8d65a47c7..9bc6366d17b 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp @@ -484,7 +484,10 @@ MsgRouting AwtFrame::WmShowWindow(BOOL show, UINT status) if (fgProcessID != ::GetCurrentProcessId()) { AwtWindow* window = (AwtWindow*)GetComponent(GetHWnd()); - if (window != NULL && window->IsFocusableWindow() && window->IsAutoRequestFocus() && + if (window != NULL && + window->IsFocusableWindow() && + window->IsAutoRequestFocus() && + !::IsWindowVisible(GetHWnd()) && // the window is really showing !::IsWindow(GetModalBlocker(GetHWnd()))) { // When the Java process is not allowed to set the foreground window From f04a27dbdcc70479f9945f64939b108ebe03e00f Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Thu, 24 Nov 2016 11:58:52 +0530 Subject: [PATCH 076/235] 8048702: Deprecate obsolete classes in javax/swing/plaf/metal/MetalFileChooserUI.java Reviewed-by: serb, alexsch --- .../classes/javax/swing/plaf/metal/MetalFileChooserUI.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java b/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java index 91132582193..32db72db408 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java @@ -571,7 +571,9 @@ public class MetalFileChooserUI extends BasicFileChooserUI { /** * Obsolete class, not used in this version. + * @deprecated As of JDK version 9. Obsolete class. */ + @Deprecated(since = "9") protected class SingleClickListener extends MouseAdapter { /** * Constructs an instance of {@code SingleClickListener}. @@ -584,7 +586,9 @@ public class MetalFileChooserUI extends BasicFileChooserUI { /** * Obsolete class, not used in this version. + * @deprecated As of JDK version 9. Obsolete class. */ + @Deprecated(since = "9") @SuppressWarnings("serial") // Superclass is not serializable across versions protected class FileRenderer extends DefaultListCellRenderer { } From fdedfbc0f35d2b275db6c181a92eb451565f0334 Mon Sep 17 00:00:00 2001 From: Harsha Wardhana B Date: Thu, 24 Nov 2016 12:04:44 +0530 Subject: [PATCH 077/235] 8141591: javax/management/remote/mandatory/threads/ExecutorTest.java fails intermittently Reviewed-by: dfuchs --- .../remote/internal/ClientNotifForwarder.java | 36 ++++- .../threads/ExecutorShutdownTest.java | 148 ++++++++++++++++++ 2 files changed, 181 insertions(+), 3 deletions(-) create mode 100644 jdk/test/javax/management/remote/mandatory/threads/ExecutorShutdownTest.java diff --git a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java b/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java index e0860f8e1f0..f2014eee794 100644 --- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java +++ b/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, 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 @@ -51,7 +51,9 @@ import javax.management.remote.TargetedNotification; import com.sun.jmx.remote.util.ClassLogger; import com.sun.jmx.remote.util.EnvHelp; +import java.lang.reflect.UndeclaredThrowableException; import java.rmi.UnmarshalException; +import java.util.concurrent.RejectedExecutionException; public abstract class ClientNotifForwarder { @@ -559,10 +561,38 @@ public abstract class ClientNotifForwarder { } } } else { - executor.execute(this); + try { + executor.execute(this); + } catch (Exception e) { + if (isRejectedExecutionException(e)) { + // We reached here because the executor was shutdown. + // If executor was supplied by client, then it was shutdown + // abruptly or JMXConnector was shutdown along with executor + // while this thread was suspended at L564. + if (!(executor instanceof LinearExecutor)) { + // Spawn new executor that will do cleanup if JMXConnector is closed + // or keep notif system running otherwise + executor = new LinearExecutor(); + executor.execute(this); + } + } else { + throw e; + } + } } } + private boolean isRejectedExecutionException(Exception e) { + Throwable cause = e; + while (cause != null) { + if (cause instanceof RejectedExecutionException) { + return true; + } + cause = cause.getCause(); + } + return false; + } + void dispatchNotification(TargetedNotification tn, Integer myListenerID, Map listeners) { @@ -866,7 +896,7 @@ public abstract class ClientNotifForwarder { // ------------------------------------------------- private final ClassLoader defaultClassLoader; - private final Executor executor; + private Executor executor; private final Map infoList = new HashMap(); diff --git a/jdk/test/javax/management/remote/mandatory/threads/ExecutorShutdownTest.java b/jdk/test/javax/management/remote/mandatory/threads/ExecutorShutdownTest.java new file mode 100644 index 00000000000..003780cc474 --- /dev/null +++ b/jdk/test/javax/management/remote/mandatory/threads/ExecutorShutdownTest.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2016, 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 8141591 + * @summary Tests if notifications are received after executor is shutdown + * @author Harsha Wardhana B + * @modules java.management + * @run clean ExecutorShutdownTest + * @run build ExecutorShutdownTest + * @run main ExecutorShutdownTest + */ +import java.util.*; +import java.util.concurrent.*; +import javax.management.*; +import javax.management.remote.*; + +/* + When you create a JMXConnector client, you can supply a + "fetch-notifications Executor", which is a + java.util.concurrent.Executor that will be used each time the + connector client wants to call RMIConnection.fetchNotifications. + If such executor is not supplies, the connector client will fallback + on default LinearExecutor. This test checks if user supplied executor + is shutdown abruptly, LinearExecutor is used to handle notifications. + */ +public class ExecutorShutdownTest { + + private static final String EXECUTOR_PROPERTY + = "jmx.remote.x.fetch.notifications.executor"; + private static final String NOTIF_TYPE = "test.type"; + + public static void main(String[] args) throws Exception { + + // Start JMXConnector Server + JMXServiceURL url = new JMXServiceURL("rmi", null, 0); + MBeanServer mbs = MBeanServerFactory.newMBeanServer(); + ObjectName emitName = new ObjectName("blah:type=Emitter"); + mbs.registerMBean(new Emitter(), emitName); + JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, + null, + mbs); + cs.start(); + + // Create executor to provide to JMXConnector client + ExecutorService executor = Executors.newCachedThreadPool(); + Map env = new HashMap<>(); + env.put(EXECUTOR_PROPERTY, executor); + JMXServiceURL addr = cs.getAddress(); + + try (JMXConnector cc = JMXConnectorFactory.connect(addr, env)) { + MBeanServerConnection mbsc = cc.getMBeanServerConnection(); + EmitterMBean emitter = (EmitterMBean) MBeanServerInvocationHandler.newProxyInstance(mbsc, + emitName, + EmitterMBean.class, + false); + SemaphoreListener listener = new SemaphoreListener(); + NotificationFilterSupport filter = new NotificationFilterSupport(); + filter.enableType(NOTIF_TYPE); + mbsc.addNotificationListener(emitName, listener, filter, null); + + final int NOTIF_COUNT = 3; + for (int i = 0; i < NOTIF_COUNT; i++) { + emitter.emit(); + listener.await(); + } + Thread.sleep(1); + listener.checkUnavailable(); + System.out.println("Got notifications with client provided executor"); + + // After shutting down executor, notifications are handled by linear executor + executor.shutdown(); + for (int i = 0; i < NOTIF_COUNT; i++) { + emitter.emit(); + listener.await(); + } + Thread.sleep(1); + listener.checkUnavailable(); + System.out.println("Got notifications with linear executor"); + } + cs.stop(); + System.out.println("TEST PASSED !!!"); + } + + /* Simple MBean that sends a notification every time we ask it to. */ + public static interface EmitterMBean { + + public void emit(); + } + + public static class Emitter + extends NotificationBroadcasterSupport implements EmitterMBean { + + public void emit() { + sendNotification(new Notification(NOTIF_TYPE, this, seq++)); + } + + private long seq = 1; + } + + /* Simple NotificationListener that allows you to wait until a + notification has been received. Since it uses a semaphore, you + can wait either before or after the notification has in fact + been received and it will work in either case. */ + private static class SemaphoreListener implements NotificationListener { + + void await() throws InterruptedException { + semaphore.acquire(); + } + + /* Ensure no extra notifications were received. If we can acquire + the semaphore, that means its release() method was called more + times than its acquire() method, which means there were too + many notifications. */ + void checkUnavailable() throws Exception { + if (semaphore.tryAcquire()) { + throw new Exception("Got extra notifications!"); + } + } + + public void handleNotification(Notification n, Object h) { + semaphore.release(); + } + + private final Semaphore semaphore = new Semaphore(0); + } +} From b61b0b8c006df152f014dfcd9d9800638ec371ae Mon Sep 17 00:00:00 2001 From: Avik Niyogi Date: Thu, 24 Nov 2016 14:11:32 +0530 Subject: [PATCH 078/235] 8167160: [TEST_BUG][PIT] failure of javax/swing/JRadioButton/8033699/bug8033699.java Reviewed-by: psadhukhan, serb --- .../JRadioButton/8033699/bug8033699.java | 76 ++++++++++++++----- 1 file changed, 57 insertions(+), 19 deletions(-) diff --git a/jdk/test/javax/swing/JRadioButton/8033699/bug8033699.java b/jdk/test/javax/swing/JRadioButton/8033699/bug8033699.java index 4b95dc92bb3..a9ad28e7504 100644 --- a/jdk/test/javax/swing/JRadioButton/8033699/bug8033699.java +++ b/jdk/test/javax/swing/JRadioButton/8033699/bug8033699.java @@ -26,22 +26,31 @@ * @key headful * @library ../../regtesthelpers * @build Util - * @bug 8033699 8154043 + * @bug 8033699 8154043 8167160 * @summary Incorrect radio button behavior when pressing tab key - * @author Vivi An * @run main bug8033699 */ - -import javax.swing.*; -import javax.swing.event.*; -import java.awt.event.*; -import java.awt.*; +import java.awt.KeyboardFocusManager; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; public class bug8033699 { - private static Robot robot; + private static JFrame mainFrame; + private static Robot robot; private static JButton btnStart; - private static ButtonGroup btnGrp; private static JButton btnEnd; private static JButton btnMiddle; private static JRadioButton radioBtn1; @@ -51,7 +60,9 @@ public class bug8033699 { public static void main(String args[]) throws Throwable { SwingUtilities.invokeAndWait(new Runnable() { + @Override public void run() { + changeLAF(); createAndShowGUI(); } }); @@ -84,11 +95,30 @@ public class bug8033699 { // down key circle back to first button in grouped radio button runTest8(); + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + mainFrame.dispose(); + } + }); + } + + private static void changeLAF() { + String currentLAF = UIManager.getLookAndFeel().toString(); + System.out.println(currentLAF); + currentLAF = currentLAF.toLowerCase(); + if (currentLAF.contains("aqua") || currentLAF.contains("nimbus")) { + try { + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + } catch (Exception ex) { + ex.printStackTrace(); + } + } } private static void createAndShowGUI() { - JFrame mainFrame = new JFrame("Bug 8033699 - 8 Tests for Grouped/Non Group Radio Buttons"); - + mainFrame = new JFrame("Bug 8033699 - 8 Tests for Grouped/Non Group Radio Buttons"); btnStart = new JButton("Start"); btnEnd = new JButton("End"); btnMiddle = new JButton("Middle"); @@ -132,12 +162,13 @@ public class bug8033699 { } // Radio button Group as a single component when traversing through tab key - private static void runTest1() throws Exception{ + private static void runTest1() throws Exception { hitKey(robot, KeyEvent.VK_TAB); hitKey(robot, KeyEvent.VK_TAB); hitKey(robot, KeyEvent.VK_TAB); SwingUtilities.invokeAndWait(new Runnable() { + @Override public void run() { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtnSingle) { System.out.println("Radio Button Group Go To Next Component through Tab Key failed"); @@ -148,9 +179,10 @@ public class bug8033699 { } // Non-Grouped Radio button as a single component when traversing through tab key - private static void runTest2() throws Exception{ + private static void runTest2() throws Exception { hitKey(robot, KeyEvent.VK_TAB); SwingUtilities.invokeAndWait(new Runnable() { + @Override public void run() { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != btnEnd) { System.out.println("Non Grouped Radio Button Go To Next Component through Tab Key failed"); @@ -161,11 +193,12 @@ public class bug8033699 { } // Non-Grouped Radio button and Group Radio button as a single component when traversing through shift-tab key - private static void runTest3() throws Exception{ + private static void runTest3() throws Exception { hitKey(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); hitKey(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); hitKey(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); SwingUtilities.invokeAndWait(new Runnable() { + @Override public void run() { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn1) { System.out.println("Radio button Group/Non Grouped Radio Button SHIFT-Tab Key Test failed"); @@ -176,10 +209,11 @@ public class bug8033699 { } // Using arrow key to move focus in radio button group - private static void runTest4() throws Exception{ + private static void runTest4() throws Exception { hitKey(robot, KeyEvent.VK_DOWN); hitKey(robot, KeyEvent.VK_RIGHT); SwingUtilities.invokeAndWait(new Runnable() { + @Override public void run() { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn3) { System.out.println("Radio button Group UP/LEFT Arrow Key Move Focus Failed"); @@ -189,10 +223,11 @@ public class bug8033699 { }); } - private static void runTest5() throws Exception{ + private static void runTest5() throws Exception { hitKey(robot, KeyEvent.VK_UP); hitKey(robot, KeyEvent.VK_LEFT); SwingUtilities.invokeAndWait(new Runnable() { + @Override public void run() { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn1) { System.out.println("Radio button Group Left/Up Arrow Key Move Focus Failed"); @@ -202,10 +237,11 @@ public class bug8033699 { }); } - private static void runTest6() throws Exception{ + private static void runTest6() throws Exception { hitKey(robot, KeyEvent.VK_UP); hitKey(robot, KeyEvent.VK_UP); SwingUtilities.invokeAndWait(new Runnable() { + @Override public void run() { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn2) { System.out.println("Radio button Group Circle Back To First Button Test"); @@ -215,9 +251,10 @@ public class bug8033699 { }); } - private static void runTest7() throws Exception{ + private static void runTest7() throws Exception { hitKey(robot, KeyEvent.VK_TAB); SwingUtilities.invokeAndWait(new Runnable() { + @Override public void run() { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != btnMiddle) { System.out.println("Separate Component added in button group layout"); @@ -227,9 +264,10 @@ public class bug8033699 { }); } - private static void runTest8() throws Exception{ + private static void runTest8() throws Exception { hitKey(robot, KeyEvent.VK_TAB); SwingUtilities.invokeAndWait(new Runnable() { + @Override public void run() { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtnSingle) { System.out.println("Separate Component added in button group layout"); From d63b1299f76526ac2b65c0128cda43805326bd14 Mon Sep 17 00:00:00 2001 From: Igor Ignatyev Date: Fri, 25 Nov 2016 11:55:33 +0300 Subject: [PATCH 079/235] 8170226: Implement setting jtreg @requires property vm.jvmci Reviewed-by: kvn --- test/jtreg-ext/requires/VMProps.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/jtreg-ext/requires/VMProps.java b/test/jtreg-ext/requires/VMProps.java index ab44e466ad4..06299e7ecd5 100644 --- a/test/jtreg-ext/requires/VMProps.java +++ b/test/jtreg-ext/requires/VMProps.java @@ -61,6 +61,7 @@ public class VMProps implements Callable> { map.put("vm.flightRecorder", vmFlightRecorder()); map.put("vm.simpleArch", vmArch()); map.put("vm.debug", vmDebug()); + map.put("vm.jvmci", vmJvmci()); vmGC(map); // vm.gc.X = true/false VMProps.dump(map); @@ -156,6 +157,14 @@ public class VMProps implements Callable> { return "" + System.getProperty("jdk.debug").contains("debug"); } + /** + * @return true if VM supports JVMCI and false otherwise + */ + protected String vmJvmci() { + // builds with jvmci have this flag + return "" + (WB.getBooleanVMFlag("EnableJVMCI") != null); + } + /** * For all existing GC sets vm.gc.X property. * Example vm.gc.G1=true means: From 7a6eaf487deda1a2fe5d8d9d45427b3ee481d925 Mon Sep 17 00:00:00 2001 From: Igor Ignatyev Date: Tue, 29 Nov 2016 00:25:09 +0300 Subject: [PATCH 080/235] 8170226: Implement setting jtreg @requires property vm.jvmci Reviewed-by: kvn --- hotspot/test/TEST.ROOT | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/test/TEST.ROOT b/hotspot/test/TEST.ROOT index 393e1382967..9fe5392024b 100644 --- a/hotspot/test/TEST.ROOT +++ b/hotspot/test/TEST.ROOT @@ -45,6 +45,7 @@ requires.properties= \ vm.gc.Serial \ vm.gc.Parallel \ vm.gc.ConcMarkSweep \ + vm.jvmci \ vm.debug # Tests using jtreg 4.2 b03 features From f9087dae6df5c9bc6a04f216c14ae343c0eed424 Mon Sep 17 00:00:00 2001 From: Igor Ignatyev Date: Tue, 29 Nov 2016 00:25:13 +0300 Subject: [PATCH 081/235] 8170227: use vm.jvmci property in compiler/jvmci tests Reviewed-by: kvn --- .../jvmci/JVM_GetJVMCIRuntimeTest.java | 2 +- .../jvmci/SecurityRestrictionsTest.java | 2 +- .../jvmci/TestJVMCIPrintProperties.java | 2 +- .../compilerToVM/AllocateCompileIdTest.java | 2 +- .../AsResolvedJavaMethodTest.java | 3 +-- .../compilerToVM/CanInlineMethodTest.java | 2 +- .../compilerToVM/CollectCountersTest.java | 2 +- .../jvmci/compilerToVM/DebugOutputTest.java | 2 +- .../compilerToVM/DisassembleCodeBlobTest.java | 2 +- .../DoNotInlineOrCompileTest.java | 2 +- .../ExecuteInstalledCodeTest.java | 25 ++++++++++++++++++- .../FindUniqueConcreteMethodTest.java | 2 +- .../jvmci/compilerToVM/GetBytecodeTest.java | 2 +- .../compilerToVM/GetClassInitializerTest.java | 2 +- .../compilerToVM/GetConstantPoolTest.java | 2 +- .../compilerToVM/GetExceptionTableTest.java | 2 +- .../compilerToVM/GetImplementorTest.java | 2 +- .../compilerToVM/GetLineNumberTableTest.java | 2 +- .../GetLocalVariableTableTest.java | 2 +- .../GetMaxCallTargetOffsetTest.java | 2 +- .../compilerToVM/GetNextStackFrameTest.java | 2 +- .../GetResolvedJavaMethodTest.java | 2 +- .../compilerToVM/GetResolvedJavaTypeTest.java | 2 +- .../GetStackTraceElementTest.java | 2 +- .../jvmci/compilerToVM/GetSymbolTest.java | 2 +- .../GetVtableIndexForInterfaceTest.java | 2 +- .../HasCompiledCodeForOSRTest.java | 2 +- .../HasFinalizableSubclassTest.java | 2 +- .../InvalidateInstalledCodeTest.java | 2 +- .../jvmci/compilerToVM/IsMatureTest.java | 2 +- .../JVM_RegisterJVMCINatives.java | 2 +- .../compilerToVM/LookupKlassInPoolTest.java | 2 +- .../LookupKlassRefIndexInPoolTest.java | 2 +- .../compilerToVM/LookupMethodInPoolTest.java | 2 +- .../LookupNameAndTypeRefIndexInPoolTest.java | 2 +- .../compilerToVM/LookupNameInPoolTest.java | 2 +- .../LookupSignatureInPoolTest.java | 2 +- .../jvmci/compilerToVM/LookupTypeTest.java | 2 +- .../MaterializeVirtualObjectTest.java | 2 +- ...ethodIsIgnoredBySecurityStackWalkTest.java | 2 +- .../compilerToVM/ReadConfigurationTest.java | 2 +- .../jvmci/compilerToVM/ReprofileTest.java | 2 +- .../ResolveConstantInPoolTest.java | 2 +- .../compilerToVM/ResolveFieldInPoolTest.java | 2 +- .../jvmci/compilerToVM/ResolveMethodTest.java | 2 +- ...solvePossiblyCachedConstantInPoolTest.java | 2 +- .../compilerToVM/ResolveTypeInPoolTest.java | 2 +- .../ShouldDebugNonSafepointsTest.java | 2 +- .../compilerToVM/ShouldInlineMethodTest.java | 2 +- .../errors/TestInvalidCompilationResult.java | 2 +- .../jvmci/errors/TestInvalidDebugInfo.java | 2 +- .../jvmci/errors/TestInvalidOopMap.java | 2 +- ...JvmciNotifyBootstrapFinishedEventTest.java | 2 +- .../events/JvmciNotifyInstallEventTest.java | 2 +- .../jvmci/events/JvmciShutdownEventTest.java | 2 +- .../jdk/vm/ci/code/test/DataPatchTest.java | 2 +- .../code/test/InterpreterFrameSizeTest.java | 2 +- .../code/test/MaxOopMapStackOffsetTest.java | 2 +- .../jdk/vm/ci/code/test/NativeCallTest.java | 2 +- .../code/test/SimpleCodeInstallationTest.java | 2 +- .../vm/ci/code/test/SimpleDebugInfoTest.java | 2 +- .../code/test/VirtualObjectDebugInfoTest.java | 2 +- ...HotSpotConstantReflectionProviderTest.java | 2 +- .../test/MemoryAccessProviderTest.java | 2 +- .../test/MethodHandleAccessProviderTest.java | 2 +- .../jdk/vm/ci/runtime/test/ConstantTest.java | 2 +- .../vm/ci/runtime/test/RedefineClassTest.java | 2 +- ...lvedJavaTypeResolveConcreteMethodTest.java | 2 +- .../ResolvedJavaTypeResolveMethodTest.java | 2 +- .../test/TestConstantReflectionProvider.java | 2 +- .../jdk/vm/ci/runtime/test/TestJavaField.java | 2 +- .../vm/ci/runtime/test/TestJavaMethod.java | 2 +- .../jdk/vm/ci/runtime/test/TestJavaType.java | 2 +- .../runtime/test/TestMetaAccessProvider.java | 2 +- .../runtime/test/TestResolvedJavaField.java | 2 +- .../runtime/test/TestResolvedJavaMethod.java | 2 +- .../ci/runtime/test/TestResolvedJavaType.java | 2 +- .../compiler/jvmci/meta/StableFieldTest.java | 2 +- 78 files changed, 101 insertions(+), 79 deletions(-) diff --git a/hotspot/test/compiler/jvmci/JVM_GetJVMCIRuntimeTest.java b/hotspot/test/compiler/jvmci/JVM_GetJVMCIRuntimeTest.java index 667cb9ea554..481334f4ca4 100644 --- a/hotspot/test/compiler/jvmci/JVM_GetJVMCIRuntimeTest.java +++ b/hotspot/test/compiler/jvmci/JVM_GetJVMCIRuntimeTest.java @@ -24,7 +24,7 @@ /** * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @modules java.base/jdk.internal.misc * @modules jdk.vm.ci/jdk.vm.ci.runtime diff --git a/hotspot/test/compiler/jvmci/SecurityRestrictionsTest.java b/hotspot/test/compiler/jvmci/SecurityRestrictionsTest.java index 8a91560e5e3..b86cfbf6dd9 100644 --- a/hotspot/test/compiler/jvmci/SecurityRestrictionsTest.java +++ b/hotspot/test/compiler/jvmci/SecurityRestrictionsTest.java @@ -24,7 +24,7 @@ /** * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/TestJVMCIPrintProperties.java b/hotspot/test/compiler/jvmci/TestJVMCIPrintProperties.java index 630780dbb26..4f40c5b8a2d 100644 --- a/hotspot/test/compiler/jvmci/TestJVMCIPrintProperties.java +++ b/hotspot/test/compiler/jvmci/TestJVMCIPrintProperties.java @@ -24,7 +24,7 @@ /* * @test TestBasicLogOutput * @summary Ensure -XX:-JVMCIPrintProperties can be enabled and successfully prints expected output to stdout. - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib */ diff --git a/hotspot/test/compiler/jvmci/compilerToVM/AllocateCompileIdTest.java b/hotspot/test/compiler/jvmci/compilerToVM/AllocateCompileIdTest.java index dbf618d6bd7..adfece82f94 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/AllocateCompileIdTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/AllocateCompileIdTest.java @@ -24,7 +24,7 @@ /** * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/AsResolvedJavaMethodTest.java b/hotspot/test/compiler/jvmci/compilerToVM/AsResolvedJavaMethodTest.java index 1234edb4cd6..09e8f0e2b5b 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/AsResolvedJavaMethodTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/AsResolvedJavaMethodTest.java @@ -19,13 +19,12 @@ * 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 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/CanInlineMethodTest.java b/hotspot/test/compiler/jvmci/compilerToVM/CanInlineMethodTest.java index 020521b99ed..092acf12549 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/CanInlineMethodTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/CanInlineMethodTest.java @@ -24,7 +24,7 @@ /** * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/CollectCountersTest.java b/hotspot/test/compiler/jvmci/compilerToVM/CollectCountersTest.java index b3627b73387..507c56987d7 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/CollectCountersTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/CollectCountersTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib/ * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/DebugOutputTest.java b/hotspot/test/compiler/jvmci/compilerToVM/DebugOutputTest.java index 13caa191f7d..806c2e7e349 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/DebugOutputTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/DebugOutputTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/DisassembleCodeBlobTest.java b/hotspot/test/compiler/jvmci/compilerToVM/DisassembleCodeBlobTest.java index f5929d746a1..9101d2a66e5 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/DisassembleCodeBlobTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/DisassembleCodeBlobTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/DoNotInlineOrCompileTest.java b/hotspot/test/compiler/jvmci/compilerToVM/DoNotInlineOrCompileTest.java index d0213562250..574604ccd24 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/DoNotInlineOrCompileTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/DoNotInlineOrCompileTest.java @@ -24,7 +24,7 @@ /** * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/ExecuteInstalledCodeTest.java b/hotspot/test/compiler/jvmci/compilerToVM/ExecuteInstalledCodeTest.java index 4c509335114..5d7c4d376ba 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/ExecuteInstalledCodeTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/ExecuteInstalledCodeTest.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2015, 2016, 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 compiler.jvmci.compilerToVM; import jdk.test.lib.Asserts; @@ -16,7 +39,7 @@ import java.util.List; /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/FindUniqueConcreteMethodTest.java b/hotspot/test/compiler/jvmci/compilerToVM/FindUniqueConcreteMethodTest.java index 25cbb97b1b9..4f39cf05c6c 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/FindUniqueConcreteMethodTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/FindUniqueConcreteMethodTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/GetBytecodeTest.java b/hotspot/test/compiler/jvmci/compilerToVM/GetBytecodeTest.java index 0c820103073..e959482d0f1 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/GetBytecodeTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetBytecodeTest.java @@ -24,7 +24,7 @@ /** * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/GetClassInitializerTest.java b/hotspot/test/compiler/jvmci/compilerToVM/GetClassInitializerTest.java index 8204043b223..5dcc9f4e7e7 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/GetClassInitializerTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetClassInitializerTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/GetConstantPoolTest.java b/hotspot/test/compiler/jvmci/compilerToVM/GetConstantPoolTest.java index 98937f9eb85..2aa39371567 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/GetConstantPoolTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetConstantPoolTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/GetExceptionTableTest.java b/hotspot/test/compiler/jvmci/compilerToVM/GetExceptionTableTest.java index fdfe329812c..af7c9bb8985 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/GetExceptionTableTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetExceptionTableTest.java @@ -24,7 +24,7 @@ /** * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/GetImplementorTest.java b/hotspot/test/compiler/jvmci/compilerToVM/GetImplementorTest.java index d9dd305aaf7..3811c74abf6 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/GetImplementorTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetImplementorTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib/ * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/GetLineNumberTableTest.java b/hotspot/test/compiler/jvmci/compilerToVM/GetLineNumberTableTest.java index e27e85f96d1..33b20f2f4bb 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/GetLineNumberTableTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetLineNumberTableTest.java @@ -24,7 +24,7 @@ /** * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @library ../common/patches diff --git a/hotspot/test/compiler/jvmci/compilerToVM/GetLocalVariableTableTest.java b/hotspot/test/compiler/jvmci/compilerToVM/GetLocalVariableTableTest.java index 503145a39dd..8202d1260c1 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/GetLocalVariableTableTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetLocalVariableTableTest.java @@ -24,7 +24,7 @@ /** * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/GetMaxCallTargetOffsetTest.java b/hotspot/test/compiler/jvmci/compilerToVM/GetMaxCallTargetOffsetTest.java index 438eab27d05..0923e10c9b7 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/GetMaxCallTargetOffsetTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetMaxCallTargetOffsetTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib/ * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/GetNextStackFrameTest.java b/hotspot/test/compiler/jvmci/compilerToVM/GetNextStackFrameTest.java index 110c2cbe1bb..0b079f3741f 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/GetNextStackFrameTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetNextStackFrameTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java index 24a60d4992e..18af0153352 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java index 38adf2fc720..c8afdcbf3c5 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/GetStackTraceElementTest.java b/hotspot/test/compiler/jvmci/compilerToVM/GetStackTraceElementTest.java index 1961de54953..0c3e4ba92cc 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/GetStackTraceElementTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetStackTraceElementTest.java @@ -24,7 +24,7 @@ /** * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/GetSymbolTest.java b/hotspot/test/compiler/jvmci/compilerToVM/GetSymbolTest.java index d8f256f0b52..7b14a8c2a95 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/GetSymbolTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetSymbolTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/GetVtableIndexForInterfaceTest.java b/hotspot/test/compiler/jvmci/compilerToVM/GetVtableIndexForInterfaceTest.java index 50c66cc7cbc..8cfc1d89cf9 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/GetVtableIndexForInterfaceTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetVtableIndexForInterfaceTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/HasCompiledCodeForOSRTest.java b/hotspot/test/compiler/jvmci/compilerToVM/HasCompiledCodeForOSRTest.java index 6f7f2c22f00..969a7f6d5ff 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/HasCompiledCodeForOSRTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/HasCompiledCodeForOSRTest.java @@ -24,7 +24,7 @@ /** * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/HasFinalizableSubclassTest.java b/hotspot/test/compiler/jvmci/compilerToVM/HasFinalizableSubclassTest.java index 3c924901b59..57ec63acd3e 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/HasFinalizableSubclassTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/HasFinalizableSubclassTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java b/hotspot/test/compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java index c16e0205b5b..2b95b87647b 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/IsMatureTest.java b/hotspot/test/compiler/jvmci/compilerToVM/IsMatureTest.java index 9668ec48c40..e1427d0becb 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/IsMatureTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/IsMatureTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib * ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/JVM_RegisterJVMCINatives.java b/hotspot/test/compiler/jvmci/compilerToVM/JVM_RegisterJVMCINatives.java index c6b63be07f2..3ba72a3099d 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/JVM_RegisterJVMCINatives.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/JVM_RegisterJVMCINatives.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @modules java.base/jdk.internal.misc * @modules jdk.vm.ci/jdk.vm.ci.hotspot diff --git a/hotspot/test/compiler/jvmci/compilerToVM/LookupKlassInPoolTest.java b/hotspot/test/compiler/jvmci/compilerToVM/LookupKlassInPoolTest.java index b619ae040b7..690ef34b195 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/LookupKlassInPoolTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/LookupKlassInPoolTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @summary Testing compiler.jvmci.CompilerToVM.lookupKlassInPool method * @library /test/lib / * @library ../common/patches diff --git a/hotspot/test/compiler/jvmci/compilerToVM/LookupKlassRefIndexInPoolTest.java b/hotspot/test/compiler/jvmci/compilerToVM/LookupKlassRefIndexInPoolTest.java index e3e719797a4..e53d695161d 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/LookupKlassRefIndexInPoolTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/LookupKlassRefIndexInPoolTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8138708 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/LookupMethodInPoolTest.java b/hotspot/test/compiler/jvmci/compilerToVM/LookupMethodInPoolTest.java index 5c8a8cb3593..f6d139c3b05 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/LookupMethodInPoolTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/LookupMethodInPoolTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8138708 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/LookupNameAndTypeRefIndexInPoolTest.java b/hotspot/test/compiler/jvmci/compilerToVM/LookupNameAndTypeRefIndexInPoolTest.java index 8c395e3a66b..ed376e04e41 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/LookupNameAndTypeRefIndexInPoolTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/LookupNameAndTypeRefIndexInPoolTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8138708 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/LookupNameInPoolTest.java b/hotspot/test/compiler/jvmci/compilerToVM/LookupNameInPoolTest.java index 6262c85f67b..e01f023f716 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/LookupNameInPoolTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/LookupNameInPoolTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8138708 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/LookupSignatureInPoolTest.java b/hotspot/test/compiler/jvmci/compilerToVM/LookupSignatureInPoolTest.java index 9807fbf5046..3dc8a64bdd2 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/LookupSignatureInPoolTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/LookupSignatureInPoolTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8138708 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/LookupTypeTest.java b/hotspot/test/compiler/jvmci/compilerToVM/LookupTypeTest.java index 20d57babd97..225da6983e4 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/LookupTypeTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/LookupTypeTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/MaterializeVirtualObjectTest.java b/hotspot/test/compiler/jvmci/compilerToVM/MaterializeVirtualObjectTest.java index c4068a1254d..dee13cfef8d 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/MaterializeVirtualObjectTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/MaterializeVirtualObjectTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * & (vm.compMode != "Xcomp" | vm.opt.TieredCompilation == null | vm.opt.TieredCompilation == true) * @summary no "-Xcomp -XX:-TieredCompilation" combination allowed until JDK-8140018 is resolved * @library / /test/lib diff --git a/hotspot/test/compiler/jvmci/compilerToVM/MethodIsIgnoredBySecurityStackWalkTest.java b/hotspot/test/compiler/jvmci/compilerToVM/MethodIsIgnoredBySecurityStackWalkTest.java index aa5c55a55ea..6f87bcfcd2d 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/MethodIsIgnoredBySecurityStackWalkTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/MethodIsIgnoredBySecurityStackWalkTest.java @@ -24,7 +24,7 @@ /** * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/ReadConfigurationTest.java b/hotspot/test/compiler/jvmci/compilerToVM/ReadConfigurationTest.java index b10ef88a7eb..866756c5b42 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/ReadConfigurationTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/ReadConfigurationTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/ReprofileTest.java b/hotspot/test/compiler/jvmci/compilerToVM/ReprofileTest.java index 3a731c5f3cd..9953d4c596a 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/ReprofileTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/ReprofileTest.java @@ -24,7 +24,7 @@ /** * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") & (vm.opt.TieredStopAtLevel == null | vm.opt.TieredStopAtLevel == 3) + * @requires vm.jvmci & (vm.opt.TieredStopAtLevel == null | vm.opt.TieredStopAtLevel == 3) * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/ResolveConstantInPoolTest.java b/hotspot/test/compiler/jvmci/compilerToVM/ResolveConstantInPoolTest.java index dc06f68ff99..63aef07deee 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/ResolveConstantInPoolTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/ResolveConstantInPoolTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java b/hotspot/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java index b6294b9a1e8..2ee506ba4f9 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8138708 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java b/hotspot/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java index f3fd052a5ae..248077d615e 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/ResolvePossiblyCachedConstantInPoolTest.java b/hotspot/test/compiler/jvmci/compilerToVM/ResolvePossiblyCachedConstantInPoolTest.java index e78322f7e3d..ca91e75011f 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/ResolvePossiblyCachedConstantInPoolTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/ResolvePossiblyCachedConstantInPoolTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8138708 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/ResolveTypeInPoolTest.java b/hotspot/test/compiler/jvmci/compilerToVM/ResolveTypeInPoolTest.java index 02b288bea04..3f48fd2f7b0 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/ResolveTypeInPoolTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/ResolveTypeInPoolTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @summary Testing compiler.jvmci.CompilerToVM.resolveTypeInPool method * @library /test/lib / * @library ../common/patches diff --git a/hotspot/test/compiler/jvmci/compilerToVM/ShouldDebugNonSafepointsTest.java b/hotspot/test/compiler/jvmci/compilerToVM/ShouldDebugNonSafepointsTest.java index 2e66c2eefec..18a571ba660 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/ShouldDebugNonSafepointsTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/ShouldDebugNonSafepointsTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib/ * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/compilerToVM/ShouldInlineMethodTest.java b/hotspot/test/compiler/jvmci/compilerToVM/ShouldInlineMethodTest.java index 80d1c354015..675a1364041 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/ShouldInlineMethodTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/ShouldInlineMethodTest.java @@ -24,7 +24,7 @@ /** * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/errors/TestInvalidCompilationResult.java b/hotspot/test/compiler/jvmci/errors/TestInvalidCompilationResult.java index 4cc352451dc..7ef5f8e4800 100644 --- a/hotspot/test/compiler/jvmci/errors/TestInvalidCompilationResult.java +++ b/hotspot/test/compiler/jvmci/errors/TestInvalidCompilationResult.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @modules jdk.vm.ci/jdk.vm.ci.hotspot * jdk.vm.ci/jdk.vm.ci.code * jdk.vm.ci/jdk.vm.ci.code.site diff --git a/hotspot/test/compiler/jvmci/errors/TestInvalidDebugInfo.java b/hotspot/test/compiler/jvmci/errors/TestInvalidDebugInfo.java index e4a4d46f204..8d3e92b1912 100644 --- a/hotspot/test/compiler/jvmci/errors/TestInvalidDebugInfo.java +++ b/hotspot/test/compiler/jvmci/errors/TestInvalidDebugInfo.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @modules jdk.vm.ci/jdk.vm.ci.hotspot * jdk.vm.ci/jdk.vm.ci.code * jdk.vm.ci/jdk.vm.ci.code.site diff --git a/hotspot/test/compiler/jvmci/errors/TestInvalidOopMap.java b/hotspot/test/compiler/jvmci/errors/TestInvalidOopMap.java index ad1a1d55f70..2e3f5f65e97 100644 --- a/hotspot/test/compiler/jvmci/errors/TestInvalidOopMap.java +++ b/hotspot/test/compiler/jvmci/errors/TestInvalidOopMap.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @modules jdk.vm.ci/jdk.vm.ci.hotspot * jdk.vm.ci/jdk.vm.ci.code * jdk.vm.ci/jdk.vm.ci.code.site diff --git a/hotspot/test/compiler/jvmci/events/JvmciNotifyBootstrapFinishedEventTest.java b/hotspot/test/compiler/jvmci/events/JvmciNotifyBootstrapFinishedEventTest.java index fdd7a00f211..84a4c90938b 100644 --- a/hotspot/test/compiler/jvmci/events/JvmciNotifyBootstrapFinishedEventTest.java +++ b/hotspot/test/compiler/jvmci/events/JvmciNotifyBootstrapFinishedEventTest.java @@ -24,7 +24,7 @@ /** * @test * @bug 8156034 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/events/JvmciNotifyInstallEventTest.java b/hotspot/test/compiler/jvmci/events/JvmciNotifyInstallEventTest.java index bec53e675ee..bb888c36a00 100644 --- a/hotspot/test/compiler/jvmci/events/JvmciNotifyInstallEventTest.java +++ b/hotspot/test/compiler/jvmci/events/JvmciNotifyInstallEventTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library / /test/lib * @library ../common/patches * @modules java.base/jdk.internal.misc diff --git a/hotspot/test/compiler/jvmci/events/JvmciShutdownEventTest.java b/hotspot/test/compiler/jvmci/events/JvmciShutdownEventTest.java index dc0973664e9..76f6538bac6 100644 --- a/hotspot/test/compiler/jvmci/events/JvmciShutdownEventTest.java +++ b/hotspot/test/compiler/jvmci/events/JvmciShutdownEventTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8136421 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @modules java.base/jdk.internal.misc * @modules jdk.vm.ci/jdk.vm.ci.hotspot diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DataPatchTest.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DataPatchTest.java index c2e3edf502f..10a968f696c 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DataPatchTest.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DataPatchTest.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9") & os.arch != "aarch64" + * @requires vm.jvmci & (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9") * @library / * @modules jdk.vm.ci/jdk.vm.ci.hotspot * jdk.vm.ci/jdk.vm.ci.meta diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/InterpreterFrameSizeTest.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/InterpreterFrameSizeTest.java index db19e221487..05d8bdb9c44 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/InterpreterFrameSizeTest.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/InterpreterFrameSizeTest.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9") & os.arch != "aarch64" + * @requires vm.jvmci & (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9") * @modules jdk.vm.ci/jdk.vm.ci.hotspot * jdk.vm.ci/jdk.vm.ci.code * jdk.vm.ci/jdk.vm.ci.code.site diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/MaxOopMapStackOffsetTest.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/MaxOopMapStackOffsetTest.java index 4a9532809c7..78965574ff2 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/MaxOopMapStackOffsetTest.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/MaxOopMapStackOffsetTest.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9") & os.arch != "aarch64" + * @requires vm.jvmci & (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9") * @library / * @modules jdk.vm.ci/jdk.vm.ci.hotspot * jdk.vm.ci/jdk.vm.ci.meta diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java index 0800e7bea10..49a52f8c01e 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9") & os.arch != "aarch64" + * @requires vm.jvmci & (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9") * @library /test/lib / * @modules jdk.vm.ci/jdk.vm.ci.hotspot * jdk.vm.ci/jdk.vm.ci.code diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleCodeInstallationTest.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleCodeInstallationTest.java index 1f69fc86e2f..908eaf6e79a 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleCodeInstallationTest.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleCodeInstallationTest.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9") & os.arch != "aarch64" + * @requires vm.jvmci & (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9") * @library / * @modules jdk.vm.ci/jdk.vm.ci.hotspot * jdk.vm.ci/jdk.vm.ci.meta diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java index 85c7b453add..6f3833ed9fd 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9") & os.arch != "aarch64" + * @requires vm.jvmci & (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9") * @library / * @modules jdk.vm.ci/jdk.vm.ci.hotspot * jdk.vm.ci/jdk.vm.ci.meta diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java index bee4f8d3b81..88625aa349d 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9") & os.arch != "aarch64" + * @requires vm.jvmci & (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9") * @library / * @modules jdk.vm.ci/jdk.vm.ci.hotspot * jdk.vm.ci/jdk.vm.ci.meta diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotConstantReflectionProviderTest.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotConstantReflectionProviderTest.java index c820b7ede33..b3ee6312348 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotConstantReflectionProviderTest.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotConstantReflectionProviderTest.java @@ -23,7 +23,7 @@ /* * @test jdk.vm.ci.hotspot.test.HotSpotConstantReflectionProviderTest - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @modules jdk.vm.ci/jdk.vm.ci.runtime * jdk.vm.ci/jdk.vm.ci.meta * jdk.vm.ci/jdk.vm.ci.hotspot diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MemoryAccessProviderTest.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MemoryAccessProviderTest.java index e99f7bbf9a5..bbf4c3a1ab9 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MemoryAccessProviderTest.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MemoryAccessProviderTest.java @@ -24,7 +24,7 @@ /* * @test * @bug 8152341 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib /compiler/jvmci/jdk.vm.ci.hotspot.test/src * @modules jdk.vm.ci/jdk.vm.ci.meta * jdk.vm.ci/jdk.vm.ci.common diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MethodHandleAccessProviderTest.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MethodHandleAccessProviderTest.java index 601b1925bea..675ef8b61a3 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MethodHandleAccessProviderTest.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MethodHandleAccessProviderTest.java @@ -25,7 +25,7 @@ * @test * @bug 8152343 * @bug 8161068 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib /compiler/jvmci/jdk.vm.ci.hotspot.test/src * @modules jdk.vm.ci/jdk.vm.ci.meta * jdk.vm.ci/jdk.vm.ci.runtime diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ConstantTest.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ConstantTest.java index 69323c14ab0..fb0f1a2bd80 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ConstantTest.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ConstantTest.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library ../../../../../ * @modules jdk.vm.ci/jdk.vm.ci.meta * jdk.vm.ci/jdk.vm.ci.runtime diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/RedefineClassTest.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/RedefineClassTest.java index f56aa751d5f..30f5b723cee 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/RedefineClassTest.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/RedefineClassTest.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library ../../../../../ * @modules jdk.vm.ci/jdk.vm.ci.meta * jdk.vm.ci/jdk.vm.ci.runtime diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveConcreteMethodTest.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveConcreteMethodTest.java index 21cdc8563d9..78c5a79f81c 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveConcreteMethodTest.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveConcreteMethodTest.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @modules jdk.vm.ci/jdk.vm.ci.meta * jdk.vm.ci/jdk.vm.ci.runtime * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.ResolvedJavaTypeResolveConcreteMethodTest diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveMethodTest.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveMethodTest.java index a32395c1762..f4b15b2dc82 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveMethodTest.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveMethodTest.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @modules jdk.vm.ci/jdk.vm.ci.meta * jdk.vm.ci/jdk.vm.ci.runtime * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.ResolvedJavaTypeResolveMethodTest diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestConstantReflectionProvider.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestConstantReflectionProvider.java index 5d91756350e..43cd69f0352 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestConstantReflectionProvider.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestConstantReflectionProvider.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library ../../../../../ * @modules jdk.vm.ci/jdk.vm.ci.meta * jdk.vm.ci/jdk.vm.ci.runtime diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaField.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaField.java index 622c25e0624..792901898a3 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaField.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaField.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library ../../../../../ * @modules jdk.vm.ci/jdk.vm.ci.meta * jdk.vm.ci/jdk.vm.ci.runtime diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaMethod.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaMethod.java index 5af25f8057a..a8edfec11e5 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaMethod.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaMethod.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library ../../../../../ * @modules jdk.vm.ci/jdk.vm.ci.meta * jdk.vm.ci/jdk.vm.ci.runtime diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaType.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaType.java index 66e50693f9a..669b579d51b 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaType.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaType.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library ../../../../../ * @modules jdk.vm.ci/jdk.vm.ci.meta * jdk.vm.ci/jdk.vm.ci.runtime diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java index 4352654767d..37d7d5233da 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library ../../../../../ * @modules jdk.vm.ci/jdk.vm.ci.meta * jdk.vm.ci/jdk.vm.ci.runtime diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java index 3c15295d277..48a6dc8613e 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library ../../../../../ * @modules jdk.vm.ci/jdk.vm.ci.meta * jdk.vm.ci/jdk.vm.ci.runtime diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java index 0be4d5522fb..c4fc8fce71d 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library ../../../../../ * @modules jdk.vm.ci/jdk.vm.ci.meta * jdk.vm.ci/jdk.vm.ci.runtime diff --git a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java index be0b05563e1..e8f9f9ba082 100644 --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java @@ -23,7 +23,7 @@ /** * @test - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library ../../../../../ * @modules java.base/jdk.internal.reflect * jdk.vm.ci/jdk.vm.ci.meta diff --git a/hotspot/test/compiler/jvmci/meta/StableFieldTest.java b/hotspot/test/compiler/jvmci/meta/StableFieldTest.java index 25bc2a905db..147811f6b6f 100644 --- a/hotspot/test/compiler/jvmci/meta/StableFieldTest.java +++ b/hotspot/test/compiler/jvmci/meta/StableFieldTest.java @@ -24,7 +24,7 @@ /** * @test * @bug 8151664 - * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @requires vm.jvmci * @library /test/lib / * @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.vm.annotation From 7624f76c84c0dd37e09cc15ef79cfc86c8f3127d Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Sun, 27 Nov 2016 19:58:30 -0800 Subject: [PATCH 082/235] 8169867: Method::restore_unshareable_info does not invoke Method::link_method Reviewed-by: jiangli, kvn, thartmann --- hotspot/src/share/vm/oops/constMethod.hpp | 2 +- hotspot/src/share/vm/oops/method.cpp | 109 ++++++++++++++---- .../src/share/vm/runtime/sharedRuntime.cpp | 2 + .../src/share/vm/runtime/sharedRuntime.hpp | 3 + 4 files changed, 95 insertions(+), 21 deletions(-) diff --git a/hotspot/src/share/vm/oops/constMethod.hpp b/hotspot/src/share/vm/oops/constMethod.hpp index 568c6c49283..45246ba209b 100644 --- a/hotspot/src/share/vm/oops/constMethod.hpp +++ b/hotspot/src/share/vm/oops/constMethod.hpp @@ -205,7 +205,7 @@ private: // Adapter blob (i2c/c2i) for this Method*. Set once when method is linked. union { AdapterHandlerEntry* _adapter; - AdapterHandlerEntry** _adapter_trampoline; + AdapterHandlerEntry** _adapter_trampoline; // see comments around Method::link_method() }; int _constMethod_size; diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp index 0cd830f1934..4e3dcf03bd8 100644 --- a/hotspot/src/share/vm/oops/method.cpp +++ b/hotspot/src/share/vm/oops/method.cpp @@ -953,34 +953,103 @@ void Method::unlink_method() { } #endif +/**************************************************************************** +// The following illustrates how the entries work for CDS shared Methods: +// +// Our goal is to delay writing into a shared Method until it's compiled. +// Hence, we want to determine the initial values for _i2i_entry, +// _from_interpreted_entry and _from_compiled_entry during CDS dump time. +// +// In this example, both Methods A and B have the _i2i_entry of "zero_locals". +// They also have similar signatures so that they will share the same +// AdapterHandlerEntry. +// +// _adapter_trampoline points to a fixed location in the RW section of +// the CDS archive. This location initially contains a NULL pointer. When the +// first of method A or B is linked, an AdapterHandlerEntry is allocated +// dynamically, and its c2i/i2c entries are generated. +// +// _i2i_entry and _from_interpreted_entry initially points to the same +// (fixed) location in the CODE section of the CDS archive. This contains +// an unconditional branch to the actual entry for "zero_locals", which is +// generated at run time and may be on an arbitrary address. Thus, the +// unconditional branch is also generated at run time to jump to the correct +// address. +// +// Similarly, _from_compiled_entry points to a fixed address in the CODE +// section. This address has enough space for an unconditional branch +// instruction, and is initially zero-filled. After the AdapterHandlerEntry is +// initialized, and the address for the actual c2i_entry is known, we emit a +// branch instruction here to branch to the actual c2i_entry. +// +// The effect of the extra branch on the i2i and c2i entries is negligible. +// +// The reason for putting _adapter_trampoline in RO is many shared Methods +// share the same AdapterHandlerEntry, so we can save space in the RW section +// by having the extra indirection. + + +[Method A: RW] + _constMethod ----> [ConstMethod: RO] + _adapter_trampoline -----------+ + | + _i2i_entry (same value as method B) | + _from_interpreted_entry (same value as method B) | + _from_compiled_entry (same value as method B) | + | + | +[Method B: RW] +--------+ + _constMethod ----> [ConstMethod: RO] | + _adapter_trampoline --+--->(AdapterHandlerEntry* ptr: RW)-+ + | + +-------------------------------+ + | + +----> [AdapterHandlerEntry] (allocated at run time) + _fingerprint + _c2i_entry ---------------------------------+->[c2i entry..] + _i2i_entry -------------+ _i2c_entry ---------------+-> [i2c entry..] | + _from_interpreted_entry | _c2i_unverified_entry | | + | | | | + | | (_cds_entry_table: CODE) | | + | +->[0]: jmp _entry_table[0] --> (i2i_entry_for "zero_locals") | | + | | (allocated at run time) | | + | | ... [asm code ...] | | + +-[not compiled]-+ [n]: jmp _entry_table[n] | | + | | | + | | | + +-[compiled]-------------------------------------------------------------------+ | + | + _from_compiled_entry------------> (_c2i_entry_trampoline: CODE) | + [jmp c2i_entry] ------------------------------------------------------+ + +***/ + // Called when the method_holder is getting linked. Setup entrypoints so the method // is ready to be called from interpreter, compiler, and vtables. void Method::link_method(const methodHandle& h_method, TRAPS) { // If the code cache is full, we may reenter this function for the // leftover methods that weren't linked. if (is_shared()) { - if (adapter() != NULL) return; - } else { - if (_i2i_entry != NULL) return; - - assert(adapter() == NULL, "init'd to NULL" ); + address entry = Interpreter::entry_for_cds_method(h_method); + assert(entry != NULL && entry == _i2i_entry, + "should be correctly set during dump time"); + if (adapter() != NULL) { + return; + } + assert(entry == _from_interpreted_entry, + "should be correctly set during dump time"); + } else if (_i2i_entry != NULL) { + return; } assert( _code == NULL, "nothing compiled yet" ); // Setup interpreter entrypoint assert(this == h_method(), "wrong h_method()" ); - address entry; - if (this->is_shared()) { - entry = Interpreter::entry_for_cds_method(h_method); - } else { - entry = Interpreter::entry_for_method(h_method); - } - assert(entry != NULL, "interpreter entry must be non-null"); - if (is_shared()) { - assert(entry == _i2i_entry && entry == _from_interpreted_entry, - "should be correctly set during dump time"); - } else { + if (!is_shared()) { + assert(adapter() == NULL, "init'd to NULL"); + address entry = Interpreter::entry_for_method(h_method); + assert(entry != NULL, "interpreter entry must be non-null"); // Sets both _i2i_entry and _from_interpreted_entry set_interpreter_entry(entry); } @@ -1024,7 +1093,7 @@ address Method::make_adapters(methodHandle mh, TRAPS) { if (mh->is_shared()) { assert(mh->adapter() == adapter, "must be"); - assert(mh->_from_compiled_entry != NULL, "must be"); // FIXME, the instructions also not NULL + assert(mh->_from_compiled_entry != NULL, "must be"); } else { mh->set_adapter_entry(adapter); mh->_from_compiled_entry = adapter->get_c2i_entry(); @@ -1034,9 +1103,9 @@ address Method::make_adapters(methodHandle mh, TRAPS) { void Method::restore_unshareable_info(TRAPS) { // Since restore_unshareable_info can be called more than once for a method, don't - // redo any work. If this field is restored, there is nothing to do. - if (_from_compiled_entry == NULL) { - // restore method's vtable by calling a virtual function + // redo any work. + if (adapter() == NULL) { + // Restore Method's C++ vtable by calling a virtual function restore_vtable(); methodHandle mh(THREAD, this); diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp index 46f70657daf..00c550534b6 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp @@ -2600,6 +2600,7 @@ AdapterHandlerEntry* AdapterHandlerLibrary::new_entry(AdapterFingerPrint* finger AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(const methodHandle& method) { AdapterHandlerEntry* entry = get_adapter0(method); if (method->is_shared()) { + // See comments around Method::link_method() MutexLocker mu(AdapterHandlerLibrary_lock); if (method->adapter() == NULL) { method->update_adapter_trampoline(entry); @@ -2609,6 +2610,7 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(const methodHandle& meth CodeBuffer buffer(trampoline, (int)SharedRuntime::trampoline_size()); MacroAssembler _masm(&buffer); SharedRuntime::generate_trampoline(&_masm, entry->get_c2i_entry()); + assert(*(int*)trampoline != 0, "Instruction(s) for trampoline must not be encoded as zeros."); if (PrintInterpreter) { Disassembler::decode(buffer.insts_begin(), buffer.insts_end()); diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.hpp b/hotspot/src/share/vm/runtime/sharedRuntime.hpp index d938217bb9c..417db771393 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp @@ -676,6 +676,9 @@ class AdapterHandlerEntry : public BasicHashtableEntry { void print_adapter_on(outputStream* st) const; }; +// This class is used only with DumpSharedSpaces==true. It holds extra information +// that's used only during CDS dump time. +// For details, see comments around Method::link_method() class CDSAdapterHandlerEntry: public AdapterHandlerEntry { address _c2i_entry_trampoline; // allocated from shared spaces "MC" region AdapterHandlerEntry** _adapter_trampoline; // allocated from shared spaces "MD" region From caf8bb3f8b4ecd5e52b880353e811878f55e7e59 Mon Sep 17 00:00:00 2001 From: David Buck Date: Tue, 29 Nov 2016 06:20:56 +0000 Subject: [PATCH 083/235] 8170431: non-ASCII characters in source code comments (jimage.hpp) Reviewed-by: dholmes --- hotspot/src/share/vm/classfile/jimage.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/classfile/jimage.hpp b/hotspot/src/share/vm/classfile/jimage.hpp index f34ba6efde9..e2268e91510 100644 --- a/hotspot/src/share/vm/classfile/jimage.hpp +++ b/hotspot/src/share/vm/classfile/jimage.hpp @@ -94,7 +94,7 @@ typedef void (*JImageClose_t)(JImageFile* jimage); * Ex. * const char* package = (*JImagePackageToModule)(image, "java/lang"); * tty->print_cr(package); - * —> java.base + * -> java.base */ extern "C" const char * JIMAGE_PackageToModule(JImageFile* jimage, const char* package_name); @@ -126,7 +126,7 @@ typedef JImageLocationRef(*JImageFindResource_t)(JImageFile* jimage, /* - * JImageGetResource - Given an open image file (see JImageOpen), a resource’s + * JImageGetResource - Given an open image file (see JImageOpen), a resource's * location information (see JImageFindResource), a buffer of appropriate * size and the size, retrieve the bytes associated with the * resource. If the size is less than the resource size then the read is truncated. @@ -158,7 +158,7 @@ typedef jlong(*JImageGetResource_t)(JImageFile* jimage, JImageLocationRef locati * Ex. * bool ctw_visitor(JImageFile* jimage, const char* module_name, const char* version, * const char* package, const char* name, const char* extension, void* arg) { - * if (strcmp(extension, “class”) == 0) { + * if (strcmp(extension, "class") == 0) { * char path[JIMAGE_MAX_PATH]; * Thread* THREAD = Thread::current(); * jio_snprintf(path, JIMAGE_MAX_PATH - 1, "/%s/%s", package, name); From 5e29b0af21ef18b4805b0208738294cfef7c5fa3 Mon Sep 17 00:00:00 2001 From: Tobias Hartmann Date: Tue, 29 Nov 2016 08:16:15 +0100 Subject: [PATCH 084/235] 8168996: C2 crash at postaloc.cpp:140 : assert(false) failed: unexpected yanked node Prevent MemBarAcquire from keeping a LoadNNode alive by adding it to the worklist if it is the only user of a DecodeNNode. Reviewed-by: kvn --- hotspot/src/share/vm/opto/node.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/opto/node.cpp b/hotspot/src/share/vm/opto/node.cpp index 833b7600d3e..9b336888f62 100644 --- a/hotspot/src/share/vm/opto/node.cpp +++ b/hotspot/src/share/vm/opto/node.cpp @@ -1117,8 +1117,8 @@ bool Node::has_special_unique_user() const { if (this->is_Store()) { // Condition for back-to-back stores folding. return n->Opcode() == op && n->in(MemNode::Memory) == this; - } else if (this->is_Load()) { - // Condition for removing an unused LoadNode from the MemBarAcquire precedence input + } else if (this->is_Load() || this->is_DecodeN()) { + // Condition for removing an unused LoadNode or DecodeNNode from the MemBarAcquire precedence input return n->Opcode() == Op_MemBarAcquire; } else if (op == Op_AddL) { // Condition for convL2I(addL(x,y)) ==> addI(convL2I(x),convL2I(y)) From 9b7be3512e9e1a3e03e371ae65f8e60640d31e28 Mon Sep 17 00:00:00 2001 From: Kirill Zhaldybin Date: Fri, 25 Nov 2016 20:00:51 +0300 Subject: [PATCH 085/235] 8169003: LogDecorations.iso8601_utctime_test fails if numeric locale uses "," as separator between integer and fraction part Reviewed-by: mlarsson, iignatyev --- .../native/logging/test_logDecorations.cpp | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/hotspot/test/native/logging/test_logDecorations.cpp b/hotspot/test/native/logging/test_logDecorations.cpp index f4c7b87e391..68c0210f325 100644 --- a/hotspot/test/native/logging/test_logDecorations.cpp +++ b/hotspot/test/native/logging/test_logDecorations.cpp @@ -131,10 +131,9 @@ TEST(LogDecorations, iso8601_time) { time_t expected_ts = time(NULL); // Verify format - int y, M, d, h, m; - double s; - int read = sscanf(timestr, "%d-%d-%dT%d:%d:%lf", &y, &M, &d, &h, &m, &s); - ASSERT_EQ(6, read) << "Invalid format: " << timestr; + int y, M, d, h, m, s, ms; + int read = sscanf(timestr, "%d-%d-%dT%d:%d:%d.%d", &y, &M, &d, &h, &m, &s, &ms); + ASSERT_EQ(7, read) << "Invalid format: " << timestr; // Verify reported time & date struct tm reported_time = {0}; @@ -167,17 +166,16 @@ TEST(LogDecorations, iso8601_utctime) { // Verify format char trailing_character; - int y, M, d, h, m, offset; - double s; - int read = sscanf(timestr, "%d-%d-%dT%d:%d:%lf%c%d", &y, &M, &d, &h, &m, &s, &trailing_character, &offset); - ASSERT_GT(read, 7) << "Invalid format: " << timestr; + int y, M, d, h, m, s, ms, offset; + + int read = sscanf(timestr, "%d-%d-%dT%d:%d:%d.%d%c%d", &y, &M, &d, &h, &m, &s, &ms, &trailing_character, &offset); + + ASSERT_EQ(9, read) << "Invalid format: " << timestr; // Ensure time is UTC (no offset) - if (trailing_character == '+') { - ASSERT_EQ(0, offset) << "Invalid offset: " << timestr; - } else { - ASSERT_EQ('Z', trailing_character) << "Invalid offset: " << timestr; - } + ASSERT_EQ('+', trailing_character) << "Invalid trailing character for UTC: " + << trailing_character; + ASSERT_EQ(0, offset) << "Invalid offset: " << timestr; struct tm reported_time = {0}; reported_time.tm_year = y - 1900; From f2dcdc6fb577e5b055b4c1f8c0afa1630222ed1f Mon Sep 17 00:00:00 2001 From: Kirill Zhaldybin Date: Mon, 28 Nov 2016 18:54:30 +0300 Subject: [PATCH 086/235] 8166156: Convert test_semaphore to GTest Reviewed-by: kbarrett, tschatzl, stefank --- .../share/vm/utilities/internalVMTests.cpp | 1 - .../native/runtime/test_semaphore.cpp} | 38 ++++++++----------- 2 files changed, 15 insertions(+), 24 deletions(-) rename hotspot/{src/share/vm/runtime/semaphore.cpp => test/native/runtime/test_semaphore.cpp} (86%) diff --git a/hotspot/src/share/vm/utilities/internalVMTests.cpp b/hotspot/src/share/vm/utilities/internalVMTests.cpp index 26a551d1676..ecc4bf75eeb 100644 --- a/hotspot/src/share/vm/utilities/internalVMTests.cpp +++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp @@ -41,7 +41,6 @@ void InternalVMTests::run_test(const char* name, void (*test)()) { void InternalVMTests::run() { tty->print_cr("Running internal VM tests"); - run_unit_test(test_semaphore); run_unit_test(TestReservedSpace_test); run_unit_test(TestReserveMemorySpecial_test); run_unit_test(TestVirtualSpace_test); diff --git a/hotspot/src/share/vm/runtime/semaphore.cpp b/hotspot/test/native/runtime/test_semaphore.cpp similarity index 86% rename from hotspot/src/share/vm/runtime/semaphore.cpp rename to hotspot/test/native/runtime/test_semaphore.cpp index 2fedafbb76e..31939424912 100644 --- a/hotspot/src/share/vm/runtime/semaphore.cpp +++ b/hotspot/test/native/runtime/test_semaphore.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, 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 @@ -19,16 +19,11 @@ * 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 "utilities/debug.hpp" #include "runtime/semaphore.hpp" - -/////////////// Unit tests /////////////// - -#ifndef PRODUCT +#include "unittest.hpp" static void test_semaphore_single_separate(uint count) { Semaphore sem(0); @@ -67,7 +62,19 @@ static void test_semaphore_many(uint value, uint max, uint increments) { } } -static void test_semaphore_many() { +TEST(Semaphore, single_separate) { + for (uint i = 1; i < 10; i++) { + test_semaphore_single_separate(i); + } +} + +TEST(Semaphore, single_combined) { + for (uint i = 1; i < 10; i++) { + test_semaphore_single_combined(i); + } +} + +TEST(Semaphore, many) { for (uint max = 0; max < 10; max++) { for (uint value = 0; value < max; value++) { for (uint inc = 1; inc <= max - value; inc++) { @@ -76,18 +83,3 @@ static void test_semaphore_many() { } } } - -void test_semaphore() { - for (uint i = 1; i < 10; i++) { - test_semaphore_single_separate(i); - } - - for (uint i = 0; i < 10; i++) { - test_semaphore_single_combined(i); - } - - test_semaphore_many(); -} - -#endif // PRODUCT - From f9911247afc55871118f4c2d08b3b1c3095eb6fb Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Tue, 29 Nov 2016 11:26:25 -0500 Subject: [PATCH 087/235] 8170297: runtime/SharedArchiveFile/LargeSharedSpace.java didn't run out of memory Split the test cases. Add -XX:+UseCompressedClassPointers -XX:CompressedClassSpaceSize=3G for the 64-bit -XX:SharedMiscCodeSize=1600386047 test case. Reviewed-by: ccheung, iklam, dholmes --- .../SharedArchiveFile/LargeSharedSpace.java | 64 ++++++++++++++----- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/hotspot/test/runtime/SharedArchiveFile/LargeSharedSpace.java b/hotspot/test/runtime/SharedArchiveFile/LargeSharedSpace.java index 1d62853c314..35d017baa8e 100644 --- a/hotspot/test/runtime/SharedArchiveFile/LargeSharedSpace.java +++ b/hotspot/test/runtime/SharedArchiveFile/LargeSharedSpace.java @@ -24,7 +24,7 @@ /* * @test LargeSharedSpace * @bug 8168790 8169870 - * @summary Test CDS dumping with specific space size. + * @summary Test CDS dumping using specific space size without crashing. * The space size used in the test might not be suitable on windows. * @requires (os.family != "windows") * @library /test/lib @@ -35,27 +35,59 @@ import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.Platform; public class LargeSharedSpace { public static void main(String[] args) throws Exception { - String sizes[] = {"1066924031", "1600386047"}; - String expectedOutputs[] = - {/* can dump using the given size */ - "Loading classes to share", - /* the size is too large, exceeding the limit for compressed klass support */ - "larger than compressed klass limit"}; - for (int i = 0; i < sizes.length; i++) { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - "-XX:SharedMiscCodeSize="+sizes[i], "-XX:+UnlockDiagnosticVMOptions", + ProcessBuilder pb; + OutputAnalyzer output; + + // Test case 1: -XX:SharedMiscCodeSize=1066924031 + // + // The archive should be dumped successfully. It might fail to reserve memory + // for shared space under low memory condition. The dumping process should not crash. + pb = ProcessTools.createJavaProcessBuilder( + "-XX:SharedMiscCodeSize=1066924031", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./LargeSharedSpace.jsa", "-Xshare:dump"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output = new OutputAnalyzer(pb.start()); + try { + output.shouldContain("Loading classes to share"); + } catch (RuntimeException e1) { + output.shouldContain("Unable to allocate memory for shared space"); + } + + // Test case 2: -XX:SharedMiscCodeSize=1600386047 + // + // On 64-bit platform, compressed class pointer is used. When the combined + // shared space size and the compressed space size is larger than the 4G + // compressed klass limit (0x100000000), error is reported. + // + // The dumping process should not crash. + if (Platform.is64bit()) { + pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UseCompressedClassPointers", "-XX:CompressedClassSpaceSize=3G", + "-XX:SharedMiscCodeSize=1600386047", "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=./LargeSharedSpace.jsa", "-Xshare:dump"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("larger than compressed klass limit"); + } + + // Test case 3: -XX:SharedMiscCodeSize=1600386047 + // + // On 32-bit platform, compressed class pointer is not used. It may fail + // to reserve memory under low memory condition. + // + // The dumping process should not crash. + if (Platform.is32bit()) { + pb = ProcessTools.createJavaProcessBuilder( + "-XX:SharedMiscCodeSize=1600386047", "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=./LargeSharedSpace.jsa", "-Xshare:dump"); + output = new OutputAnalyzer(pb.start()); try { - output.shouldContain(expectedOutputs[i]); - } catch (RuntimeException e) { - /* failed to reserve the memory for the required size, might happen - on 32-bit platforms */ + output.shouldContain("Loading classes to share"); + } catch (RuntimeException e3) { output.shouldContain("Unable to allocate memory for shared space"); } - } + } } } From 0925fecaf5e5da75c055de7fdf4ad07d0977201c Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Tue, 29 Nov 2016 19:25:36 +0100 Subject: [PATCH 088/235] 8170395: Metaspace initialization queries the wrong chunk freelist Reviewed-by: mgerdin, pliden, stuefe --- hotspot/src/share/vm/memory/metaspace.cpp | 278 +++++++++++------- hotspot/src/share/vm/memory/metaspace.hpp | 13 +- .../test/native/memory/test_spaceManager.cpp | 39 +++ 3 files changed, 219 insertions(+), 111 deletions(-) create mode 100644 hotspot/test/native/memory/test_spaceManager.cpp diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index d5843df1077..3cfbf6dcb75 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -596,9 +596,8 @@ class VirtualSpaceList : public CHeapObj { size_t free_bytes(); - Metachunk* get_new_chunk(size_t word_size, - size_t grow_chunks_by_words, - size_t medium_chunk_bunch); + Metachunk* get_new_chunk(size_t chunk_word_size, + size_t suggested_commit_granularity); bool expand_node_by(VirtualSpaceNode* node, size_t min_words, @@ -749,15 +748,22 @@ class SpaceManager : public CHeapObj { MediumChunkMultiple = 4 }; - bool is_class() { return _mdtype == Metaspace::ClassType; } + static size_t specialized_chunk_size(bool is_class) { return is_class ? ClassSpecializedChunk : SpecializedChunk; } + static size_t small_chunk_size(bool is_class) { return is_class ? ClassSmallChunk : SmallChunk; } + static size_t medium_chunk_size(bool is_class) { return is_class ? ClassMediumChunk : MediumChunk; } + + static size_t smallest_chunk_size(bool is_class) { return specialized_chunk_size(is_class); } // Accessors - size_t specialized_chunk_size() { return (size_t) is_class() ? ClassSpecializedChunk : SpecializedChunk; } - size_t small_chunk_size() { return (size_t) is_class() ? ClassSmallChunk : SmallChunk; } - size_t medium_chunk_size() { return (size_t) is_class() ? ClassMediumChunk : MediumChunk; } - size_t medium_chunk_bunch() { return medium_chunk_size() * MediumChunkMultiple; } + bool is_class() const { return _mdtype == Metaspace::ClassType; } - size_t smallest_chunk_size() { return specialized_chunk_size(); } + size_t specialized_chunk_size() const { return specialized_chunk_size(is_class()); } + size_t small_chunk_size() const { return small_chunk_size(is_class()); } + size_t medium_chunk_size() const { return medium_chunk_size(is_class()); } + + size_t smallest_chunk_size() const { return smallest_chunk_size(is_class()); } + + size_t medium_chunk_bunch() const { return medium_chunk_size() * MediumChunkMultiple; } size_t allocated_blocks_words() const { return _allocated_blocks_words; } size_t allocated_blocks_bytes() const { return _allocated_blocks_words * BytesPerWord; } @@ -781,10 +787,13 @@ class SpaceManager : public CHeapObj { // decremented for all the Metachunks in-use by this SpaceManager. void dec_total_from_size_metrics(); - // Set the sizes for the initial chunks. - void get_initial_chunk_sizes(Metaspace::MetaspaceType type, - size_t* chunk_word_size, - size_t* class_chunk_word_size); + // Adjust the initial chunk size to match one of the fixed chunk list sizes, + // or return the unadjusted size if the requested size is humongous. + static size_t adjust_initial_chunk_size(size_t requested, bool is_class_space); + size_t adjust_initial_chunk_size(size_t requested) const; + + // Get the initial chunks size for this metaspace type. + size_t get_initial_chunk_size(Metaspace::MetaspaceType type) const; size_t sum_capacity_in_chunks_in_use() const; size_t sum_used_in_chunks_in_use() const; @@ -795,7 +804,7 @@ class SpaceManager : public CHeapObj { size_t sum_count_in_chunks_in_use(); size_t sum_count_in_chunks_in_use(ChunkIndex i); - Metachunk* get_new_chunk(size_t word_size, size_t grow_chunks_by_words); + Metachunk* get_new_chunk(size_t chunk_word_size); // Block allocation and deallocation. // Allocates a block from the current chunk @@ -1400,12 +1409,10 @@ bool VirtualSpaceList::expand_by(size_t min_words, size_t preferred_words) { return false; } -Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, - size_t grow_chunks_by_words, - size_t medium_chunk_bunch) { +Metachunk* VirtualSpaceList::get_new_chunk(size_t chunk_word_size, size_t suggested_commit_granularity) { // Allocate a chunk out of the current virtual space. - Metachunk* next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words); + Metachunk* next = current_virtual_space()->get_chunk_vs(chunk_word_size); if (next != NULL) { return next; @@ -1414,8 +1421,8 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, // The expand amount is currently only determined by the requested sizes // and not how much committed memory is left in the current virtual space. - size_t min_word_size = align_size_up(grow_chunks_by_words, Metaspace::commit_alignment_words()); - size_t preferred_word_size = align_size_up(medium_chunk_bunch, Metaspace::commit_alignment_words()); + size_t min_word_size = align_size_up(chunk_word_size, Metaspace::commit_alignment_words()); + size_t preferred_word_size = align_size_up(suggested_commit_granularity, Metaspace::commit_alignment_words()); if (min_word_size >= preferred_word_size) { // Can happen when humongous chunks are allocated. preferred_word_size = min_word_size; @@ -1423,7 +1430,7 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, bool expanded = expand_by(min_word_size, preferred_word_size); if (expanded) { - next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words); + next = current_virtual_space()->get_chunk_vs(chunk_word_size); assert(next != NULL, "The allocation was expected to succeed after the expansion"); } @@ -1917,36 +1924,58 @@ void ChunkManager::print_on(outputStream* out) const { // SpaceManager methods -void SpaceManager::get_initial_chunk_sizes(Metaspace::MetaspaceType type, - size_t* chunk_word_size, - size_t* class_chunk_word_size) { - switch (type) { - case Metaspace::BootMetaspaceType: - *chunk_word_size = Metaspace::first_chunk_word_size(); - *class_chunk_word_size = Metaspace::first_class_chunk_word_size(); - break; - case Metaspace::ROMetaspaceType: - *chunk_word_size = SharedReadOnlySize / wordSize; - *class_chunk_word_size = ClassSpecializedChunk; - break; - case Metaspace::ReadWriteMetaspaceType: - *chunk_word_size = SharedReadWriteSize / wordSize; - *class_chunk_word_size = ClassSpecializedChunk; - break; - case Metaspace::AnonymousMetaspaceType: - case Metaspace::ReflectionMetaspaceType: - *chunk_word_size = SpecializedChunk; - *class_chunk_word_size = ClassSpecializedChunk; - break; - default: - *chunk_word_size = SmallChunk; - *class_chunk_word_size = ClassSmallChunk; - break; +size_t SpaceManager::adjust_initial_chunk_size(size_t requested, bool is_class_space) { + size_t chunk_sizes[] = { + specialized_chunk_size(is_class_space), + small_chunk_size(is_class_space), + medium_chunk_size(is_class_space) + }; + + // Adjust up to one of the fixed chunk sizes ... + for (size_t i = 0; i < ARRAY_SIZE(chunk_sizes); i++) { + if (requested <= chunk_sizes[i]) { + return chunk_sizes[i]; + } } - assert(*chunk_word_size != 0 && *class_chunk_word_size != 0, - "Initial chunks sizes bad: data " SIZE_FORMAT - " class " SIZE_FORMAT, - *chunk_word_size, *class_chunk_word_size); + + // ... or return the size as a humongous chunk. + return requested; +} + +size_t SpaceManager::adjust_initial_chunk_size(size_t requested) const { + return adjust_initial_chunk_size(requested, is_class()); +} + +size_t SpaceManager::get_initial_chunk_size(Metaspace::MetaspaceType type) const { + size_t requested; + + if (is_class()) { + switch (type) { + case Metaspace::BootMetaspaceType: requested = Metaspace::first_class_chunk_word_size(); break; + case Metaspace::ROMetaspaceType: requested = ClassSpecializedChunk; break; + case Metaspace::ReadWriteMetaspaceType: requested = ClassSpecializedChunk; break; + case Metaspace::AnonymousMetaspaceType: requested = ClassSpecializedChunk; break; + case Metaspace::ReflectionMetaspaceType: requested = ClassSpecializedChunk; break; + default: requested = ClassSmallChunk; break; + } + } else { + switch (type) { + case Metaspace::BootMetaspaceType: requested = Metaspace::first_chunk_word_size(); break; + case Metaspace::ROMetaspaceType: requested = SharedReadOnlySize / wordSize; break; + case Metaspace::ReadWriteMetaspaceType: requested = SharedReadWriteSize / wordSize; break; + case Metaspace::AnonymousMetaspaceType: requested = SpecializedChunk; break; + case Metaspace::ReflectionMetaspaceType: requested = SpecializedChunk; break; + default: requested = SmallChunk; break; + } + } + + // Adjust to one of the fixed chunk sizes (unless humongous) + const size_t adjusted = adjust_initial_chunk_size(requested); + + assert(adjusted != 0, "Incorrect initial chunk size. Requested: " + SIZE_FORMAT " adjusted: " SIZE_FORMAT, requested, adjusted); + + return adjusted; } size_t SpaceManager::sum_free_in_chunks_in_use() const { @@ -2131,8 +2160,8 @@ MetaWord* SpaceManager::grow_and_allocate(size_t word_size) { } // Get another chunk - size_t grow_chunks_by_words = calc_chunk_size(word_size); - Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words); + size_t chunk_word_size = calc_chunk_size(word_size); + Metachunk* next = get_new_chunk(chunk_word_size); MetaWord* mem = NULL; @@ -2431,14 +2460,12 @@ void SpaceManager::retire_current_chunk() { } } -Metachunk* SpaceManager::get_new_chunk(size_t word_size, - size_t grow_chunks_by_words) { +Metachunk* SpaceManager::get_new_chunk(size_t chunk_word_size) { // Get a chunk from the chunk freelist - Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words); + Metachunk* next = chunk_manager()->chunk_freelist_allocate(chunk_word_size); if (next == NULL) { - next = vs_list()->get_new_chunk(word_size, - grow_chunks_by_words, + next = vs_list()->get_new_chunk(chunk_word_size, medium_chunk_bunch()); } @@ -3176,7 +3203,7 @@ void Metaspace::initialize_class_space(ReservedSpace rs) { SIZE_FORMAT " != " SIZE_FORMAT, rs.size(), CompressedClassSpaceSize); assert(using_class_space(), "Must be using class space"); _class_space_list = new VirtualSpaceList(rs); - _chunk_manager_class = new ChunkManager(SpecializedChunk, ClassSmallChunk, ClassMediumChunk); + _chunk_manager_class = new ChunkManager(ClassSpecializedChunk, ClassSmallChunk, ClassMediumChunk); if (!_class_space_list->initialization_succeeded()) { vm_exit_during_initialization("Failed to setup compressed class space virtual space list."); @@ -3346,75 +3373,62 @@ void Metaspace::post_initialize() { MetaspaceGC::post_initialize(); } -Metachunk* Metaspace::get_initialization_chunk(MetadataType mdtype, - size_t chunk_word_size, - size_t chunk_bunch) { +void Metaspace::initialize_first_chunk(MetaspaceType type, MetadataType mdtype) { + Metachunk* chunk = get_initialization_chunk(type, mdtype); + if (chunk != NULL) { + // Add to this manager's list of chunks in use and current_chunk(). + get_space_manager(mdtype)->add_chunk(chunk, true); + } +} + +Metachunk* Metaspace::get_initialization_chunk(MetaspaceType type, MetadataType mdtype) { + size_t chunk_word_size = get_space_manager(mdtype)->get_initial_chunk_size(type); + // Get a chunk from the chunk freelist Metachunk* chunk = get_chunk_manager(mdtype)->chunk_freelist_allocate(chunk_word_size); - if (chunk != NULL) { - return chunk; + + if (chunk == NULL) { + chunk = get_space_list(mdtype)->get_new_chunk(chunk_word_size, + get_space_manager(mdtype)->medium_chunk_bunch()); } - return get_space_list(mdtype)->get_new_chunk(chunk_word_size, chunk_word_size, chunk_bunch); + // For dumping shared archive, report error if allocation has failed. + if (DumpSharedSpaces && chunk == NULL) { + report_insufficient_metaspace(MetaspaceAux::committed_bytes() + chunk_word_size * BytesPerWord); + } + + return chunk; +} + +void Metaspace::verify_global_initialization() { + assert(space_list() != NULL, "Metadata VirtualSpaceList has not been initialized"); + assert(chunk_manager_metadata() != NULL, "Metadata ChunkManager has not been initialized"); + + if (using_class_space()) { + assert(class_space_list() != NULL, "Class VirtualSpaceList has not been initialized"); + assert(chunk_manager_class() != NULL, "Class ChunkManager has not been initialized"); + } } void Metaspace::initialize(Mutex* lock, MetaspaceType type) { + verify_global_initialization(); - assert(space_list() != NULL, - "Metadata VirtualSpaceList has not been initialized"); - assert(chunk_manager_metadata() != NULL, - "Metadata ChunkManager has not been initialized"); - + // Allocate SpaceManager for metadata objects. _vsm = new SpaceManager(NonClassType, lock); - if (_vsm == NULL) { - return; - } - size_t word_size; - size_t class_word_size; - vsm()->get_initial_chunk_sizes(type, &word_size, &class_word_size); if (using_class_space()) { - assert(class_space_list() != NULL, - "Class VirtualSpaceList has not been initialized"); - assert(chunk_manager_class() != NULL, - "Class ChunkManager has not been initialized"); - // Allocate SpaceManager for classes. _class_vsm = new SpaceManager(ClassType, lock); - if (_class_vsm == NULL) { - return; - } } MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); // Allocate chunk for metadata objects - Metachunk* new_chunk = get_initialization_chunk(NonClassType, - word_size, - vsm()->medium_chunk_bunch()); - // For dumping shared archive, report error if allocation has failed. - if (DumpSharedSpaces && new_chunk == NULL) { - report_insufficient_metaspace(MetaspaceAux::committed_bytes() + word_size * BytesPerWord); - } - assert(!DumpSharedSpaces || new_chunk != NULL, "should have enough space for both chunks"); - if (new_chunk != NULL) { - // Add to this manager's list of chunks in use and current_chunk(). - vsm()->add_chunk(new_chunk, true); - } + initialize_first_chunk(type, NonClassType); // Allocate chunk for class metadata objects if (using_class_space()) { - Metachunk* class_chunk = get_initialization_chunk(ClassType, - class_word_size, - class_vsm()->medium_chunk_bunch()); - if (class_chunk != NULL) { - class_vsm()->add_chunk(class_chunk, true); - } else { - // For dumping shared archive, report error if allocation has failed. - if (DumpSharedSpaces) { - report_insufficient_metaspace(MetaspaceAux::committed_bytes() + class_word_size * BytesPerWord); - } - } + initialize_first_chunk(type, ClassType); } _alloc_record_head = NULL; @@ -3840,7 +3854,7 @@ class TestMetaspaceAuxTest : AllStatic { // vm_allocation_granularity aligned on Windows. size_t large_size = (size_t)(2*256*K + (os::vm_page_size()/BytesPerWord)); large_size += (os::vm_page_size()/BytesPerWord); - vs_list->get_new_chunk(large_size, large_size, 0); + vs_list->get_new_chunk(large_size, 0); } static void test() { @@ -4017,4 +4031,54 @@ void TestVirtualSpaceNode_test() { TestVirtualSpaceNodeTest::test(); TestVirtualSpaceNodeTest::test_is_available(); } + +// The following test is placed here instead of a gtest / unittest file +// because the ChunkManager class is only available in this file. +class SpaceManagerTest : AllStatic { + friend void SpaceManager_test_adjust_initial_chunk_size(); + + static void test_adjust_initial_chunk_size(bool is_class) { + const size_t smallest = SpaceManager::smallest_chunk_size(is_class); + const size_t normal = SpaceManager::small_chunk_size(is_class); + const size_t medium = SpaceManager::medium_chunk_size(is_class); + +#define test_adjust_initial_chunk_size(value, expected, is_class_value) \ + do { \ + size_t v = value; \ + size_t e = expected; \ + assert(SpaceManager::adjust_initial_chunk_size(v, (is_class_value)) == e, \ + "Expected: " SIZE_FORMAT " got: " SIZE_FORMAT, e, v); \ + } while (0) + + // Smallest (specialized) + test_adjust_initial_chunk_size(1, smallest, is_class); + test_adjust_initial_chunk_size(smallest - 1, smallest, is_class); + test_adjust_initial_chunk_size(smallest, smallest, is_class); + + // Small + test_adjust_initial_chunk_size(smallest + 1, normal, is_class); + test_adjust_initial_chunk_size(normal - 1, normal, is_class); + test_adjust_initial_chunk_size(normal, normal, is_class); + + // Medium + test_adjust_initial_chunk_size(normal + 1, medium, is_class); + test_adjust_initial_chunk_size(medium - 1, medium, is_class); + test_adjust_initial_chunk_size(medium, medium, is_class); + + // Humongous + test_adjust_initial_chunk_size(medium + 1, medium + 1, is_class); + +#undef test_adjust_initial_chunk_size + } + + static void test_adjust_initial_chunk_size() { + test_adjust_initial_chunk_size(false); + test_adjust_initial_chunk_size(true); + } +}; + +void SpaceManager_test_adjust_initial_chunk_size() { + SpaceManagerTest::test_adjust_initial_chunk_size(); +} + #endif diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp index 99581899fe8..87ab90331b7 100644 --- a/hotspot/src/share/vm/memory/metaspace.hpp +++ b/hotspot/src/share/vm/memory/metaspace.hpp @@ -105,14 +105,15 @@ class Metaspace : public CHeapObj { }; private: + static void verify_global_initialization(); + void initialize(Mutex* lock, MetaspaceType type); - // Get the first chunk for a Metaspace. Used for + // Initialize the first chunk for a Metaspace. Used for // special cases such as the boot class loader, reflection // class loader and anonymous class loader. - Metachunk* get_initialization_chunk(MetadataType mdtype, - size_t chunk_word_size, - size_t chunk_bunch); + void initialize_first_chunk(MetaspaceType type, MetadataType mdtype); + Metachunk* get_initialization_chunk(MetaspaceType type, MetadataType mdtype); // Align up the word size to the allocation word size static size_t align_word_size_up(size_t); @@ -139,6 +140,10 @@ class Metaspace : public CHeapObj { SpaceManager* _class_vsm; SpaceManager* class_vsm() const { return _class_vsm; } + SpaceManager* get_space_manager(MetadataType mdtype) { + assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype"); + return mdtype == ClassType ? class_vsm() : vsm(); + } // Allocate space for metadata of type mdtype. This is space // within a Metachunk and is used by diff --git a/hotspot/test/native/memory/test_spaceManager.cpp b/hotspot/test/native/memory/test_spaceManager.cpp new file mode 100644 index 00000000000..b253d22de68 --- /dev/null +++ b/hotspot/test/native/memory/test_spaceManager.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, 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" + +// The test function is only available in debug builds +#ifdef ASSERT + +#include "unittest.hpp" + +void SpaceManager_test_adjust_initial_chunk_size(); + +TEST(SpaceManager, adjust_initial_chunk_size) { + // The SpaceManager is only available in metaspace.cpp, + // so the test code is located in that file. + SpaceManager_test_adjust_initial_chunk_size(); +} + +#endif // ASSERT From 020f7ed9da9926a17f4d3d8fb3808c366390fe8f Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Tue, 29 Nov 2016 12:40:46 -0800 Subject: [PATCH 089/235] 8170416: CompilerControl: VectorizeDebug option type is incorrect VectorizeDebug C2 option flag should be uintx instead of bool. Reviewed-by: thartmann --- hotspot/src/share/vm/compiler/compilerDirectives.hpp | 3 ++- hotspot/src/share/vm/compiler/directivesParser.hpp | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/compiler/compilerDirectives.hpp b/hotspot/src/share/vm/compiler/compilerDirectives.hpp index a4909b554ae..283fd48127e 100644 --- a/hotspot/src/share/vm/compiler/compilerDirectives.hpp +++ b/hotspot/src/share/vm/compiler/compilerDirectives.hpp @@ -64,7 +64,7 @@ cflags(TraceOptoOutput, bool, false, TraceOptoOutput) \ cflags(TraceSpilling, bool, TraceSpilling, TraceSpilling) \ cflags(Vectorize, bool, false, Vectorize) \ - cflags(VectorizeDebug, bool, false, VectorizeDebug) \ + cflags(VectorizeDebug, uintx, 0, VectorizeDebug) \ cflags(CloneMapDebug, bool, false, CloneMapDebug) \ cflags(DoReserveCopyInSuperWordDebug, bool, false, DoReserveCopyInSuperWordDebug) \ cflags(IGVPrintLevel, intx, PrintIdealGraphLevel, IGVPrintLevel) \ @@ -140,6 +140,7 @@ public: compilerdirectives_c1_flags(set_function_definition) void print_intx(outputStream* st, ccstr n, intx v, bool mod) { if (mod) { st->print("%s:" INTX_FORMAT " ", n, v); } } + void print_uintx(outputStream* st, ccstr n, intx v, bool mod) { if (mod) { st->print("%s:" UINTX_FORMAT " ", n, v); } } void print_bool(outputStream* st, ccstr n, bool v, bool mod) { if (mod) { st->print("%s:%s ", n, v ? "true" : "false"); } } void print_double(outputStream* st, ccstr n, double v, bool mod) { if (mod) { st->print("%s:%f ", n, v); } } void print_ccstr(outputStream* st, ccstr n, ccstr v, bool mod) { if (mod) { st->print("%s:%s ", n, v); } } diff --git a/hotspot/src/share/vm/compiler/directivesParser.hpp b/hotspot/src/share/vm/compiler/directivesParser.hpp index ef0b48b20be..724ca5597a6 100644 --- a/hotspot/src/share/vm/compiler/directivesParser.hpp +++ b/hotspot/src/share/vm/compiler/directivesParser.hpp @@ -31,6 +31,7 @@ enum FlagType { boolFlag, intxFlag, + uintxFlag, doubleFlag, ccstrFlag, ccstrlistFlag, @@ -40,6 +41,7 @@ enum FlagType { static const char* flag_type_names[] = { "bool", "int", + "uint", "double", "string", "string list", From 947115f16fb0122acf017fe499b50f73aa43e5b0 Mon Sep 17 00:00:00 2001 From: Vivek Deshpande Date: Tue, 29 Nov 2016 17:41:08 -0800 Subject: [PATCH 090/235] 8170430: x86 pow() stub from Intel libm is inconsistent with pow() from fdlib Do not use libm stubs when InlineIntrinsics switched off Reviewed-by: kvn --- hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp | 2 +- hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp index c52be1e17cb..d32917a5ab0 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp @@ -3857,7 +3857,7 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_crc32c_table_addr = (address)StubRoutines::x86::_crc32c_table; StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul); } - if (VM_Version::supports_sse2() && UseLibmIntrinsic) { + if (VM_Version::supports_sse2() && UseLibmIntrinsic && InlineIntrinsics) { if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin) || vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos) || vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtan)) { diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp index 7ffe08b29fc..1853cf9a42a 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp @@ -5017,7 +5017,7 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_crc32c_table_addr = (address)StubRoutines::x86::_crc32c_table; StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul); } - if (VM_Version::supports_sse2() && UseLibmIntrinsic) { + if (VM_Version::supports_sse2() && UseLibmIntrinsic && InlineIntrinsics) { if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin) || vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos) || vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtan)) { From 793c6e5da72d817b7ddbcccb93d6c0d61f299954 Mon Sep 17 00:00:00 2001 From: Igor Nunes Date: Fri, 25 Nov 2016 11:15:12 -0200 Subject: [PATCH 091/235] 8170328: PPC64: Use andis instead of lis/and Reviewed-by: goetz, mdoerr --- hotspot/src/cpu/ppc/vm/ppc.ad | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/hotspot/src/cpu/ppc/vm/ppc.ad b/hotspot/src/cpu/ppc/vm/ppc.ad index 4c50b9b0448..91b5756802b 100644 --- a/hotspot/src/cpu/ppc/vm/ppc.ad +++ b/hotspot/src/cpu/ppc/vm/ppc.ad @@ -9580,6 +9580,19 @@ instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ ins_pipe(pipe_class_default); %} +// Left shifted Immediate And +instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ + match(Set dst (AndI src1 src2)); + effect(KILL cr0); + format %{ "ANDIS $dst, $src1, $src2.hi" %} + size(4); + ins_encode %{ + // TODO: PPC port $archOpcode(ppc64Opcode_andis_); + __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); + %} + ins_pipe(pipe_class_default); +%} + // Immediate And instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ match(Set dst (AndI src1 src2)); From c6705841d42f4f480e41ec5c04a79c0824ca79d8 Mon Sep 17 00:00:00 2001 From: Kirill Zhaldybin Date: Fri, 25 Nov 2016 20:53:36 +0300 Subject: [PATCH 092/235] 8168341: Gtests on JSon produce an enormous amount of hardly understandable output to stdout Reviewed-by: iignatyev, ppunegov, kvn --- hotspot/test/native/utilities/test_json.cpp | 461 ++++++++++---------- 1 file changed, 235 insertions(+), 226 deletions(-) diff --git a/hotspot/test/native/utilities/test_json.cpp b/hotspot/test/native/utilities/test_json.cpp index 758ea8a8992..e55fed6afc0 100644 --- a/hotspot/test/native/utilities/test_json.cpp +++ b/hotspot/test/native/utilities/test_json.cpp @@ -19,497 +19,506 @@ * 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 "memory/resourceArea.hpp" #include "prims/jvm.h" #include "utilities/json.hpp" #include "unittest.hpp" class JSON_GTest : public JSON { -public: - static void test(const char* json, bool valid); + public: + static void test(const char* json, bool valid); + char* get_output(); -private: - JSON_GTest(const char* text); + private: + JSON_GTest(const char* text); + stringStream output; - void log(uint level, const char* format, ...) ATTRIBUTE_PRINTF(3, 4); + void log(uint level, const char* format, ...) ATTRIBUTE_PRINTF(3, 4); - bool callback(JSON_TYPE t, JSON_VAL* v, uint level); - JSON_TYPE prev; + bool callback(JSON_TYPE t, JSON_VAL* v, uint level); + JSON_TYPE prev; }; -void JSON_GTest::test(const char* text, bool should_pass) { - JSON_GTest json(text); - if (should_pass) { - ASSERT_TRUE(json.valid()) << "failed on a valid json string"; - } else { - ASSERT_FALSE(json.valid()) << "succeeded on an invalid json string"; - } +char* JSON_GTest::get_output() { + return output.as_string(); } -JSON_GTest::JSON_GTest(const char* text) : JSON(text, false, tty) { - prev = JSON_NONE; - parse(); +void JSON_GTest::test(const char* text, bool should_pass) { + ResourceMark rm; + JSON_GTest json(text); + if (should_pass) { + ASSERT_TRUE(json.valid()) << "failed on a valid json string" + << std::endl << "debug output:" << std::endl << json.get_output(); + } else { + ASSERT_FALSE(json.valid()) << "succeeded on an invalid json string" + << std::endl << "debug output:" << std::endl << json.get_output(); + } +} + +JSON_GTest::JSON_GTest(const char* text) : JSON(text, false, &output) { + prev = JSON_NONE; + parse(); } TEST_VM(utilities, json_curly_braces) { - JSON_GTest::test("{}", true); + JSON_GTest::test("{}", true); } TEST_VM(utilities, json_brackets) { - JSON_GTest::test("[]", true); + JSON_GTest::test("[]", true); } TEST_VM(utilities, json_space_braces) { - JSON_GTest::test(" { } ", true); + JSON_GTest::test(" { } ", true); } TEST_VM(utilities, json_space_bracketes) { - JSON_GTest::test(" [ ] ", true); + JSON_GTest::test(" [ ] ", true); } TEST_VM(utilities, json_quoted_error) { - JSON_GTest::test("\"error\"", false); + JSON_GTest::test("\"error\"", false); } TEST_VM(utilities, json_error_string) { - JSON_GTest::test("error", false); + JSON_GTest::test("error", false); } TEST_VM(utilities, json_simple_integer) { - JSON_GTest::test("1", false); + JSON_GTest::test("1", false); } TEST_VM(utilities, json_siple_float) { - JSON_GTest::test("1.2", false); + JSON_GTest::test("1.2", false); } TEST_VM(utilities, json_simple_boolean_true) { - JSON_GTest::test("true", false); + JSON_GTest::test("true", false); } TEST_VM(utilities, json_simple_boolean_false) { - JSON_GTest::test("false", false); + JSON_GTest::test("false", false); } TEST_VM(utilities, json_simple_null) { - JSON_GTest::test("null", false); + JSON_GTest::test("null", false); } TEST_VM(utilities, json_one_element_int_array) { - JSON_GTest::test("[ 1 ]", true); + JSON_GTest::test("[ 1 ]", true); } TEST_VM(utilities, json_int_array) { - JSON_GTest::test("[ 1, ]", true); + JSON_GTest::test("[ 1, ]", true); } TEST_VM(utilities, json_one_element_bool_array) { - JSON_GTest::test("[ true ]", true); + JSON_GTest::test("[ true ]", true); } TEST_VM(utilities, json_bool_array) { - JSON_GTest::test("[ true, ]", true); + JSON_GTest::test("[ true, ]", true); } TEST_VM(utilities, json_one_element_false_array) { - JSON_GTest::test("[ false ]", true); + JSON_GTest::test("[ false ]", true); } TEST_VM(utilities, json_false_bool_array) { - JSON_GTest::test("[ false, ]", true); + JSON_GTest::test("[ false, ]", true); } TEST_VM(utilities, json_one_null_array) { - JSON_GTest::test("[ null ]", true); + JSON_GTest::test("[ null ]", true); } TEST_VM(utilities, json_null_array) { - JSON_GTest::test("[ null, ]", true); + JSON_GTest::test("[ null, ]", true); } TEST_VM(utilities, json_one_empty_string_array) { - JSON_GTest::test("[ \"\" ]", true); + JSON_GTest::test("[ \"\" ]", true); } TEST_VM(utilities, json_empty_string_array) { - JSON_GTest::test("[ \"\", ]", true); + JSON_GTest::test("[ \"\", ]", true); } TEST_VM(utilities, json_single_string_array) { - JSON_GTest::test("[ \"elem1\" ]", true); + JSON_GTest::test("[ \"elem1\" ]", true); } TEST_VM(utilities, json_string_comma_arrray) { - JSON_GTest::test("[ \"elem1\", ]", true); + JSON_GTest::test("[ \"elem1\", ]", true); } TEST_VM(utilities, json_two_strings_array) { - JSON_GTest::test("[ \"elem1\", \"elem2\" ]", true); + JSON_GTest::test("[ \"elem1\", \"elem2\" ]", true); } TEST_VM(utilities, json_two_strings_comma_array) { - JSON_GTest::test("[ \"elem1\", \"elem2\", ]", true); + JSON_GTest::test("[ \"elem1\", \"elem2\", ]", true); } TEST_VM(utilities, json_curly_braces_outside) { - JSON_GTest::test("[ \"elem1\" ] { }", false); + JSON_GTest::test("[ \"elem1\" ] { }", false); } TEST_VM(utilities, json_element_in_array) { - JSON_GTest::test("[ elem1, \"elem2\" ]", false); + JSON_GTest::test("[ elem1, \"elem2\" ]", false); } TEST_VM(utilities, json_incorrect_end_array) { - JSON_GTest::test("[ \"elem1\"", false); + JSON_GTest::test("[ \"elem1\"", false); } TEST_VM(utilities, json_incorrect_string_end) { - JSON_GTest::test("[ \"elem1 ]", false); + JSON_GTest::test("[ \"elem1 ]", false); } TEST_VM(utilities, json_incorrect_end_of_two_elements_array) { - JSON_GTest::test("[ \"elem1\", \"elem2\"", false); + JSON_GTest::test("[ \"elem1\", \"elem2\"", false); } TEST_VM(utilities, json_incorrect_bool_true_array) { - JSON_GTest::test("[ truefoo ]", false); + JSON_GTest::test("[ truefoo ]", false); } TEST_VM(utilities, json_incorrect_bool_false_array) { - JSON_GTest::test("[ falsefoo ]", false); + JSON_GTest::test("[ falsefoo ]", false); } TEST_VM(utilities, json_incorrect_null_array) { - JSON_GTest::test("[ nullfoo ]", false); + JSON_GTest::test("[ nullfoo ]", false); } TEST_VM(utilities, json_key_pair) { - JSON_GTest::test("{ key : 1 }", true); + JSON_GTest::test("{ key : 1 }", true); } TEST_VM(utilities, json_key_pair_comma) { - JSON_GTest::test("{ key : 1, }", true); + JSON_GTest::test("{ key : 1, }", true); } TEST_VM(utilities, json_bool_true_key) { - JSON_GTest::test("{ key : true }", true); + JSON_GTest::test("{ key : true }", true); } TEST_VM(utilities, json_bool_true_key_comma) { - JSON_GTest::test("{ key : true, }", true); + JSON_GTest::test("{ key : true, }", true); } TEST_VM(utilities, json_bool_false_key) { - JSON_GTest::test("{ key : false }", true); + JSON_GTest::test("{ key : false }", true); } TEST_VM(utilities, json_bool_false_key_comma) { - JSON_GTest::test("{ key : false, }", true); + JSON_GTest::test("{ key : false, }", true); } TEST_VM(utilities, json_null_key) { - JSON_GTest::test("{ key : null }", true); + JSON_GTest::test("{ key : null }", true); } TEST_VM(utilities, json_null_key_comma) { - JSON_GTest::test("{ key : null, }", true); + JSON_GTest::test("{ key : null, }", true); } TEST_VM(utilities, json_pair_of_empty_strings) { - JSON_GTest::test("{ \"\" : \"\" }", true); + JSON_GTest::test("{ \"\" : \"\" }", true); } TEST_VM(utilities, json_pair_of_empty_strings_comma) { - JSON_GTest::test("{ \"\" : \"\", }", true); + JSON_GTest::test("{ \"\" : \"\", }", true); } TEST_VM(utilities, json_pair_of_strings) { - JSON_GTest::test("{ \"key1\" : \"val1\" }", true); + JSON_GTest::test("{ \"key1\" : \"val1\" }", true); } TEST_VM(utilities, json_pair_of_strings_comma) { - JSON_GTest::test("{ \"key1\" : \"val1\", }", true); + JSON_GTest::test("{ \"key1\" : \"val1\", }", true); } TEST_VM(utilities, json_two_pairs_of_strings) { - JSON_GTest::test("{ \"key1\" : \"val1\", \"key2\" : \"val2\" }", true); + JSON_GTest::test("{ \"key1\" : \"val1\", \"key2\" : \"val2\" }", true); } TEST_VM(utilities, json_two_pairs_of_strings_comma) { - JSON_GTest::test("{ \"key1\" : \"val1\", \"key2\" : \"val2\", }", true); + JSON_GTest::test("{ \"key1\" : \"val1\", \"key2\" : \"val2\", }", true); } TEST_VM(utilities, json_array_outside) { - JSON_GTest::test("{ \"key\" : \"val\" } [ \"error\" ]", false); + JSON_GTest::test("{ \"key\" : \"val\" } [ \"error\" ]", false); } TEST_VM(utilities, json_incorrect_object_end) { - JSON_GTest::test("{ \"key\" : \"val\" ", false); + JSON_GTest::test("{ \"key\" : \"val\" ", false); } TEST_VM(utilities, json_empty_comment) { - JSON_GTest::test("/**/ { }", true); + JSON_GTest::test("/**/ { }", true); } TEST_VM(utilities, json_space_comment) { - JSON_GTest::test("/* */ { }", true); + JSON_GTest::test("/* */ { }", true); } TEST_VM(utilities, json_comment) { - JSON_GTest::test("/*foo*/ { }", true); + JSON_GTest::test("/*foo*/ { }", true); } TEST_VM(utilities, json_star_comment) { - JSON_GTest::test("/* *foo */ { }", true); + JSON_GTest::test("/* *foo */ { }", true); } TEST_VM(utilities, json_stars_comment) { - JSON_GTest::test("/* *foo* */ { }", true); + JSON_GTest::test("/* *foo* */ { }", true); } TEST_VM(utilities, json_special_comment) { - JSON_GTest::test("/* /*foo */ { }", true); + JSON_GTest::test("/* /*foo */ { }", true); } TEST_VM(utilities, json_comment_after) { - JSON_GTest::test("{ } /* foo */", true); + JSON_GTest::test("{ } /* foo */", true); } TEST_VM(utilities, json_comment_after_and_space) { - JSON_GTest::test("{ } /* foo */ ", true); + JSON_GTest::test("{ } /* foo */ ", true); } TEST_VM(utilities, json_one_line_empty_comment_after) { - JSON_GTest::test("{ } //", true); + JSON_GTest::test("{ } //", true); } TEST_VM(utilities, json_one_line_space_comment_after) { - JSON_GTest::test("{ } // ", true); + JSON_GTest::test("{ } // ", true); } TEST_VM(utilities, json_one_line_comment_after) { - JSON_GTest::test("{ } // foo", true); + JSON_GTest::test("{ } // foo", true); } TEST_VM(utilities, json_incorrect_multiline_comment) { - JSON_GTest::test("/* * / { }", false); + JSON_GTest::test("/* * / { }", false); } TEST_VM(utilities, json_incorrect_multiline_comment_begin) { - JSON_GTest::test("/ * */ { }", false); + JSON_GTest::test("/ * */ { }", false); } TEST_VM(utilities, json_oneline_comment_only) { - JSON_GTest::test("// { }", false); + JSON_GTest::test("// { }", false); } TEST_VM(utilities, json_multiline_comment_only) { - JSON_GTest::test("/* { } */", false); + JSON_GTest::test("/* { } */", false); } TEST_VM(utilities, json_multiline_comment_2) { - JSON_GTest::test("/* { } */ ", false); + JSON_GTest::test("/* { } */ ", false); } TEST_VM(utilities, json_incorrectly_commented_object) { - JSON_GTest::test("/* { } ", false); + JSON_GTest::test("/* { } ", false); } TEST_VM(utilities, json_missing_multiline_end) { - JSON_GTest::test("{ } /* ", false); + JSON_GTest::test("{ } /* ", false); } TEST_VM(utilities, json_missing_multiline_slash) { - JSON_GTest::test("/* { } *", false); + JSON_GTest::test("/* { } *", false); } TEST_VM(utilities, json_commented_object_end) { - JSON_GTest::test("{ /* } */", false); + JSON_GTest::test("{ /* } */", false); } TEST_VM(utilities, json_commented_array_end) { - JSON_GTest::test("[ /* ] */", false); + JSON_GTest::test("[ /* ] */", false); } TEST_VM(utilities, json_missing_object_end) { - JSON_GTest::test("{ key : \"val\", /* } */", false); + JSON_GTest::test("{ key : \"val\", /* } */", false); } TEST_VM(utilities, json_missing_array_end) { - JSON_GTest::test("[ \"val\", /* ] */", false); + JSON_GTest::test("[ \"val\", /* ] */", false); } TEST_VM(utilities, json_key_values_1) { - JSON_GTest::test("/* comment */{ key1 : { \"key2\" : { \"key3\" : [ \"elem1\", \"elem2\"," - "{ \"key4\" : null }, 3 , 2 , 1 , 0 , -1 , -2 , -3 , true, false, null, ] }, \"key5\"" - " : true }, \"key6\" : [ \"☃\" ], key7 : \"val\",}", true); + JSON_GTest::test("/* comment */{ key1 : { \"key2\" : { \"key3\" : [ \"elem1\", \"elem2\"," + "{ \"key4\" : null }, 3 , 2 , 1 , 0 , -1 , -2 , -3 , true, false, null, ] }, \"key5\"" + " : true }, \"key6\" : [ \"☃\" ], key7 : \"val\",}", true); } TEST_VM(utilities, json_key_values_2) { - JSON_GTest::test("/* comment */ { \"key1\" : { \"key2\" : { \"key3\" : [ \"elem1\", \"elem2\"," - "{ \"key4\" : null }, 3 , 2 , 1 , 0 , -1 , -2 , -3 , true, false, null, ] }, \"key5\"" - " : true }, \"key6\" : [ \"☃\" ], key7 : \"val\",}", true); + JSON_GTest::test("/* comment */ { \"key1\" : { \"key2\" : { \"key3\" : [ \"elem1\", \"elem2\"," + "{ \"key4\" : null }, 3 , 2 , 1 , 0 , -1 , -2 , -3 , true, false, null, ] }, \"key5\"" + " : true }, \"key6\" : [ \"☃\" ], key7 : \"val\",}", true); } TEST_VM(utilities, json_quoted_symbols) { - JSON_GTest::test("/*comment*/{\"ff1 fsd\":{\"☃\":{\"☃\":[\"☃\",\"☃\"]}," - "\"☃\":true},\"☃\":[\"☃\"],\"foo\":\"☃\",}", true); + JSON_GTest::test("/*comment*/{\"ff1 fsd\":{\"☃\":{\"☃\":[\"☃\",\"☃\"]}," + "\"☃\":true},\"☃\":[\"☃\"],\"foo\":\"☃\",}", true); } TEST_VM(utilities, json_incorrect_key) { - JSON_GTest::test("/* comment */ { key1 error : { \"☃\" : { \"☃\" : [ \"☃\"," - " \"☃\" ] }, \"☃\" : true }, \"baz\" : [ \"☃\" ], foo : \"☃\",}", - false); // first key needs to be quoted since it contains a space + JSON_GTest::test("/* comment */ { key1 error : { \"☃\" : { \"☃\" : [ \"☃\"," + " \"☃\" ] }, \"☃\" : true }, \"baz\" : [ \"☃\" ], foo : \"☃\",}", + false); // first key needs to be quoted since it contains a space } TEST_VM(utilities, json_array_with_newline) { - JSON_GTest::test("[\n]", true); + JSON_GTest::test("[\n]", true); } TEST_VM(utilities, json_directives_file) { - JSON_GTest::test( - "[" "\n" - " {" - " // pattern to match against class+method+signature" "\n" - " // leading and trailing wildcard (*) allowed" "\n" - " match: \"foo.bar.*\"," "\n" - " " "\n" - " // override defaults for specified compiler" "\n" - " // we may differentiate between levels too. TBD." "\n" - " c1: {" "\n" - " //override c1 presets " "\n" - " array_bounds_check_removal: false" "\n" - " }," "\n" - "" "\n" - " c2: {" "\n" - " // control inlining of method" "\n" - " // + force inline, - dont inline" "\n" - " inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n" - " }," "\n" - "" "\n" - " // directives outside a specific preset applies to all compilers" "\n" - " inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n" - " print_assembly: true," "\n" - " verify_oopmaps: true," "\n" - " max_loop_unrolling: 5" "\n" - " }," "\n" - " {" "\n" - " // matching several patterns require an array" "\n" - " match: [\"baz.*\",\"frob*\"]," "\n" - "" "\n" - " // only enable c1 for this directive" "\n" - " // all enabled by default. Command disables all not listed" "\n" - " enable: \"c1\"," "\n" - "" "\n" - " // applies to all compilers" "\n" - " // + force inline, - dont inline" "\n" - " inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n" - " print_inlining: true," "\n" - "" "\n" - " // force matching compiles to be blocking/syncronous" "\n" - " blocking_compile: true" "\n" - " }," "\n" - "]" "\n", true); + JSON_GTest::test( + "[" "\n" + " {" + " // pattern to match against class+method+signature" "\n" + " // leading and trailing wildcard (*) allowed" "\n" + " match: \"foo.bar.*\"," "\n" + " " "\n" + " // override defaults for specified compiler" "\n" + " // we may differentiate between levels too. TBD." "\n" + " c1: {" "\n" + " //override c1 presets " "\n" + " array_bounds_check_removal: false" "\n" + " }," "\n" + "" "\n" + " c2: {" "\n" + " // control inlining of method" "\n" + " // + force inline, - dont inline" "\n" + " inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n" + " }," "\n" + "" "\n" + " // directives outside a specific preset applies to all compilers" "\n" + " inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n" + " print_assembly: true," "\n" + " verify_oopmaps: true," "\n" + " max_loop_unrolling: 5" "\n" + " }," "\n" + " {" "\n" + " // matching several patterns require an array" "\n" + " match: [\"baz.*\",\"frob*\"]," "\n" + "" "\n" + " // only enable c1 for this directive" "\n" + " // all enabled by default. Command disables all not listed" "\n" + " enable: \"c1\"," "\n" + "" "\n" + " // applies to all compilers" "\n" + " // + force inline, - dont inline" "\n" + " inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n" + " print_inlining: true," "\n" + "" "\n" + " // force matching compiles to be blocking/syncronous" "\n" + " blocking_compile: true" "\n" + " }," "\n" + "]" "\n", true); } void JSON_GTest::log(uint indent, const char* format, ...) { - if (prev != JSON_KEY) { - for (uint i = 0; i < indent; i++) { - _st->print(" "); - } + if (prev != JSON_KEY) { + for (uint i = 0; i < indent; i++) { + _st->print(" "); } - va_list args; - va_start(args, format); - _st->vprint(format, args); - va_end(args); + } + va_list args; + va_start(args, format); + _st->vprint(format, args); + va_end(args); } bool JSON_GTest::callback(JSON_TYPE t, JSON_VAL* v, uint rlevel) { - switch (t) { - case JSON_OBJECT_BEGIN: - log(rlevel, "{\n"); - prev = JSON_NONE; // Only care about JSON_KEY, to indent correctly - return true; + switch (t) { + case JSON_OBJECT_BEGIN: + log(rlevel, "{\n"); + prev = JSON_NONE; // Only care about JSON_KEY, to indent correctly + return true; - case JSON_OBJECT_END: - log(rlevel, "},\n"); - prev = JSON_NONE; - return true; + case JSON_OBJECT_END: + log(rlevel, "},\n"); + prev = JSON_NONE; + return true; - case JSON_ARRAY_BEGIN: - log(rlevel, "[\n"); - prev = JSON_NONE; - return true; + case JSON_ARRAY_BEGIN: + log(rlevel, "[\n"); + prev = JSON_NONE; + return true; - case JSON_ARRAY_END: - log(rlevel, "],\n"); - prev = JSON_NONE; - return true; + case JSON_ARRAY_END: + log(rlevel, "],\n"); + prev = JSON_NONE; + return true; - case JSON_KEY: - for (uint i = 0; i < rlevel; i++) { - _st->print(" "); - } - _st->print(""); - for (size_t i = 0; i < v->str.length; i++) { - u_char c = v->str.start[i]; - if (c == 0) { - return false; - } - _st->print("%c", c); - } - _st->print(" : "); - prev = JSON_KEY; - return true; + case JSON_KEY: + for (uint i = 0; i < rlevel; i++) { + _st->print(" "); + } + _st->print(""); + for (size_t i = 0; i < v->str.length; i++) { + u_char c = v->str.start[i]; + if (c == 0) { + return false; + } + _st->print("%c", c); + } + _st->print(" : "); + prev = JSON_KEY; + return true; - case JSON_STRING: - if (prev != JSON_KEY) { - for (uint i = 0; i < rlevel; i++) { - _st->print(" "); - } - } - _st->print(""); - for (size_t i = 0; i < v->str.length; i++) { - u_char c = v->str.start[i]; - if (c == 0) { - return false; - } - _st->print("%c", c); - } - _st->print(",\n"); - prev = JSON_NONE; - return true; + case JSON_STRING: + if (prev != JSON_KEY) { + for (uint i = 0; i < rlevel; i++) { + _st->print(" "); + } + } + _st->print(""); + for (size_t i = 0; i < v->str.length; i++) { + u_char c = v->str.start[i]; + if (c == 0) { + return false; + } + _st->print("%c", c); + } + _st->print(",\n"); + prev = JSON_NONE; + return true; - case JSON_NUMBER_INT: - log(rlevel, "%" PRId64 ",\n", v->int_value); - prev = JSON_NONE; - return true; + case JSON_NUMBER_INT: + log(rlevel, "%" PRId64 ",\n", v->int_value); + prev = JSON_NONE; + return true; - case JSON_NUMBER_FLOAT: - log(rlevel, "%lf,\n", v->double_value); - prev = JSON_NONE; - return true; + case JSON_NUMBER_FLOAT: + log(rlevel, "%lf,\n", v->double_value); + prev = JSON_NONE; + return true; - case JSON_TRUE: - log(rlevel, ",\n"); - prev = JSON_NONE; - return true; + case JSON_TRUE: + log(rlevel, ",\n"); + prev = JSON_NONE; + return true; - case JSON_FALSE: - log(rlevel, ",\n"); - prev = JSON_NONE; - return true; + case JSON_FALSE: + log(rlevel, ",\n"); + prev = JSON_NONE; + return true; - case JSON_NULL: - log(rlevel, ",\n"); - prev = JSON_NONE; - return true; + case JSON_NULL: + log(rlevel, ",\n"); + prev = JSON_NONE; + return true; - default: - error(INTERNAL_ERROR, "unknown JSON type"); - return false; - } + default: + error(INTERNAL_ERROR, "unknown JSON type"); + return false; + } } From 893ec916559516ffe8b5dd139463c77a00b74bf8 Mon Sep 17 00:00:00 2001 From: Semyon Sadetsky Date: Mon, 28 Nov 2016 10:36:40 +0300 Subject: [PATCH 093/235] 8168135: The issue JDK-8164462 seems not fixed in b140 Reviewed-by: serb --- .../unix/classes/sun/awt/X11/XContentWindow.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XContentWindow.java b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XContentWindow.java index 85e578b4052..74444b8d2d6 100644 --- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XContentWindow.java +++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XContentWindow.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -123,15 +123,26 @@ public final class XContentWindow extends XWindow { // Change in the size of the content window means, well, change of the size // Change in the location of the content window means change in insets boolean needHandleResize = !(newBounds.equals(getBounds())); + boolean needPaint = width <= 0 || height <= 0; reshape(newBounds); if (needHandleResize) { insLog.fine("Sending RESIZED"); handleResize(newBounds); } + if (needPaint) { + postPaintEvent(target, 0, 0, newBounds.width, newBounds.height); + } } finally { XToolkit.awtUnlock(); } - validateSurface(); + } + + @Override + public void handleExposeEvent(XEvent xev) { + if (width <= 0 || height <= 0) { + return; + } + super.handleExposeEvent(xev); } // NOTE: This method may be called by privileged threads. From 547092cf8d16d7045f651c8008ce7a778b20a5e4 Mon Sep 17 00:00:00 2001 From: Maksim Khramov Date: Mon, 28 Nov 2016 14:36:46 +0300 Subject: [PATCH 094/235] 8167284: [TESTBUG] [PIT] possible regression: javax/swing/JRadioButton/FocusTraversal/FocusTraversal.java Reviewed-by: ssadetsky, yan --- .../FocusTraversal/FocusTraversal.java | 43 +++++-------------- 1 file changed, 10 insertions(+), 33 deletions(-) diff --git a/jdk/test/javax/swing/JRadioButton/FocusTraversal/FocusTraversal.java b/jdk/test/javax/swing/JRadioButton/FocusTraversal/FocusTraversal.java index 4c773c0f7b1..9ab19f7b245 100644 --- a/jdk/test/javax/swing/JRadioButton/FocusTraversal/FocusTraversal.java +++ b/jdk/test/javax/swing/JRadioButton/FocusTraversal/FocusTraversal.java @@ -42,7 +42,6 @@ import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JTextField; import javax.swing.KeyStroke; -import javax.swing.LookAndFeel; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; @@ -133,41 +132,19 @@ public class FocusTraversal { } private static void runTestCase() throws Exception { - LookAndFeel lookAndFeel = UIManager.getLookAndFeel(); focusOn(a); - if (isExcludedLookAndFeel(lookAndFeel)) { - robot.keyPress(KeyEvent.VK_ENTER); - robot.keyRelease(KeyEvent.VK_ENTER); - robot.waitForIdle(); - isFocusOwner(b, "forward"); - robot.keyPress(KeyEvent.VK_SHIFT); - robot.keyPress(KeyEvent.VK_TAB); - robot.keyRelease(KeyEvent.VK_TAB); - robot.keyRelease(KeyEvent.VK_SHIFT); - robot.waitForIdle(); - isFocusOwner(a, "backward"); - } else { + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + robot.waitForIdle(); + isFocusOwner(next, "forward"); + robot.keyPress(KeyEvent.VK_SHIFT); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_SHIFT); + robot.waitForIdle(); + isFocusOwner(a, "backward"); - robot.keyPress(KeyEvent.VK_ENTER); - robot.keyRelease(KeyEvent.VK_ENTER); - robot.waitForIdle(); - isFocusOwner(next, "forward"); - robot.keyPress(KeyEvent.VK_SHIFT); - robot.keyPress(KeyEvent.VK_TAB); - robot.keyRelease(KeyEvent.VK_TAB); - robot.keyRelease(KeyEvent.VK_SHIFT); - robot.waitForIdle(); - isFocusOwner(d, "backward"); - } - - } - - private static boolean isExcludedLookAndFeel(LookAndFeel lookAndFeel) { - - return lookAndFeel.toString().toLowerCase().contains("aqua") - || lookAndFeel.toString().toLowerCase().contains("nimbus") - || lookAndFeel.toString().toLowerCase().contains("gtk"); } private static void focusOn(Component component) From cc87ed96f5b76d675af4c041451b463baf61de03 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Mon, 28 Nov 2016 14:57:12 +0100 Subject: [PATCH 095/235] 8170388: Deprecate the flag -XX:ExplicitGCInvokesConcurrentAndUnloadsClasses Reviewed-by: tschatzl, jprovino --- hotspot/src/share/vm/runtime/arguments.cpp | 1 + ...tGCInvokesConcurrentAndUnloadsClasses.java | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 hotspot/test/gc/arguments/TestExplicitGCInvokesConcurrentAndUnloadsClasses.java diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 4ba3ec45004..485ecadd31b 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -375,6 +375,7 @@ static SpecialFlag const special_jvm_flags[] = { { "AutoGCSelectPauseMillis", JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::jdk(10) }, { "UseAutoGCSelectPolicy", JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::jdk(10) }, { "UseParNewGC", JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::jdk(10) }, + { "ExplicitGCInvokesConcurrentAndUnloadsClasses", JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::jdk(10) }, { "ConvertSleepToYield", JDK_Version::jdk(9), JDK_Version::jdk(10), JDK_Version::jdk(11) }, { "ConvertYieldToSleep", JDK_Version::jdk(9), JDK_Version::jdk(10), JDK_Version::jdk(11) }, diff --git a/hotspot/test/gc/arguments/TestExplicitGCInvokesConcurrentAndUnloadsClasses.java b/hotspot/test/gc/arguments/TestExplicitGCInvokesConcurrentAndUnloadsClasses.java new file mode 100644 index 00000000000..83f075760d6 --- /dev/null +++ b/hotspot/test/gc/arguments/TestExplicitGCInvokesConcurrentAndUnloadsClasses.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016, 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 TestExplicitGCInvokesConcurrentAndUnloadsClasses + * @summary Test that the flag ExplicitGCInvokesConcurrentAndUnloadsClasses is deprecated + * @bug 8170388 + * @key gc + * @library /test/lib + * @modules java.base/jdk.internal.misc + * java.management + * @run driver TestExplicitGCInvokesConcurrentAndUnloadsClasses + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class TestExplicitGCInvokesConcurrentAndUnloadsClasses { + public static void main(String[] args) throws Exception { + ProcessBuilder pb = + ProcessTools.createJavaProcessBuilder("-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses", + "-Xlog:gc", + "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("ExplicitGCInvokesConcurrentAndUnloadsClasses was deprecated"); + output.shouldHaveExitValue(0); + } +} From 1ac940c263c5b33c2b0cd5cb17c8aece32fc687f Mon Sep 17 00:00:00 2001 From: Phil Race Date: Tue, 29 Nov 2016 09:54:16 -0800 Subject: [PATCH 096/235] 8167103: Intermittent font loading failure on macOS with JFXPanel application Reviewed-by: serb, psadhukhan --- .../macosx/classes/sun/font/CFontManager.java | 18 +++++++++++++--- .../macosx/native/libawt_lwawt/font/AWTFont.m | 21 +++++++------------ 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java b/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java index 0c505b28576..45f48328717 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java +++ b/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java @@ -141,12 +141,24 @@ public final class CFontManager extends SunFontManager { } } - protected void registerFontsInDir(String dirName, boolean useJavaRasterizer, int fontRank, boolean defer, boolean resolveSymLinks) { - loadNativeDirFonts(dirName); + protected void registerFontsInDir(final String dirName, boolean useJavaRasterizer, + int fontRank, boolean defer, boolean resolveSymLinks) { + + String[] files = AccessController.doPrivileged((PrivilegedAction) () -> { + return new File(dirName).list(getTrueTypeFilter()); + }); + + if (files == null) { + return; + } else { + for (String f : files) { + loadNativeDirFonts(dirName+File.separator+f); + } + } super.registerFontsInDir(dirName, useJavaRasterizer, fontRank, defer, resolveSymLinks); } - private native void loadNativeDirFonts(String dirName); + private native void loadNativeDirFonts(String fontPath); private native void loadNativeFonts(); void registerFont(String fontName, String fontFamilyName) { diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m b/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m index d374e5a1241..bca21021347 100644 --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m @@ -404,19 +404,14 @@ Java_sun_font_CFontManager_loadNativeDirFonts { JNF_COCOA_ENTER(env); - NSString *nsFilePath = JNFJavaToNSString(env, filename); - - FSRef iFile; - OSStatus status = CreateFSRef(&iFile, nsFilePath); - - if (status == noErr) { - ATSFontContainerRef oContainer; - status = ATSFontActivateFromFileReference(&iFile, kATSFontContextLocal, - kATSFontFormatUnspecified, - NULL, kNilOptions, - &oContainer); - } - + NSString *path = JNFJavaToNSString(env, filename); + NSURL *url = [NSURL fileURLWithPath:(NSString *)path]; + bool res = CTFontManagerRegisterFontsForURL((CFURLRef)url, kCTFontManagerScopeProcess, nil); +#ifdef DEBUG + NSLog(@"path is : %@", (NSString*)path); + NSLog(@"url is : %@", (NSString*)url); + printf("res is %d\n", res); +#endif JNF_COCOA_EXIT(env); } From 0043906c46a3b4ced203f2053c94b456b3d4d34d Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Tue, 29 Nov 2016 15:20:30 -0800 Subject: [PATCH 097/235] 8170428: Move src.zip to JDK/lib/src.zip Reviewed-by: prr, billyh, pbhat --- make/Images.gmk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/make/Images.gmk b/make/Images.gmk index 47fcd8f3323..a20b930c249 100644 --- a/make/Images.gmk +++ b/make/Images.gmk @@ -354,11 +354,11 @@ JDK_TARGETS += $(JDK_DOC_TARGETS) ################################################################################ # src.zip -$(JDK_IMAGE_DIR)/src.zip: $(SUPPORT_OUTPUTDIR)/src.zip +$(JDK_IMAGE_DIR)/lib/src.zip: $(SUPPORT_OUTPUTDIR)/src.zip $(call LogInfo, Copying $(patsubst $(OUTPUT_ROOT)/%,%,$@)) $(install-file) -JDK_TARGETS += $(JDK_IMAGE_DIR)/src.zip +JDK_TARGETS += $(JDK_IMAGE_DIR)/lib/src.zip ################################################################################ # /demo dir From 1d0671e8dc428eb08d02d7d8572cd31e237ccfee Mon Sep 17 00:00:00 2001 From: Semyon Sadetsky Date: Wed, 30 Nov 2016 10:47:57 +0300 Subject: [PATCH 098/235] 8160087: Change IOOBE to warning in the scenarios when it had not being thrown before the JDK-8078514 Reviewed-by: azvegint, alexsch --- .../classes/javax/swing/DefaultRowSorter.java | 31 +++-- .../DefaultRowSorterIOOBEtest.java | 119 ++++++++++++++++++ 2 files changed, 142 insertions(+), 8 deletions(-) create mode 100644 jdk/test/javax/swing/JTable/SorterIOOBEtest/DefaultRowSorterIOOBEtest.java diff --git a/jdk/src/java.desktop/share/classes/javax/swing/DefaultRowSorter.java b/jdk/src/java.desktop/share/classes/javax/swing/DefaultRowSorter.java index 5bc2f0687a9..542e1cb3c16 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/DefaultRowSorter.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/DefaultRowSorter.java @@ -182,6 +182,8 @@ public abstract class DefaultRowSorter extends RowSorter { */ private int modelRowCount; + // Whether to print warning about JDK-8160087 + private static boolean warning8160087 = true; /** * Creates an empty DefaultRowSorter. @@ -489,10 +491,7 @@ public abstract class DefaultRowSorter extends RowSorter { */ public int convertRowIndexToView(int index) { if (modelToView == null) { - if (index < 0 || index >= modelRowCount) { - throw new IndexOutOfBoundsException("Invalid index"); - } - return index; + return convertUnsortedUnfiltered(index); } return modelToView[index]; } @@ -504,14 +503,30 @@ public abstract class DefaultRowSorter extends RowSorter { */ public int convertRowIndexToModel(int index) { if (viewToModel == null) { - if (index < 0 || index >= modelRowCount) { - throw new IndexOutOfBoundsException("Invalid index"); - } - return index; + return convertUnsortedUnfiltered(index); } return viewToModel[index].modelIndex; } + private int convertUnsortedUnfiltered(int index) { + if (index < 0 || index >= modelRowCount) { + if(index >= modelRowCount && + index < getModelWrapper().getRowCount()) { + // 8160087 + if(warning8160087) { + warning8160087 = false; + System.err.println("WARNING: row index is bigger than " + + "sorter's row count. Most likely this is a wrong " + + "sorter usage."); + } + } else { + throw new IndexOutOfBoundsException("Invalid index"); + } + } + return index; + } + + private boolean isUnsorted() { List keys = getSortKeys(); int keySize = keys.size(); diff --git a/jdk/test/javax/swing/JTable/SorterIOOBEtest/DefaultRowSorterIOOBEtest.java b/jdk/test/javax/swing/JTable/SorterIOOBEtest/DefaultRowSorterIOOBEtest.java new file mode 100644 index 00000000000..fec08479521 --- /dev/null +++ b/jdk/test/javax/swing/JTable/SorterIOOBEtest/DefaultRowSorterIOOBEtest.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2016, 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 8160087 + * @summary Change IOOBE to warning in the scenarios when it had not being + * thrown before the JDK-8078514 + * @run main/othervm DefaultRowSorterIOOBEtest + */ + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableModel; +import javax.swing.table.TableRowSorter; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +public class DefaultRowSorterIOOBEtest extends TableRowSorter { + static List rows = new ArrayList<>(); + + static TableModel tableModel = new AbstractTableModel() { + + @Override + public int getRowCount() { + return rows.size(); + } + + @Override + public int getColumnCount() { + return 1; + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + return rows.get(rowIndex); + } + }; + + public static void main(String[] args) { + DefaultRowSorter sorter = + new DefaultRowSorter<>() { + { + setModelWrapper(new SorterModelWrapper()); + } + }; + + PrintStream err = System.err; + ByteArrayOutputStream bos = new ByteArrayOutputStream(10000) { + @Override + public synchronized void write(byte[] b, int off, int len) { + super.write(b, off, len); + err.print(new String(b, off, len)); + } + }; + System.setErr(new PrintStream(bos)); + + rows.add("New"); + + sorter.convertRowIndexToView(0); + sorter.convertRowIndexToModel(0); + + String out = new String(bos.toByteArray()); + if(out.indexOf("WARNING:") < 0) { + throw new RuntimeException("No warnings found"); + } + } + + static class SorterModelWrapper extends + DefaultRowSorter.ModelWrapper { + + @Override + public TableModel getModel() { + return tableModel; + } + + @Override + public int getColumnCount() { + return tableModel.getColumnCount(); + } + + @Override + public int getRowCount() { + return tableModel.getRowCount(); + } + + @Override + public Object getValueAt(int row, int column) { + return tableModel.getValueAt(row, column); + } + + @Override + public Integer getIdentifier(int row) { + return row; + } + } +} From 96be8c0cc8c5f118ce4048df2943292c7817f237 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Wed, 30 Nov 2016 12:07:17 -0800 Subject: [PATCH 099/235] 8170470: superword may miss reductions Reviewed-by: kvn --- hotspot/src/share/vm/opto/loopTransform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/opto/loopTransform.cpp b/hotspot/src/share/vm/opto/loopTransform.cpp index b9368b42dff..d35d71aebd4 100644 --- a/hotspot/src/share/vm/opto/loopTransform.cpp +++ b/hotspot/src/share/vm/opto/loopTransform.cpp @@ -1742,7 +1742,7 @@ void PhaseIdealLoop::mark_reductions(IdealLoopTree *loop) { // The result of the reduction must not be used in the loop for (DUIterator_Fast imax, i = def_node->fast_outs(imax); i < imax && ok; i++) { Node* u = def_node->fast_out(i); - if (has_ctrl(u) && !loop->is_member(get_loop(get_ctrl(u)))) { + if (!loop->is_member(get_loop(ctrl_or_self(u)))) { continue; } if (u == phi) { From b1fd8970438f2b926da6ae9aa37d9d2f6db41542 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Thu, 1 Dec 2016 10:51:36 +0530 Subject: [PATCH 100/235] 7190578: Nimbus: css test for 4936917 fails Reviewed-by: serb, aghaisas --- .../text/html/StyleSheet/bug4936917.java | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 jdk/test/javax/swing/text/html/StyleSheet/bug4936917.java diff --git a/jdk/test/javax/swing/text/html/StyleSheet/bug4936917.java b/jdk/test/javax/swing/text/html/StyleSheet/bug4936917.java new file mode 100644 index 00000000000..10fe6e867bc --- /dev/null +++ b/jdk/test/javax/swing/text/html/StyleSheet/bug4936917.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2016, 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 4936917 7190578 + @summary Tests if background is correctly painted when has css margins + @author Denis Sharypov + @library ../../../regtesthelpers + @run main bug4936917 +*/ + + + +import java.awt.Color; +import java.awt.Point; +import java.awt.Robot; +import java.util.Timer; +import javax.swing.JComponent; +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + + +public class bug4936917 { + + private boolean passed = false; + private Timer timer; + private JEditorPane editorPane; + private static JFrame f; + private volatile Point p = null; + + private String text = + "" + + " some text "; + + public void init() throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + editorPane = new JEditorPane("text/html", ""); + editorPane.setEditable(false); + editorPane.setMargin(new java.awt.Insets(0, 0, 0, 0)); + editorPane.setText(text); + + f = new JFrame(); + f.getContentPane().add(editorPane); + f.setSize(600, 400); + f.setVisible(true); + } + }); + blockTillDisplayed(editorPane); + Robot robot = new Robot(); + robot.waitForIdle(); + + int x0 = p.x + 15 ; + int y = p.y + 15; + int match = 0; + int nonmatch = 0; + + passed = true; + for (int x = x0; x < x0 + 10; x++) { + System.out.println("color ("+x+"," + y +")=" + robot.getPixelColor(x,y)); + if (!robot.getPixelColor(x, y).equals(new Color(0xcc, 0xcc, 0xcc))) { + nonmatch++; + } else match++; + } + if (nonmatch > match) { + passed = false; + } + } + + void blockTillDisplayed(JComponent comp) throws Exception { + while (p == null) { + try { + SwingUtilities.invokeAndWait(() -> { + p = comp.getLocationOnScreen(); + }); + } catch (IllegalStateException e) { + try { + Thread.sleep(1000); + } catch (InterruptedException ie) { + } + } + } + } + + public void destroy() throws Exception { + SwingUtilities.invokeAndWait(()->f.dispose()); + if(!passed) { + throw new RuntimeException("Test failed."); + } + } + + + public static void main(String args[]) throws Exception { + bug4936917 test = new bug4936917(); + test.init(); + test.destroy(); + } +} From 78e6980e1a971bd1de53bbce576dfc944ae51733 Mon Sep 17 00:00:00 2001 From: Gunter Haug Date: Fri, 2 Dec 2016 11:07:27 +0100 Subject: [PATCH 101/235] 8170409: CMS: Crash in CardTableModRefBSForCTRS::process_chunk_boundaries Reviewed-by: simonis, tschatzl, mgerdin, dlong --- hotspot/src/share/vm/gc/cms/parCardTableModRefBS.cpp | 11 ++++++++--- .../share/vm/gc/shared/cardTableModRefBSForCTRS.hpp | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/gc/cms/parCardTableModRefBS.cpp b/hotspot/src/share/vm/gc/cms/parCardTableModRefBS.cpp index ccb513d097d..4456fe6fc7d 100644 --- a/hotspot/src/share/vm/gc/cms/parCardTableModRefBS.cpp +++ b/hotspot/src/share/vm/gc/cms/parCardTableModRefBS.cpp @@ -395,9 +395,13 @@ get_LNC_array_for_space(Space* sp, // event lock and do the read again in case some other thread had already // succeeded and done the resize. int cur_collection = GenCollectedHeap::heap()->total_collections(); - if (_last_LNC_resizing_collection[i] != cur_collection) { + // Updated _last_LNC_resizing_collection[i] must not be visible before + // _lowest_non_clean and friends are visible. Therefore use acquire/release + // to guarantee this on non TSO architecures. + if (OrderAccess::load_acquire(&_last_LNC_resizing_collection[i]) != cur_collection) { MutexLocker x(ParGCRareEvent_lock); - if (_last_LNC_resizing_collection[i] != cur_collection) { + // This load_acquire is here for clarity only. The MutexLocker already fences. + if (OrderAccess::load_acquire(&_last_LNC_resizing_collection[i]) != cur_collection) { if (_lowest_non_clean[i] == NULL || n_chunks != _lowest_non_clean_chunk_size[i]) { @@ -417,7 +421,8 @@ get_LNC_array_for_space(Space* sp, _lowest_non_clean[i][j] = NULL; } } - _last_LNC_resizing_collection[i] = cur_collection; + // Make sure this gets visible only after _lowest_non_clean* was initialized + OrderAccess::release_store(&_last_LNC_resizing_collection[i], cur_collection); } } // In any case, now do the initialization. diff --git a/hotspot/src/share/vm/gc/shared/cardTableModRefBSForCTRS.hpp b/hotspot/src/share/vm/gc/shared/cardTableModRefBSForCTRS.hpp index abf6ee0dc18..8da81104ba9 100644 --- a/hotspot/src/share/vm/gc/shared/cardTableModRefBSForCTRS.hpp +++ b/hotspot/src/share/vm/gc/shared/cardTableModRefBSForCTRS.hpp @@ -85,7 +85,7 @@ private: CardArr* _lowest_non_clean; size_t* _lowest_non_clean_chunk_size; uintptr_t* _lowest_non_clean_base_chunk_index; - int* _last_LNC_resizing_collection; + volatile int* _last_LNC_resizing_collection; // Initializes "lowest_non_clean" to point to the array for the region // covering "sp", and "lowest_non_clean_base_chunk_index" to the chunk From 83ff43e7372bef4120ab92c40df3e0a3e2f1308f Mon Sep 17 00:00:00 2001 From: Rachel Protacio Date: Mon, 5 Dec 2016 11:45:20 -0500 Subject: [PATCH 102/235] 8168850: Mark module entries that have been specified by --patch-module Adds a boolean to ModuleEntry to specify whether the module has been patched using the command line --patch-module Reviewed-by: jiangli, lfoltan, dholmes --- .../src/share/vm/classfile/classLoader.cpp | 22 ++++++++++++++++--- .../src/share/vm/classfile/classLoader.hpp | 2 ++ .../src/share/vm/classfile/moduleEntry.cpp | 8 +++++++ .../src/share/vm/classfile/moduleEntry.hpp | 9 ++++++++ hotspot/src/share/vm/logging/logTag.hpp | 1 + 5 files changed, 39 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classLoader.cpp b/hotspot/src/share/vm/classfile/classLoader.cpp index a7e2222fe4d..88b00362d06 100644 --- a/hotspot/src/share/vm/classfile/classLoader.cpp +++ b/hotspot/src/share/vm/classfile/classLoader.cpp @@ -751,6 +751,21 @@ void ClassLoader::setup_patch_mod_entries() { } } +// Determine whether the module has been patched via the command-line +// option --patch-module +bool ClassLoader::is_in_patch_mod_entries(Symbol* module_name) { + if (_patch_mod_entries != NULL && _patch_mod_entries->is_nonempty()) { + int table_len = _patch_mod_entries->length(); + for (int i = 0; i < table_len; i++) { + ModuleClassPathList* patch_mod = _patch_mod_entries->at(i); + if (module_name->fast_compare(patch_mod->module_name()) == 0) { + return true; + } + } + } + return false; +} + void ClassLoader::setup_search_path(const char *class_path, bool bootstrap_search) { int len = (int)strlen(class_path); int end = 0; @@ -1764,9 +1779,6 @@ void classLoader_init1() { // Complete the ClassPathEntry setup for the boot loader void ClassLoader::classLoader_init2(TRAPS) { - // Create the moduleEntry for java.base - create_javabase(); - // Setup the list of module/path pairs for --patch-module processing // This must be done after the SymbolTable is created in order // to use fast_compare on module names instead of a string compare. @@ -1774,6 +1786,10 @@ void ClassLoader::classLoader_init2(TRAPS) { setup_patch_mod_entries(); } + // Create the ModuleEntry for java.base (must occur after setup_patch_mod_entries + // to successfully determine if java.base has been patched) + create_javabase(); + // Setup the initial java.base/path pair for the exploded build entries. // As more modules are defined during module system initialization, more // entries will be added to the exploded build array. diff --git a/hotspot/src/share/vm/classfile/classLoader.hpp b/hotspot/src/share/vm/classfile/classLoader.hpp index 1bdbd7025b8..b7f494ce178 100644 --- a/hotspot/src/share/vm/classfile/classLoader.hpp +++ b/hotspot/src/share/vm/classfile/classLoader.hpp @@ -418,6 +418,8 @@ class ClassLoader: AllStatic { } } + static bool is_in_patch_mod_entries(Symbol* module_name); + #if INCLUDE_CDS // Sharing dump and restore diff --git a/hotspot/src/share/vm/classfile/moduleEntry.cpp b/hotspot/src/share/vm/classfile/moduleEntry.cpp index 42f79db8dc5..f9c8d5977fc 100644 --- a/hotspot/src/share/vm/classfile/moduleEntry.cpp +++ b/hotspot/src/share/vm/classfile/moduleEntry.cpp @@ -301,6 +301,14 @@ ModuleEntry* ModuleEntryTable::new_entry(unsigned int hash, Handle module_handle entry->set_version(version); entry->set_location(location); + if (ClassLoader::is_in_patch_mod_entries(name)) { + entry->set_is_patched(); + if (log_is_enabled(Trace, modules, patch)) { + ResourceMark rm; + log_trace(modules, patch)("Marked module %s as patched from --patch-module", name->as_C_string()); + } + } + TRACE_INIT_MODULE_ID(entry); return entry; diff --git a/hotspot/src/share/vm/classfile/moduleEntry.hpp b/hotspot/src/share/vm/classfile/moduleEntry.hpp index cffc672a7f2..fa5d1cd3712 100644 --- a/hotspot/src/share/vm/classfile/moduleEntry.hpp +++ b/hotspot/src/share/vm/classfile/moduleEntry.hpp @@ -63,6 +63,7 @@ private: bool _can_read_all_unnamed; bool _has_default_read_edges; // JVMTI redefine/retransform support bool _must_walk_reads; // walk module's reads list at GC safepoints to purge out dead modules + bool _is_patched; // whether the module is patched via --patch-module TRACE_DEFINE_TRACE_ID_FIELD; enum {MODULE_READS_SIZE = 101}; // Initial size of list of modules that the module can read. @@ -77,6 +78,7 @@ public: _can_read_all_unnamed = false; _has_default_read_edges = false; _must_walk_reads = false; + _is_patched = false; } Symbol* name() const { return literal(); } @@ -131,6 +133,13 @@ public: return prev; } + void set_is_patched() { + _is_patched = true; + } + bool is_patched() { + return _is_patched; + } + ModuleEntry* next() const { return (ModuleEntry*)HashtableEntry::next(); } diff --git a/hotspot/src/share/vm/logging/logTag.hpp b/hotspot/src/share/vm/logging/logTag.hpp index 90638b41b38..5b9e03ba228 100644 --- a/hotspot/src/share/vm/logging/logTag.hpp +++ b/hotspot/src/share/vm/logging/logTag.hpp @@ -90,6 +90,7 @@ LOG_TAG(oopmap) \ LOG_TAG(os) \ LOG_TAG(pagesize) \ + LOG_TAG(patch) \ LOG_TAG(path) \ LOG_TAG(phases) \ LOG_TAG(plab) \ From 6d271f4386a675f237ca13c79020c2d1206bd399 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Mon, 5 Dec 2016 17:57:43 +0100 Subject: [PATCH 103/235] 8066474: Remove the lib/ directory from Linux and Solaris images Reviewed-by: tbell, ihse, kvn --- hotspot/make/hotspot.script | 5 +-- hotspot/src/os/aix/vm/os_aix.cpp | 6 +-- hotspot/src/os/linux/vm/os_linux.cpp | 21 ++++------ hotspot/src/os/solaris/vm/os_solaris.cpp | 39 +++---------------- hotspot/test/Makefile | 7 +--- .../test/runtime/StackGuardPages/testme.sh | 2 +- .../ThreadSignalMask/exeThreadSignalMask.c | 4 +- 7 files changed, 20 insertions(+), 64 deletions(-) diff --git a/hotspot/make/hotspot.script b/hotspot/make/hotspot.script index 942eafa39d7..13fc625376a 100644 --- a/hotspot/make/hotspot.script +++ b/hotspot/make/hotspot.script @@ -124,15 +124,14 @@ fi # We will set the LD_LIBRARY_PATH as follows: # o $JVMPATH (directory portion only) -# o $JRE/lib/$ARCH +# o $JRE/lib # followed by the user's previous effective LD_LIBRARY_PATH, if # any. JRE=$JDK JAVA_HOME=$JDK export JAVA_HOME -ARCH=@@LIBARCH@@ -SBP=${MYDIR}:${JRE}/lib/${ARCH} +SBP=${MYDIR}:${JRE}/lib # Set up a suitable LD_LIBRARY_PATH or DYLD_LIBRARY_PATH diff --git a/hotspot/src/os/aix/vm/os_aix.cpp b/hotspot/src/os/aix/vm/os_aix.cpp index a87885e2273..f2a3b69c79a 100644 --- a/hotspot/src/os/aix/vm/os_aix.cpp +++ b/hotspot/src/os/aix/vm/os_aix.cpp @@ -547,11 +547,7 @@ void os::init_system_properties_values() { if (pslash != NULL) { pslash = strrchr(buf, '/'); if (pslash != NULL) { - *pslash = '\0'; // Get rid of /. - pslash = strrchr(buf, '/'); - if (pslash != NULL) { - *pslash = '\0'; // Get rid of /lib. - } + *pslash = '\0'; // Get rid of /lib. } } Arguments::set_java_home(buf); diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index a59f52041e9..3b6122ffc0d 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -218,9 +218,6 @@ bool os::have_special_privileges() { #endif #endif -// Cpu architecture string -static char cpu_arch[] = HOTSPOT_LIB_ARCH; - // pid_t gettid() // @@ -263,7 +260,7 @@ void os::init_system_properties_values() { // // Obtain the JAVA_HOME value from the location of libjvm.so. // This library should be located at: - // /jre/lib//{client|server}/libjvm.so. + // /lib/{client|server}/libjvm.so. // // If "/jre/lib/" appears at the right place in the path, then we // assume libjvm.so is installed in a JDK and we use this path. @@ -329,11 +326,7 @@ void os::init_system_properties_values() { if (pslash != NULL) { pslash = strrchr(buf, '/'); if (pslash != NULL) { - *pslash = '\0'; // Get rid of /. - pslash = strrchr(buf, '/'); - if (pslash != NULL) { - *pslash = '\0'; // Get rid of /lib. - } + *pslash = '\0'; // Get rid of /lib. } } Arguments::set_java_home(buf); @@ -360,9 +353,9 @@ void os::init_system_properties_values() { // That's +1 for the colon and +1 for the trailing '\0'. char *ld_library_path = (char *)NEW_C_HEAP_ARRAY(char, strlen(v) + 1 + - sizeof(SYS_EXT_DIR) + sizeof("/lib/") + strlen(cpu_arch) + sizeof(DEFAULT_LIBPATH) + 1, + sizeof(SYS_EXT_DIR) + sizeof("/lib/") + sizeof(DEFAULT_LIBPATH) + 1, mtInternal); - sprintf(ld_library_path, "%s%s" SYS_EXT_DIR "/lib/%s:" DEFAULT_LIBPATH, v, v_colon, cpu_arch); + sprintf(ld_library_path, "%s%s" SYS_EXT_DIR "/lib:" DEFAULT_LIBPATH, v, v_colon); Arguments::set_library_path(ld_library_path); FREE_C_HEAP_ARRAY(char, ld_library_path); } @@ -2310,7 +2303,7 @@ void os::jvm_path(char *buf, jint buflen) { if (Arguments::sun_java_launcher_is_altjvm()) { // Support for the java launcher's '-XXaltjvm=' option. Typical - // value for buf is "/jre/lib///libjvm.so". + // value for buf is "/jre/lib//libjvm.so". // If "/jre/lib/" appears at the right place in the string, then // assume we are installed in a JDK and we're done. Otherwise, check // for a JAVA_HOME environment variable and fix up the path so it @@ -2346,9 +2339,9 @@ void os::jvm_path(char *buf, jint buflen) { len = strlen(buf); assert(len < buflen, "Ran out of buffer room"); jrelib_p = buf + len; - snprintf(jrelib_p, buflen-len, "/jre/lib/%s", cpu_arch); + snprintf(jrelib_p, buflen-len, "/jre/lib"); if (0 != access(buf, F_OK)) { - snprintf(jrelib_p, buflen-len, "/lib/%s", cpu_arch); + snprintf(jrelib_p, buflen-len, "/lib"); } if (0 == access(buf, F_OK)) { diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index 1c1182388f3..527246dcc3d 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -534,13 +534,12 @@ void os::init_system_properties_values() { #define SYS_EXT_DIR "/usr/jdk/packages" #define EXTENSIONS_DIR "/lib/ext" - char cpu_arch[12]; // Buffer that fits several sprintfs. // Note that the space for the colon and the trailing null are provided // by the nulls included by the sizeof operator. const size_t bufsize = MAX3((size_t)MAXPATHLEN, // For dll_dir & friends. - sizeof(SYS_EXT_DIR) + sizeof("/lib/") + strlen(cpu_arch), // invariant ld_library_path + sizeof(SYS_EXT_DIR) + sizeof("/lib/"), // invariant ld_library_path (size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR) + sizeof(SYS_EXT_DIR) + sizeof(EXTENSIONS_DIR)); // extensions dir char *buf = (char *)NEW_C_HEAP_ARRAY(char, bufsize, mtInternal); @@ -561,11 +560,7 @@ void os::init_system_properties_values() { if (pslash != NULL) { pslash = strrchr(buf, '/'); if (pslash != NULL) { - *pslash = '\0'; // Get rid of /. - pslash = strrchr(buf, '/'); - if (pslash != NULL) { - *pslash = '\0'; // Get rid of /lib. - } + *pslash = '\0'; // Get rid of /lib. } } Arguments::set_java_home(buf); @@ -623,21 +618,8 @@ void os::init_system_properties_values() { // However, to prevent the proliferation of improperly built native // libraries, the new path component /usr/jdk/packages is added here. - // Determine the actual CPU architecture. - sysinfo(SI_ARCHITECTURE, cpu_arch, sizeof(cpu_arch)); -#ifdef _LP64 - // If we are a 64-bit vm, perform the following translations: - // sparc -> sparcv9 - // i386 -> amd64 - if (strcmp(cpu_arch, "sparc") == 0) { - strcat(cpu_arch, "v9"); - } else if (strcmp(cpu_arch, "i386") == 0) { - strcpy(cpu_arch, "amd64"); - } -#endif - // Construct the invariant part of ld_library_path. - sprintf(common_path, SYS_EXT_DIR "/lib/%s", cpu_arch); + sprintf(common_path, SYS_EXT_DIR "/lib"); // Struct size is more than sufficient for the path components obtained // through the dlinfo() call, so only add additional space for the path @@ -2076,18 +2058,9 @@ void os::jvm_path(char *buf, jint buflen) { // Look for JAVA_HOME in the environment. char* java_home_var = ::getenv("JAVA_HOME"); if (java_home_var != NULL && java_home_var[0] != 0) { - char cpu_arch[12]; char* jrelib_p; int len; - sysinfo(SI_ARCHITECTURE, cpu_arch, sizeof(cpu_arch)); -#ifdef _LP64 - // If we are on sparc running a 64-bit vm, look in jre/lib/sparcv9. - if (strcmp(cpu_arch, "sparc") == 0) { - strcat(cpu_arch, "v9"); - } else if (strcmp(cpu_arch, "i386") == 0) { - strcpy(cpu_arch, "amd64"); - } -#endif + // Check the current module name "libjvm.so". p = strrchr(buf, '/'); assert(strstr(p, "/libjvm") == p, "invalid library name"); @@ -2098,9 +2071,9 @@ void os::jvm_path(char *buf, jint buflen) { len = strlen(buf); assert(len < buflen, "Ran out of buffer space"); jrelib_p = buf + len; - snprintf(jrelib_p, buflen-len, "/jre/lib/%s", cpu_arch); + snprintf(jrelib_p, buflen-len, "/jre/lib"); if (0 != access(buf, F_OK)) { - snprintf(jrelib_p, buflen-len, "/lib/%s", cpu_arch); + snprintf(jrelib_p, buflen-len, "/lib"); } if (0 == access(buf, F_OK)) { diff --git a/hotspot/test/Makefile b/hotspot/test/Makefile index b852714c906..5acb7782333 100644 --- a/hotspot/test/Makefile +++ b/hotspot/test/Makefile @@ -415,13 +415,8 @@ PHONY_LIST += sanitytest # Set up the directory in which the jvm directories live (client/, server/, etc.) ifeq ($(PLATFORM),windows) JVMS_DIR := $(PRODUCT_HOME)/bin -else ifeq ($(PLATFORM),bsd) -JVMS_DIR := $(PRODUCT_HOME)/lib else -# The jvms live in the architecture directory (amd64, sparcv9, -# etc.). By using a wildcard there's no need to figure out the exact -# name of that directory. -JVMS_DIR := $(PRODUCT_HOME)/lib/* +JVMS_DIR := $(PRODUCT_HOME)/lib endif # Use the existance of a directory as a sign that jvm variant is available diff --git a/hotspot/test/runtime/StackGuardPages/testme.sh b/hotspot/test/runtime/StackGuardPages/testme.sh index 22c50010bfd..96759ad9eb1 100644 --- a/hotspot/test/runtime/StackGuardPages/testme.sh +++ b/hotspot/test/runtime/StackGuardPages/testme.sh @@ -42,7 +42,7 @@ then exit 0 fi -LD_LIBRARY_PATH=.:${TESTJAVA}/jre/lib/${VM_CPU}/${VM_TYPE}:${TESTJAVA}/lib/${VM_CPU}/${VM_TYPE}:/usr/lib:$LD_LIBRARY_PATH +LD_LIBRARY_PATH=.:${TESTJAVA}/lib/${VM_TYPE}:/usr/lib:$LD_LIBRARY_PATH export LD_LIBRARY_PATH # Run the test for a java and native overflow diff --git a/hotspot/test/runtime/ThreadSignalMask/exeThreadSignalMask.c b/hotspot/test/runtime/ThreadSignalMask/exeThreadSignalMask.c index 7e879e4c09c..b84e039f024 100644 --- a/hotspot/test/runtime/ThreadSignalMask/exeThreadSignalMask.c +++ b/hotspot/test/runtime/ThreadSignalMask/exeThreadSignalMask.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, 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 @@ -66,7 +66,7 @@ void handleError(char *messageTitle, char *messageBody) { // method to load the dynamic library libjvm void loadJVM() { char lib[PATH_MAX]; - snprintf(lib, sizeof (lib), "%s/lib/sparcv9/server/libjvm.so", path); + snprintf(lib, sizeof (lib), "%s/lib/server/libjvm.so", path); handle = dlopen(lib, RTLD_LAZY); if (!handle) { handleError(dlerror(), "2"); From 9c6128c9433207486376c2a13c576e1d8466b9a2 Mon Sep 17 00:00:00 2001 From: Rachel Protacio Date: Mon, 5 Dec 2016 16:08:20 -0500 Subject: [PATCH 104/235] 8169734: Update uses of string "java.base" to macro Replaced instances of "java.base" string with JAVA_BASE_NAME macro Reviewed-by: sspitsyn, dcubed --- .../src/share/vm/classfile/classLoader.cpp | 10 +++---- .../src/share/vm/classfile/javaClasses.cpp | 2 +- .../src/share/vm/classfile/moduleEntry.cpp | 7 ++--- hotspot/src/share/vm/classfile/modules.cpp | 27 ++++++++++--------- .../src/share/vm/classfile/packageEntry.cpp | 2 +- hotspot/src/share/vm/classfile/vmSymbols.hpp | 3 ++- hotspot/src/share/vm/oops/arrayKlass.cpp | 2 +- hotspot/src/share/vm/oops/instanceKlass.cpp | 2 +- hotspot/src/share/vm/runtime/arguments.cpp | 5 ++-- 9 files changed, 32 insertions(+), 28 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classLoader.cpp b/hotspot/src/share/vm/classfile/classLoader.cpp index 88b00362d06..62ede6ef135 100644 --- a/hotspot/src/share/vm/classfile/classLoader.cpp +++ b/hotspot/src/share/vm/classfile/classLoader.cpp @@ -504,7 +504,7 @@ ClassFileStream* ClassPathImageEntry::open_stream(const char* name, TRAPS) { if (pkg_name != NULL) { if (!Universe::is_module_initialized()) { - location = (*JImageFindResource)(_jimage, "java.base", get_jimage_version_string(), name, &size); + location = (*JImageFindResource)(_jimage, JAVA_BASE_NAME, get_jimage_version_string(), name, &size); #if INCLUDE_CDS // CDS uses the boot class loader to load classes whose packages are in // modules defined for other class loaders. So, for now, get their module @@ -786,8 +786,8 @@ void ClassLoader::setup_search_path(const char *class_path, bool bootstrap_searc // what the base or core piece of the boot loader search is. Either a java runtime // image is present or this is an exploded module build situation. if (set_base_piece) { - assert(string_ends_with(path, MODULES_IMAGE_NAME) || string_ends_with(path, "java.base"), - "Incorrect boot loader search path, no java runtime image or java.base exploded build"); + assert(string_ends_with(path, MODULES_IMAGE_NAME) || string_ends_with(path, JAVA_BASE_NAME), + "Incorrect boot loader search path, no java runtime image or " JAVA_BASE_NAME " exploded build"); struct stat st; if (os::stat(path, &st) == 0) { // Directory found @@ -1156,7 +1156,7 @@ void ClassLoader::initialize_module_loader_map(JImageFile* jimage) { ResourceMark rm; jlong size; - JImageLocationRef location = (*JImageFindResource)(jimage, "java.base", get_jimage_version_string(), MODULE_LOADER_MAP, &size); + JImageLocationRef location = (*JImageFindResource)(jimage, JAVA_BASE_NAME, get_jimage_version_string(), MODULE_LOADER_MAP, &size); if (location == 0) { vm_exit_during_initialization( "Cannot find ModuleLoaderMap location from modules jimage.", NULL); @@ -1839,7 +1839,7 @@ void ClassLoader::create_javabase() { MutexLocker ml(Module_lock, THREAD); ModuleEntry* jb_module = null_cld_modules->locked_create_entry_or_null(Handle(NULL), vmSymbols::java_base(), NULL, NULL, null_cld); if (jb_module == NULL) { - vm_exit_during_initialization("Unable to create ModuleEntry for java.base"); + vm_exit_during_initialization("Unable to create ModuleEntry for " JAVA_BASE_NAME); } ModuleEntryTable::set_javabase_moduleEntry(jb_module); } diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp index dc5fe6a90f7..0bb80e7d2be 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.cpp +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp @@ -802,7 +802,7 @@ void java_lang_Class::set_mirror_module_field(KlassHandle k, Handle mirror, Hand if (javabase_was_defined) { ModuleEntry *javabase_entry = ModuleEntryTable::javabase_moduleEntry(); assert(javabase_entry != NULL && javabase_entry->module() != NULL, - "Setting class module field, java.base should be defined"); + "Setting class module field, " JAVA_BASE_NAME " should be defined"); Handle javabase_handle(THREAD, JNIHandles::resolve(javabase_entry->module())); set_module(mirror(), javabase_handle()); } diff --git a/hotspot/src/share/vm/classfile/moduleEntry.cpp b/hotspot/src/share/vm/classfile/moduleEntry.cpp index f9c8d5977fc..6afbb306d43 100644 --- a/hotspot/src/share/vm/classfile/moduleEntry.cpp +++ b/hotspot/src/share/vm/classfile/moduleEntry.cpp @@ -373,12 +373,12 @@ void ModuleEntryTable::finalize_javabase(Handle module_handle, Symbol* version, assert(module_table != NULL, "boot loader's ModuleEntryTable not defined"); if (module_handle.is_null()) { - fatal("Unable to finalize module definition for java.base"); + fatal("Unable to finalize module definition for " JAVA_BASE_NAME); } // Set java.lang.reflect.Module, version and location for java.base ModuleEntry* jb_module = javabase_moduleEntry(); - assert(jb_module != NULL, "java.base ModuleEntry not defined"); + assert(jb_module != NULL, JAVA_BASE_NAME " ModuleEntry not defined"); jb_module->set_version(version); jb_module->set_location(location); // Once java.base's ModuleEntry _module field is set with the known @@ -395,7 +395,8 @@ void ModuleEntryTable::finalize_javabase(Handle module_handle, Symbol* version, // Their module field is set once java.base's java.lang.reflect.Module is known to the VM. void ModuleEntryTable::patch_javabase_entries(Handle module_handle) { if (module_handle.is_null()) { - fatal("Unable to patch the module field of classes loaded prior to java.base's definition, invalid java.lang.reflect.Module"); + fatal("Unable to patch the module field of classes loaded prior to " + JAVA_BASE_NAME "'s definition, invalid java.lang.reflect.Module"); } // Do the fixups for the basic primitive types diff --git a/hotspot/src/share/vm/classfile/modules.cpp b/hotspot/src/share/vm/classfile/modules.cpp index a4cdacc6035..80192758c48 100644 --- a/hotspot/src/share/vm/classfile/modules.cpp +++ b/hotspot/src/share/vm/classfile/modules.cpp @@ -177,18 +177,18 @@ static void define_javabase_module(jobject module, jstring version, if (string_obj == NULL || !string_obj->is_a(SystemDictionary::String_klass())) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), - "Bad package name for module: java.base"); + "Bad package name for module: " JAVA_BASE_NAME); } char *package_name = java_lang_String::as_utf8_string(string_obj); if (!Modules::verify_package_name(package_name)) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), - err_msg("Invalid package name: %s for module: java.base", package_name)); + err_msg("Invalid package name: %s for module: " JAVA_BASE_NAME, package_name)); } Symbol* pkg_symbol = SymbolTable::new_symbol(package_name, CHECK); // append_if_missing() returns FALSE if entry already exists. if (!pkg_list->append_if_missing(pkg_symbol)) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), - err_msg("Duplicate package name: %s for module java.base", + err_msg("Duplicate package name: %s for module " JAVA_BASE_NAME, package_name)); } } @@ -206,7 +206,7 @@ static void define_javabase_module(jobject module, jstring version, assert(pkg_list->length() == 0 || package_table != NULL, "Bad package_table"); // Ensure java.base's ModuleEntry has been created - assert(ModuleEntryTable::javabase_moduleEntry() != NULL, "No ModuleEntry for java.base"); + assert(ModuleEntryTable::javabase_moduleEntry() != NULL, "No ModuleEntry for " JAVA_BASE_NAME); bool duplicate_javabase = false; { @@ -227,7 +227,7 @@ static void define_javabase_module(jobject module, jstring version, // Some of java.base's packages were added early in bootstrapping, ignore duplicates. if (package_table->lookup_only(pkg_list->at(x)) == NULL) { pkg = package_table->locked_create_entry_or_null(pkg_list->at(x), ModuleEntryTable::javabase_moduleEntry()); - assert(pkg != NULL, "Unable to create a java.base package entry"); + assert(pkg != NULL, "Unable to create a " JAVA_BASE_NAME " package entry"); } // Unable to have a GrowableArray of TempNewSymbol. Must decrement the refcount of // the Symbol* that was created above for each package. The refcount was incremented @@ -241,7 +241,7 @@ static void define_javabase_module(jobject module, jstring version, } if (duplicate_javabase) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), - "Module java.base is already defined"); + "Module " JAVA_BASE_NAME " is already defined"); } // Only the thread that actually defined the base module will get here, @@ -250,15 +250,15 @@ static void define_javabase_module(jobject module, jstring version, // Patch any previously loaded class's module field with java.base's java.lang.reflect.Module. ModuleEntryTable::patch_javabase_entries(module_handle); - log_debug(modules)("define_javabase_module(): Definition of module: java.base," - " version: %s, location: %s, package #: %d", + log_debug(modules)("define_javabase_module(): Definition of module: " + JAVA_BASE_NAME ", version: %s, location: %s, package #: %d", module_version != NULL ? module_version : "NULL", module_location != NULL ? module_location : "NULL", pkg_list->length()); // packages defined to java.base for (int x = 0; x < pkg_list->length(); x++) { - log_trace(modules)("define_javabase_module(): creation of package %s for module java.base", + log_trace(modules)("define_javabase_module(): creation of package %s for module " JAVA_BASE_NAME, (pkg_list->at(x))->as_C_string()); } } @@ -283,7 +283,7 @@ void Modules::define_module(jobject module, jstring version, } // Special handling of java.base definition - if (strcmp(module_name, "java.base") == 0) { + if (strcmp(module_name, JAVA_BASE_NAME) == 0) { define_javabase_module(module, version, location, packages, CHECK); return; } @@ -713,7 +713,8 @@ jboolean Modules::is_exported_to_module(jobject from_module, jstring package, // This method is called by JFR and JNI. jobject Modules::get_module(jclass clazz, TRAPS) { - assert(ModuleEntryTable::javabase_defined(), "Attempt to call get_module before java.base is defined"); + assert(ModuleEntryTable::javabase_defined(), + "Attempt to call get_module before " JAVA_BASE_NAME " is defined"); if (clazz == NULL) { THROW_MSG_(vmSymbols::java_lang_NullPointerException(), @@ -759,7 +760,7 @@ jobject Modules::get_module(jclass clazz, TRAPS) { jobject Modules::get_module_by_package_name(jobject loader, jstring package, TRAPS) { ResourceMark rm(THREAD); assert(ModuleEntryTable::javabase_defined(), - "Attempt to call get_module_from_pkg before java.base is defined"); + "Attempt to call get_module_from_pkg before " JAVA_BASE_NAME " is defined"); if (NULL == package) { THROW_MSG_(vmSymbols::java_lang_NullPointerException(), @@ -796,7 +797,7 @@ jobject Modules::get_module_by_package_name(jobject loader, jstring package, TRA jobject Modules::get_named_module(Handle h_loader, const char* package_str, TRAPS) { assert(ModuleEntryTable::javabase_defined(), - "Attempt to call get_named_module before java.base is defined"); + "Attempt to call get_named_module before " JAVA_BASE_NAME " is defined"); assert(h_loader.is_null() || java_lang_ClassLoader::is_subclass(h_loader->klass()), "Class loader is not a subclass of java.lang.ClassLoader"); assert(package_str != NULL, "the package_str should not be NULL"); diff --git a/hotspot/src/share/vm/classfile/packageEntry.cpp b/hotspot/src/share/vm/classfile/packageEntry.cpp index f358c51bd59..bd9d2066c18 100644 --- a/hotspot/src/share/vm/classfile/packageEntry.cpp +++ b/hotspot/src/share/vm/classfile/packageEntry.cpp @@ -293,7 +293,7 @@ void PackageEntryTable::verify_javabase_packages(GrowableArray *pkg_lis (module_name->fast_compare(vmSymbols::java_base()) == 0) && !pkg_list->contains(entry->name())) { ResourceMark rm; - vm_exit_during_initialization("A non-java.base package was loaded prior to module system initialization", entry->name()->as_C_string()); + vm_exit_during_initialization("A non-" JAVA_BASE_NAME " package was loaded prior to module system initialization", entry->name()->as_C_string()); } } } diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp index 33c77f17bdf..0987414f357 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp @@ -25,6 +25,7 @@ #ifndef SHARE_VM_CLASSFILE_VMSYMBOLS_HPP #define SHARE_VM_CLASSFILE_VMSYMBOLS_HPP +#include "classfile/moduleEntry.hpp" #include "classfile/vmSymbols_ext.hpp" #include "oops/symbol.hpp" #include "memory/iterator.hpp" @@ -50,7 +51,7 @@ #define VM_SYMBOLS_DO(template, do_alias) \ /* commonly used class, package, module names */ \ - template(java_base, "java.base") \ + template(java_base, JAVA_BASE_NAME) \ template(java_lang_System, "java/lang/System") \ template(java_lang_Object, "java/lang/Object") \ template(java_lang_Class, "java/lang/Class") \ diff --git a/hotspot/src/share/vm/oops/arrayKlass.cpp b/hotspot/src/share/vm/oops/arrayKlass.cpp index 98088b6a1f1..e851f1920b1 100644 --- a/hotspot/src/share/vm/oops/arrayKlass.cpp +++ b/hotspot/src/share/vm/oops/arrayKlass.cpp @@ -105,7 +105,7 @@ void ArrayKlass::complete_create_array_klass(ArrayKlass* k, KlassHandle super_kl // These classes will be put on a fixup list and their module fields will be patched once // java.base is defined. assert((module_entry != NULL) || ((module_entry == NULL) && !ModuleEntryTable::javabase_defined()), - "module entry not available post java.base definition"); + "module entry not available post " JAVA_BASE_NAME " definition"); oop module = (module_entry != NULL) ? JNIHandles::resolve(module_entry->module()) : (oop)NULL; java_lang_Class::create_mirror(k, Handle(THREAD, k->class_loader()), Handle(THREAD, module), Handle(NULL), CHECK); } diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 7e6c3c809fb..ae0dd01dc67 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -2247,7 +2247,7 @@ void InstanceKlass::set_package(ClassLoaderData* loader_data, TRAPS) { // the java.base module. If a non-java.base package is erroneously placed // in the java.base module it will be caught later when java.base // is defined by ModuleEntryTable::verify_javabase_packages check. - assert(ModuleEntryTable::javabase_moduleEntry() != NULL, "java.base module is NULL"); + assert(ModuleEntryTable::javabase_moduleEntry() != NULL, JAVA_BASE_NAME " module is NULL"); _package_entry = loader_data->packages()->lookup(pkg_name, ModuleEntryTable::javabase_moduleEntry()); } else { assert(loader_data->modules()->unnamed_module() != NULL, "unnamed module is NULL"); diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 485ecadd31b..d1b0ed7c04e 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "classfile/classLoader.hpp" #include "classfile/javaAssertions.hpp" +#include "classfile/moduleEntry.hpp" #include "classfile/stringTable.hpp" #include "classfile/symbolTable.hpp" #include "code/codeCacheExtensions.hpp" @@ -3427,9 +3428,9 @@ void Arguments::add_patch_mod_prefix(const char* module_name, const char* path, // This check is only required for java.base, all other duplicate module specifications // will be checked during module system initialization. The module system initialization // will throw an ExceptionInInitializerError if this situation occurs. - if (strcmp(module_name, "java.base") == 0) { + if (strcmp(module_name, JAVA_BASE_NAME) == 0) { if (*patch_mod_javabase) { - vm_exit_during_initialization("Cannot specify java.base more than once to --patch-module"); + vm_exit_during_initialization("Cannot specify " JAVA_BASE_NAME " more than once to --patch-module"); } else { *patch_mod_javabase = true; } From 8d6d1e4cdaae6c7ec52ad89b8b7669c9501596d2 Mon Sep 17 00:00:00 2001 From: Kirill Zhaldybin Date: Thu, 1 Dec 2016 12:09:02 +0300 Subject: [PATCH 105/235] 8170490: Convert TestBufferingOopClosure_test to GTest Reviewed-by: dfazunen, iignatyev --- .../share/vm/gc/g1/bufferingOopClosure.hpp | 2 +- .../share/vm/utilities/internalVMTests.cpp | 1 - .../gc/g1/test_bufferingOopClosure.cpp} | 178 ++++++++---------- 3 files changed, 83 insertions(+), 98 deletions(-) rename hotspot/{src/share/vm/gc/g1/bufferingOopClosure.cpp => test/native/gc/g1/test_bufferingOopClosure.cpp} (52%) diff --git a/hotspot/src/share/vm/gc/g1/bufferingOopClosure.hpp b/hotspot/src/share/vm/gc/g1/bufferingOopClosure.hpp index 038aba6f744..58081684f42 100644 --- a/hotspot/src/share/vm/gc/g1/bufferingOopClosure.hpp +++ b/hotspot/src/share/vm/gc/g1/bufferingOopClosure.hpp @@ -42,7 +42,7 @@ // buffered entries. class BufferingOopClosure: public OopClosure { - friend class TestBufferingOopClosure; + friend class BufferingOopClosureTest; protected: static const size_t BufferLength = 1024; diff --git a/hotspot/src/share/vm/utilities/internalVMTests.cpp b/hotspot/src/share/vm/utilities/internalVMTests.cpp index ecc4bf75eeb..1f2954afbc0 100644 --- a/hotspot/src/share/vm/utilities/internalVMTests.cpp +++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp @@ -54,7 +54,6 @@ void InternalVMTests::run() { run_unit_test(VMStructs_test); #endif #if INCLUDE_ALL_GCS - run_unit_test(TestBufferingOopClosure_test); run_unit_test(ParallelCompact_test); #endif tty->print_cr("All internal VM tests passed"); diff --git a/hotspot/src/share/vm/gc/g1/bufferingOopClosure.cpp b/hotspot/test/native/gc/g1/test_bufferingOopClosure.cpp similarity index 52% rename from hotspot/src/share/vm/gc/g1/bufferingOopClosure.cpp rename to hotspot/test/native/gc/g1/test_bufferingOopClosure.cpp index cf1b182c57f..1bc51188660 100644 --- a/hotspot/src/share/vm/gc/g1/bufferingOopClosure.cpp +++ b/hotspot/test/native/gc/g1/test_bufferingOopClosure.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, 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 @@ -19,20 +19,15 @@ * 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 "gc/g1/bufferingOopClosure.hpp" #include "memory/iterator.hpp" -#include "utilities/debug.hpp" - -/////////////// Unit tests /////////////// - -#ifndef PRODUCT - -class TestBufferingOopClosure { +#include "unittest.hpp" +class BufferingOopClosureTest : public ::testing::Test { + public: // Helper class to fake a set of oop*s and narrowOop*s. class FakeRoots { public: @@ -121,14 +116,14 @@ class TestBufferingOopClosure { public: CountOopClosure() : _narrow_oop_count(0), _full_oop_count(0) {} void do_oop(narrowOop* p) { - assert((uintptr_t(p) & FakeRoots::NarrowOopMarker) != 0, - "The narrowOop was unexpectedly not marked with the NarrowOopMarker"); + EXPECT_NE(uintptr_t(0), (uintptr_t(p) & FakeRoots::NarrowOopMarker)) + << "The narrowOop was unexpectedly not marked with the NarrowOopMarker"; _narrow_oop_count++; } void do_oop(oop* p){ - assert((uintptr_t(p) & FakeRoots::NarrowOopMarker) == 0, - "The oop was unexpectedly marked with the NarrowOopMarker"); + EXPECT_EQ(uintptr_t(0), (uintptr_t(p) & FakeRoots::NarrowOopMarker)) + << "The oop was unexpectedly marked with the NarrowOopMarker"; _full_oop_count++; } @@ -153,33 +148,14 @@ class TestBufferingOopClosure { boc.done(); - #define assert_testCount(got, expected) \ - assert((got) == (expected), \ - "Expected: %d, got: %d, when running testCount(%d, %d, %d)", \ - (got), (expected), num_narrow, num_full, do_oop_order) + EXPECT_EQ(num_narrow, coc.narrow_oop_count()) << "when running testCount(" + << num_narrow << ", " << num_full << ", " << do_oop_order << ")"; - assert_testCount(num_narrow, coc.narrow_oop_count()); - assert_testCount(num_full, coc.full_oop_count()); - assert_testCount(num_narrow + num_full, coc.all_oop_count()); - } + EXPECT_EQ(num_full, coc.full_oop_count()) << "when running testCount(" + << num_narrow << ", " << num_full << ", " << do_oop_order << ")"; - static void testCount() { - int buffer_length = BufferingOopClosure::BufferLength; - - for (int order = 0; order < FakeRoots::MaxOrder; order++) { - testCount(0, 0, order); - testCount(10, 0, order); - testCount(0, 10, order); - testCount(10, 10, order); - testCount(buffer_length, 10, order); - testCount(10, buffer_length, order); - testCount(buffer_length, buffer_length, order); - testCount(buffer_length + 1, 10, order); - testCount(10, buffer_length + 1, order); - testCount(buffer_length + 1, buffer_length, order); - testCount(buffer_length, buffer_length + 1, order); - testCount(buffer_length + 1, buffer_length + 1, order); - } + EXPECT_EQ(num_narrow + num_full, coc.all_oop_count()) << "when running testCount(" + << num_narrow << ", " << num_full << ", " << do_oop_order << ")"; } static void testIsBufferEmptyOrFull(int num_narrow, int num_full, bool expect_empty, bool expect_full) { @@ -190,34 +166,15 @@ class TestBufferingOopClosure { fr.oops_do(&boc, 0); - #define assert_testIsBufferEmptyOrFull(got, expected) \ - assert((got) == (expected), \ - "Expected: %d, got: %d. testIsBufferEmptyOrFull(%d, %d, %s, %s)", \ - (got), (expected), num_narrow, num_full, \ - BOOL_TO_STR(expect_empty), BOOL_TO_STR(expect_full)) + EXPECT_EQ(expect_empty, boc.is_buffer_empty()) + << "when running testIsBufferEmptyOrFull(" + << num_narrow << ", " << num_full << ", " + << expect_empty << ", " << expect_full << ")"; - assert_testIsBufferEmptyOrFull(expect_empty, boc.is_buffer_empty()); - assert_testIsBufferEmptyOrFull(expect_full, boc.is_buffer_full()); - } - - static void testIsBufferEmptyOrFull() { - int bl = BufferingOopClosure::BufferLength; - - testIsBufferEmptyOrFull(0, 0, true, false); - testIsBufferEmptyOrFull(1, 0, false, false); - testIsBufferEmptyOrFull(0, 1, false, false); - testIsBufferEmptyOrFull(1, 1, false, false); - testIsBufferEmptyOrFull(10, 0, false, false); - testIsBufferEmptyOrFull(0, 10, false, false); - testIsBufferEmptyOrFull(10, 10, false, false); - testIsBufferEmptyOrFull(0, bl, false, true); - testIsBufferEmptyOrFull(bl, 0, false, true); - testIsBufferEmptyOrFull(bl/2, bl/2, false, true); - testIsBufferEmptyOrFull(bl-1, 1, false, true); - testIsBufferEmptyOrFull(1, bl-1, false, true); - // Processed - testIsBufferEmptyOrFull(bl+1, 0, false, false); - testIsBufferEmptyOrFull(bl*2, 0, false, true); + EXPECT_EQ(expect_full, boc.is_buffer_full()) + << "when running testIsBufferEmptyOrFull(" + << num_narrow << ", " << num_full << ", " + << expect_empty << ", " << expect_full << ")"; } static void testEmptyAfterDone(int num_narrow, int num_full) { @@ -231,41 +188,70 @@ class TestBufferingOopClosure { // Make sure all get processed. boc.done(); - assert(boc.is_buffer_empty(), - "Should be empty after call to done(). testEmptyAfterDone(%d, %d)", - num_narrow, num_full); + EXPECT_TRUE(boc.is_buffer_empty()) << "Should be empty after call to done()." + << " testEmptyAfterDone(" << num_narrow << ", " << num_full << ")"; } - static void testEmptyAfterDone() { - int bl = BufferingOopClosure::BufferLength; - - testEmptyAfterDone(0, 0); - testEmptyAfterDone(1, 0); - testEmptyAfterDone(0, 1); - testEmptyAfterDone(1, 1); - testEmptyAfterDone(10, 0); - testEmptyAfterDone(0, 10); - testEmptyAfterDone(10, 10); - testEmptyAfterDone(0, bl); - testEmptyAfterDone(bl, 0); - testEmptyAfterDone(bl/2, bl/2); - testEmptyAfterDone(bl-1, 1); - testEmptyAfterDone(1, bl-1); - // Processed - testEmptyAfterDone(bl+1, 0); - testEmptyAfterDone(bl*2, 0); - } - - public: - static void test() { - testCount(); - testIsBufferEmptyOrFull(); - testEmptyAfterDone(); + static int get_buffer_length() { + return BufferingOopClosure::BufferLength; } }; -void TestBufferingOopClosure_test() { - TestBufferingOopClosure::test(); +TEST_VM_F(BufferingOopClosureTest, count_test) { + int bl = BufferingOopClosureTest::get_buffer_length(); + + for (int order = 0; order < FakeRoots::MaxOrder; order++) { + testCount(0, 0, order); + testCount(10, 0, order); + testCount(0, 10, order); + testCount(10, 10, order); + testCount(bl, 10, order); + testCount(10, bl, order); + testCount(bl, bl, order); + testCount(bl + 1, 10, order); + testCount(10, bl + 1, order); + testCount(bl + 1, bl, order); + testCount(bl, bl + 1, order); + testCount(bl + 1, bl + 1, order); + } } -#endif +TEST_VM_F(BufferingOopClosureTest, buffer_empty_or_full) { + int bl = BufferingOopClosureTest::get_buffer_length(); + + testIsBufferEmptyOrFull(0, 0, true, false); + testIsBufferEmptyOrFull(1, 0, false, false); + testIsBufferEmptyOrFull(0, 1, false, false); + testIsBufferEmptyOrFull(1, 1, false, false); + testIsBufferEmptyOrFull(10, 0, false, false); + testIsBufferEmptyOrFull(0, 10, false, false); + testIsBufferEmptyOrFull(10, 10, false, false); + testIsBufferEmptyOrFull(0, bl, false, true); + testIsBufferEmptyOrFull(bl, 0, false, true); + testIsBufferEmptyOrFull(bl / 2, bl / 2, false, true); + testIsBufferEmptyOrFull(bl - 1, 1, false, true); + testIsBufferEmptyOrFull(1, bl - 1, false, true); + // Processed + testIsBufferEmptyOrFull(bl + 1, 0, false, false); + testIsBufferEmptyOrFull(bl * 2, 0, false, true); +} + +TEST_VM_F(BufferingOopClosureTest, empty_after_done) { + int bl = BufferingOopClosureTest::get_buffer_length(); + + testEmptyAfterDone(0, 0); + testEmptyAfterDone(1, 0); + testEmptyAfterDone(0, 1); + testEmptyAfterDone(1, 1); + testEmptyAfterDone(10, 0); + testEmptyAfterDone(0, 10); + testEmptyAfterDone(10, 10); + testEmptyAfterDone(0, bl); + testEmptyAfterDone(bl, 0); + testEmptyAfterDone(bl / 2, bl / 2); + testEmptyAfterDone(bl - 1, 1); + testEmptyAfterDone(1, bl - 1); + // Processed + testEmptyAfterDone(bl + 1, 0); + testEmptyAfterDone(bl * 2, 0); +} From 0fb83f04d479e964f53e44921363422d7fff04d4 Mon Sep 17 00:00:00 2001 From: Dmitry Markov Date: Fri, 2 Dec 2016 12:45:52 +0300 Subject: [PATCH 106/235] 8169589: [macosx] Activating a JDialog puts to back another dialog Reviewed-by: aivanov, serb --- .../sun/lwawt/macosx/CPlatformWindow.java | 80 +++++++++++++----- .../share/classes/java/awt/Window.java | 4 + .../share/classes/sun/awt/AWTAccessor.java | 6 ++ .../DialogAboveFrameTest.java | 81 +++++++++++++++++++ 4 files changed, 153 insertions(+), 18 deletions(-) create mode 100644 jdk/test/java/awt/Dialog/DialogAboveFrame/DialogAboveFrameTest.java diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java index d93b4bbcf21..1750516a84f 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java @@ -33,11 +33,14 @@ import java.awt.Dialog.ModalityType; import java.awt.event.*; import java.beans.*; import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; import javax.swing.*; import sun.awt.*; import sun.awt.AWTAccessor.ComponentAccessor; +import sun.awt.AWTAccessor.WindowAccessor; import sun.java2d.SurfaceData; import sun.java2d.opengl.CGLSurfaceData; import sun.lwawt.*; @@ -1063,29 +1066,70 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo return true; } + private boolean isOneOfOwnersOrSelf(CPlatformWindow window) { + while (window != null) { + if (this == window) { + return true; + } + window = window.owner; + } + return false; + } + + private CPlatformWindow getRootOwner() { + CPlatformWindow rootOwner = this; + while (rootOwner.owner != null) { + rootOwner = rootOwner.owner; + } + return rootOwner; + } + private void orderAboveSiblings() { - if (owner == null) { - return; + // Recursively pop up the windows from the very bottom, (i.e. root owner) so that + // the windows are ordered above their nearest owner; ancestors of the window, + // which is going to become 'main window', are placed above their siblings. + CPlatformWindow rootOwner = getRootOwner(); + if (rootOwner.isVisible()) { + CWrapper.NSWindow.orderFront(rootOwner.getNSWindowPtr()); } + final WindowAccessor windowAccessor = AWTAccessor.getWindowAccessor(); + orderAboveSiblingsImpl(windowAccessor.getOwnedWindows(rootOwner.target)); + } - // NOTE: the logic will fail if we have a hierarchy like: - // visible root owner - // invisible owner - // visible dialog - // However, this is an unlikely scenario for real life apps - if (owner.isVisible()) { - // Recursively pop up the windows from the very bottom so that only - // the very top-most one becomes the main window - owner.orderAboveSiblings(); + private void orderAboveSiblingsImpl(Window[] windows) { + ArrayList childWindows = new ArrayList(); - // Order the window to front of the stack of child windows - final long nsWindowSelfPtr = getNSWindowPtr(); - final long nsWindowOwnerPtr = owner.getNSWindowPtr(); - CWrapper.NSWindow.orderFront(nsWindowOwnerPtr); - CWrapper.NSWindow.orderWindow(nsWindowSelfPtr, CWrapper.NSWindow.NSWindowAbove, nsWindowOwnerPtr); + final ComponentAccessor componentAccessor = AWTAccessor.getComponentAccessor(); + final WindowAccessor windowAccessor = AWTAccessor.getWindowAccessor(); + + // Go through the list of windows and perform ordering. + for (Window w : windows) { + final Object p = componentAccessor.getPeer(w); + if (p instanceof LWWindowPeer) { + CPlatformWindow pw = (CPlatformWindow)((LWWindowPeer)p).getPlatformWindow(); + if (pw != null && pw.isVisible()) { + // If the window is one of ancestors of 'main window' or is going to become main by itself, + // the window should be ordered above its siblings; otherwise the window is just ordered + // above its nearest parent. + if (pw.isOneOfOwnersOrSelf(this)) { + CWrapper.NSWindow.orderFront(pw.getNSWindowPtr()); + } else { + CWrapper.NSWindow.orderWindow(pw.getNSWindowPtr(), CWrapper.NSWindow.NSWindowAbove, + pw.owner.getNSWindowPtr()); + } + pw.applyWindowLevel(w); + } + } + // Retrieve the child windows for each window from the list and store them for future use. + // Note: we collect data about child windows even for invisible owners, since they may have + // visible children. + childWindows.addAll(Arrays.asList(windowAccessor.getOwnedWindows(w))); + } + // If some windows, which have just been ordered, have any child windows, let's start new iteration + // and order these child windows. + if (!childWindows.isEmpty()) { + orderAboveSiblingsImpl(childWindows.toArray(new Window[0])); } - - applyWindowLevel(target); } protected void applyWindowLevel(Window target) { diff --git a/jdk/src/java.desktop/share/classes/java/awt/Window.java b/jdk/src/java.desktop/share/classes/java/awt/Window.java index ed7d63ae154..8d122be3522 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/Window.java +++ b/jdk/src/java.desktop/share/classes/java/awt/Window.java @@ -4122,6 +4122,10 @@ public class Window extends Container implements Accessible { public void setTrayIconWindow(Window w, boolean isTrayIconWindow) { w.isTrayIconWindow = isTrayIconWindow; } + + public Window[] getOwnedWindows(Window w) { + return w.getOwnedWindows_NoClientCode(); + } }); // WindowAccessor } // static diff --git a/jdk/src/java.desktop/share/classes/sun/awt/AWTAccessor.java b/jdk/src/java.desktop/share/classes/sun/awt/AWTAccessor.java index b20d8d62367..29a435c96b9 100644 --- a/jdk/src/java.desktop/share/classes/sun/awt/AWTAccessor.java +++ b/jdk/src/java.desktop/share/classes/sun/awt/AWTAccessor.java @@ -360,6 +360,12 @@ public final class AWTAccessor { * Marks the specified window as an utility window for TrayIcon. */ void setTrayIconWindow(Window w, boolean isTrayIconWindow); + + /** + * Return an array containing all the windows this + * window currently owns. + */ + Window[] getOwnedWindows(Window w); } /** diff --git a/jdk/test/java/awt/Dialog/DialogAboveFrame/DialogAboveFrameTest.java b/jdk/test/java/awt/Dialog/DialogAboveFrame/DialogAboveFrameTest.java new file mode 100644 index 00000000000..6db02253f42 --- /dev/null +++ b/jdk/test/java/awt/Dialog/DialogAboveFrame/DialogAboveFrameTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2016, 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 8169589 + * @summary Activating a dialog puts to back another dialog owned by the same frame + * @author Dmitry Markov + * @library ../../regtesthelpers + * @build Util + * @run main DialogAboveFrameTest + */ + +import java.awt.Color; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; + +import test.java.awt.regtesthelpers.Util; + +public class DialogAboveFrameTest { + public static void main(String[] args) { + Robot robot = Util.createRobot(); + + Frame frame = new Frame("Frame"); + frame.setBackground(Color.BLUE); + frame.setBounds(200, 50, 300, 300); + frame.setVisible(true); + + Dialog dialog1 = new Dialog(frame, "Dialog 1", false); + dialog1.setBackground(Color.RED); + dialog1.setBounds(100, 100, 200, 200); + dialog1.setVisible(true); + + Dialog dialog2 = new Dialog(frame, "Dialog 2", false); + dialog2.setBackground(Color.GREEN); + dialog2.setBounds(400, 100, 200, 200); + dialog2.setVisible(true); + + Util.waitForIdle(robot); + + Util.clickOnComp(dialog2, robot); + Util.waitForIdle(robot); + + Point point = dialog1.getLocationOnScreen(); + int x = point.x + (int)(dialog1.getWidth() * 0.9); + int y = point.y + (int)(dialog1.getHeight() * 0.9); + + try { + if (!robot.getPixelColor(x, y).equals(dialog1.getBackground())) { + throw new RuntimeException("Test FAILED: Dialog is behind the frame"); + } + } finally { + frame.dispose(); + dialog1.dispose(); + dialog2.dispose(); + } + } +} + From 0bf29180647aca64fe3d9935b419efeb3685dc2c Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Fri, 2 Dec 2016 15:22:35 +0530 Subject: [PATCH 107/235] 8169879: [TEST_BUG] javax/swing/text/GlyphPainter2/6427244/bug6427244.java - compilation failed Reviewed-by: psadhukhan, aghaisas --- .../GlyphPainter2/6427244/bug6427244.java | 71 ++++++++++++++----- 1 file changed, 55 insertions(+), 16 deletions(-) diff --git a/jdk/test/javax/swing/text/GlyphPainter2/6427244/bug6427244.java b/jdk/test/javax/swing/text/GlyphPainter2/6427244/bug6427244.java index f6f571aa05e..25066dafe42 100644 --- a/jdk/test/javax/swing/text/GlyphPainter2/6427244/bug6427244.java +++ b/jdk/test/javax/swing/text/GlyphPainter2/6427244/bug6427244.java @@ -23,7 +23,7 @@ */ /* @test - @bug 6427244 8144240 8166003 + @bug 6427244 8144240 8166003 8169879 @summary Test that pressing HOME correctly moves caret in I18N document. @author Sergey Groznyh @library ../../../regtesthelpers @@ -69,10 +69,12 @@ public class bug6427244 { bug6427244 t = new bug6427244(); for (String space: SPACES) { t.init(space); - t.runAllTests(); + t.testCaretPosition(); } System.out.println("OK"); + // Dispose the test interface upon completion + t.destroyTestInterface(); } void init(final String space) { @@ -113,29 +115,65 @@ public class bug6427244 { } } - void blockTillDisplayed(JComponent comp) { - if(comp != null) { - while (!comp.isVisible()) { - try { + void destroyTestInterface() { + try { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + // Dispose the frame + jf.dispose(); + } + }); + } catch (Exception ex) { + // No-op + } + } + + void blockTillDisplayed(JComponent comp) throws Exception { + while (comp != null && isCompVisible == false) { + try { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + isCompVisible = comp.isVisible(); + } + }); + + if (isCompVisible == false) { + // A short wait for component to be visible Thread.sleep(1000); - } catch (InterruptedException ie) { - /* No-op */ } + } catch (InterruptedException ex) { + // No-op. Thread resumed from sleep + } catch (Exception ex) { + throw new RuntimeException(ex); } } } public void testCaretPosition() { - Point p = tp.getLocationOnScreen(); - // the right-top corner position - p.x += (dim.width - 5); - p.y += 5; - ROBOT.mouseMove(p.x, p.y); + final Point p[] = new Point[1]; + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + p[0] = tp.getLocationOnScreen(); + + // the right-top corner position + p[0].x += (dim.width - 5); + p[0].y += 5; + } + }); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + ROBOT.mouseMove(p[0].x, p[0].y); ROBOT.clickMouse(); ROBOT.hitKey(KeyEvent.VK_HOME); ROBOT.waitForIdle(); // this will fail if caret moves out of the 1st line. if (getCaretOrdinate() != 0) { + // Dispose the test interface upon completion + destroyTestInterface(); throw new RuntimeException("Test Failed."); } } @@ -162,7 +200,8 @@ public class bug6427244 { return y[0]; } - JFrame jf; - JTextPane tp; - Dimension dim; + private JFrame jf; + private JTextPane tp; + private Dimension dim; + private volatile boolean isCompVisible = false; } From 96fc05b6726cb530d314340e03737a8fa56c2c46 Mon Sep 17 00:00:00 2001 From: Brent Christian Date: Tue, 13 Dec 2016 12:35:59 -0800 Subject: [PATCH 108/235] 8169389: Use a bitmap to control StackTraceElement::toString format and save footprint Reviewed-by: dfuchs, mchung --- .../classes/java/lang/StackTraceElement.java | 155 +++++++++--------- .../lang/StackTraceElement/ModuleFrames.java | 26 ++- 2 files changed, 98 insertions(+), 83 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/lang/StackTraceElement.java b/jdk/src/java.base/share/classes/java/lang/StackTraceElement.java index 04ba817a553..98536259a92 100644 --- a/jdk/src/java.base/share/classes/java/lang/StackTraceElement.java +++ b/jdk/src/java.base/share/classes/java/lang/StackTraceElement.java @@ -30,7 +30,6 @@ import jdk.internal.misc.SharedSecrets; import jdk.internal.misc.VM; import jdk.internal.module.ModuleHashes; -import java.lang.module.ModuleDescriptor.Version; import java.lang.reflect.Layer; import java.lang.reflect.Module; import java.util.HashSet; @@ -51,12 +50,13 @@ import java.util.Set; * @author Josh Bloch */ public final class StackTraceElement implements java.io.Serializable { - // This field is set to the compacted String representation used - // by StackTraceElement::toString and stored in serial form. + + // For Throwables and StackWalker, the VM initially sets this field to a + // reference to the declaring Class. The Class reference is used to + // construct the 'format' bitmap, and then is cleared. // - // This field is of Object type. VM initially sets this field to - // the Class object of the declaring class to build the compacted string. - private Object classOrLoaderModuleClassName; + // For STEs constructed using the public constructors, this field is not used. + private transient Class declaringClassObject; // Normally initialized by VM private String classLoaderName; @@ -66,6 +66,7 @@ public final class StackTraceElement implements java.io.Serializable { private String methodName; private String fileName; private int lineNumber; + private byte format = 0; // Default to show all /** * Creates a stack trace element representing the specified execution @@ -256,9 +257,10 @@ public final class StackTraceElement implements java.io.Serializable { } /** - * Returns a string representation of this stack trace element. The - * format of this string depends on the implementation, but the following - * examples may be regarded as typical: + * Returns a string representation of this stack trace element. + * + * @apiNote The format of this string depends on the implementation, but the + * following examples may be regarded as typical: *