diff --git a/doc/testing.html b/doc/testing.html index 195153c8612..c8d0b928bb0 100644 --- a/doc/testing.html +++ b/doc/testing.html @@ -284,9 +284,10 @@ possible, or if you want to use a fully qualified test descriptor, add

Gtest

Note: To be able to run the Gtest suite, you need to configure your build to be able to find a proper version of the gtest -source. For details, see the section "Running Tests" in the build -documentation.

+source. For details, see the section "Running Tests" in the +build documentation (html, markdown).

Since the Hotspot Gtest suite is so quick, the default is to run all tests. This is specified by just gtest, or as a fully qualified test descriptor gtest:all.

diff --git a/doc/testing.md b/doc/testing.md index d0e54aab02b..5f70f2796ad 100644 --- a/doc/testing.md +++ b/doc/testing.md @@ -198,8 +198,8 @@ use a fully qualified test descriptor, add `jtreg:`, e.g. **Note:** To be able to run the Gtest suite, you need to configure your build to be able to find a proper version of the gtest source. For details, see the -section ["Running Tests" in the build -documentation](building.html#running-tests). +section **"Running Tests" in the build +documentation** ([html](building.html#running-tests), [markdown](building.md#running-tests)). Since the Hotspot Gtest suite is so quick, the default is to run all tests. This is specified by just `gtest`, or as a fully qualified test descriptor diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index 05b2514a456..53fa4e3066c 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -1182,12 +1182,12 @@ class CallStubImpl { public: // Size of call trampoline stub. static uint size_call_trampoline() { - return 0; // no call trampolines on this platform + return MacroAssembler::max_trampoline_stub_size(); } // number of relocations needed by a call trampoline stub static uint reloc_call_trampoline() { - return 0; // no call trampolines on this platform + return 5; // metadata; call dest; trampoline address; trampoline destination; trampoline_owner_metadata } }; diff --git a/src/hotspot/cpu/aarch64/compiledIC_aarch64.cpp b/src/hotspot/cpu/aarch64/compiledIC_aarch64.cpp index 6fe3315014b..640cd495383 100644 --- a/src/hotspot/cpu/aarch64/compiledIC_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/compiledIC_aarch64.cpp @@ -89,16 +89,21 @@ void CompiledDirectCall::set_to_interpreted(const methodHandle& callee, address NativeMovConstReg* method_holder = nativeMovConstReg_at(stub + NativeInstruction::instruction_size); + // In AOT "production" run we have mixture of AOTed and normal JITed code. + // Static call stub in AOTed nmethod always has far jump. + // Normal JITed nmethod may have short or far jump depending on distance. + // Determine actual jump instruction we have in code. + address next_instr = method_holder->next_instruction_address(); + bool is_general_jump = nativeInstruction_at(next_instr)->is_general_jump(); + #ifdef ASSERT - NativeJump* jump = MacroAssembler::codestub_branch_needs_far_jump() - ? nativeGeneralJump_at(method_holder->next_instruction_address()) - : nativeJump_at(method_holder->next_instruction_address()); + NativeJump* jump = is_general_jump ? nativeGeneralJump_at(next_instr) : nativeJump_at(next_instr); verify_mt_safe(callee, entry, method_holder, jump); #endif // Update stub. method_holder->set_data((intptr_t)callee()); - MacroAssembler::pd_patch_instruction(method_holder->next_instruction_address(), entry); + MacroAssembler::pd_patch_instruction(next_instr, entry); ICache::invalidate_range(stub, to_interp_stub_size()); // Update jump to call. set_destination_mt_safe(stub); diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index ebbc35ce20a..b5e15402941 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -952,7 +952,10 @@ void MacroAssembler::emit_static_call_stub() { } int MacroAssembler::static_call_stub_size() { - if (!codestub_branch_needs_far_jump()) { + // During AOT production run AOT and JIT compiled code + // are used at the same time. We need this size + // to be the same for both types of code. + if (!codestub_branch_needs_far_jump() && !AOTCodeCache::is_on_for_use()) { // isb; movk; movz; movz; b return 5 * NativeInstruction::instruction_size; } diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp index 84a0b7588ef..4c646c82b8a 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp @@ -2341,20 +2341,16 @@ void G1CMTask::drain_local_queue(bool partially) { } } -size_t G1CMTask::start_partial_array_processing(oop obj) { - assert(should_be_sliced(obj), "Must be an array object %d and large %zu", obj->is_objArray(), obj->size()); - - objArrayOop obj_array = objArrayOop(obj); - size_t array_length = obj_array->length(); - - size_t initial_chunk_size = _partial_array_splitter.start(_task_queue, obj_array, nullptr, array_length); +size_t G1CMTask::start_partial_array_processing(objArrayOop obj) { + assert(obj->length() >= (int)ObjArrayMarkingStride, "Must be a large array object %d", obj->length()); // Mark objArray klass metadata - if (_cm_oop_closure->do_metadata()) { - _cm_oop_closure->do_klass(obj_array->klass()); - } + process_klass(obj->klass()); - process_array_chunk(obj_array, 0, initial_chunk_size); + size_t array_length = obj->length(); + size_t initial_chunk_size = _partial_array_splitter.start(_task_queue, obj, nullptr, array_length); + + process_array_chunk(obj, 0, initial_chunk_size); // Include object header size return objArrayOopDesc::object_size(checked_cast(initial_chunk_size)); diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp index 7aa93947204..f9287f673d2 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp @@ -844,12 +844,10 @@ private: // mark bitmap scan, and so needs to be pushed onto the mark stack. bool is_below_finger(oop obj, HeapWord* global_finger) const; - template void process_grey_task_entry(G1TaskQueueEntry task_entry, bool stolen); - static bool should_be_sliced(oop obj); // Start processing the given objArrayOop by first pushing its continuations and // then scanning the first chunk including the header. - size_t start_partial_array_processing(oop obj); + size_t start_partial_array_processing(objArrayOop obj); // Process the given continuation. Returns the number of words scanned. size_t process_partial_array(const G1TaskQueueEntry& task, bool stolen); // Apply the closure to the given range of elements in the objArray. @@ -918,6 +916,9 @@ public: template inline bool deal_with_reference(T* p); + // Scan the klass and visit its children. + inline void process_klass(Klass* klass); + // Scans an object and visits its children. inline void process_entry(G1TaskQueueEntry task_entry, bool stolen); diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp index 21167d5cae9..094f4dca994 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp @@ -106,9 +106,27 @@ inline void G1CMMarkStack::iterate(Fn fn) const { } #endif +inline void G1CMTask::process_klass(Klass* klass) { + _cm_oop_closure->do_klass(klass); +} + // It scans an object and visits its children. inline void G1CMTask::process_entry(G1TaskQueueEntry task_entry, bool stolen) { - process_grey_task_entry(task_entry, stolen); + assert(task_entry.is_partial_array_state() || _mark_bitmap->is_marked(cast_from_oop(task_entry.to_oop())), + "Any stolen object should be a slice or marked"); + + if (task_entry.is_partial_array_state()) { + _words_scanned += process_partial_array(task_entry, stolen); + } else { + oop obj = task_entry.to_oop(); + if (should_be_sliced(obj)) { + _words_scanned += start_partial_array_processing(objArrayOop(obj)); + } else { + _words_scanned += obj->oop_iterate_size(_cm_oop_closure); + } + } + + check_limits(); } inline void G1CMTask::push(G1TaskQueueEntry task_entry) { @@ -160,27 +178,6 @@ inline bool G1CMTask::is_below_finger(oop obj, HeapWord* global_finger) const { return objAddr < global_finger; } -template -inline void G1CMTask::process_grey_task_entry(G1TaskQueueEntry task_entry, bool stolen) { - assert(scan || (!task_entry.is_partial_array_state() && task_entry.to_oop()->is_typeArray()), "Skipping scan of grey non-typeArray"); - assert(task_entry.is_partial_array_state() || _mark_bitmap->is_marked(cast_from_oop(task_entry.to_oop())), - "Any stolen object should be a slice or marked"); - - if (scan) { - if (task_entry.is_partial_array_state()) { - _words_scanned += process_partial_array(task_entry, stolen); - } else { - oop obj = task_entry.to_oop(); - if (should_be_sliced(obj)) { - _words_scanned += start_partial_array_processing(obj); - } else { - _words_scanned += obj->oop_iterate_size(_cm_oop_closure); - } - } - } - check_limits(); -} - inline bool G1CMTask::should_be_sliced(oop obj) { return obj->is_objArray() && ((objArrayOop)obj)->length() >= (int)ObjArrayMarkingStride; } @@ -272,7 +269,6 @@ inline bool G1CMTask::make_reference_grey(oop obj) { // be pushed on the stack. So, some duplicate work, but no // correctness problems. if (is_below_finger(obj, global_finger)) { - G1TaskQueueEntry entry(obj); if (obj->is_typeArray()) { // Immediately process arrays of primitive types, rather // than pushing on the mark stack. This keeps us from @@ -284,8 +280,8 @@ inline bool G1CMTask::make_reference_grey(oop obj) { // by only doing a bookkeeping update and avoiding the // actual scan of the object - a typeArray contains no // references, and the metadata is built-in. - process_grey_task_entry(entry, false /* stolen */); } else { + G1TaskQueueEntry entry(obj); push(entry); } } diff --git a/src/hotspot/share/opto/phaseX.cpp b/src/hotspot/share/opto/phaseX.cpp index 06963eff4cf..0fecc14f31a 100644 --- a/src/hotspot/share/opto/phaseX.cpp +++ b/src/hotspot/share/opto/phaseX.cpp @@ -909,9 +909,9 @@ void PhaseIterGVN::verify_step(Node* n) { } } -void PhaseIterGVN::trace_PhaseIterGVN(Node* n, Node* nn, const Type* oldtype) { +void PhaseIterGVN::trace_PhaseIterGVN(Node* n, Node* nn, const Type* oldtype, bool progress) { const Type* newtype = type_or_null(n); - if (nn != n || oldtype != newtype) { + if (progress) { C->print_method(PHASE_AFTER_ITER_GVN_STEP, 5, n); } if (TraceIterativeGVN) { @@ -1092,7 +1092,9 @@ bool PhaseIterGVN::drain_worklist() { NOT_PRODUCT(const Type* oldtype = type_or_null(n)); // Do the transformation DEBUG_ONLY(int live_nodes_before = C->live_nodes();) + NOT_PRODUCT(uint progress_before = made_progress();) Node* nn = transform_old(n); + NOT_PRODUCT(bool progress = (made_progress() - progress_before) > 0;) DEBUG_ONLY(int live_nodes_after = C->live_nodes();) // Ensure we did not increase the live node count with more than // max_live_nodes_increase_per_iteration during the call to transform_old. @@ -1101,7 +1103,7 @@ bool PhaseIterGVN::drain_worklist() { "excessive live node increase in single iteration of IGVN: %d " "(should be at most %d)", increase, max_live_nodes_increase_per_iteration); - NOT_PRODUCT(trace_PhaseIterGVN(n, nn, oldtype);) + NOT_PRODUCT(trace_PhaseIterGVN(n, nn, oldtype, progress);) } else if (!n->is_top()) { remove_dead_node(n, NodeOrigin::Graph); } diff --git a/src/hotspot/share/opto/phaseX.hpp b/src/hotspot/share/opto/phaseX.hpp index cef273ff3df..014d16f92f6 100644 --- a/src/hotspot/share/opto/phaseX.hpp +++ b/src/hotspot/share/opto/phaseX.hpp @@ -548,7 +548,7 @@ public: #endif #ifndef PRODUCT - void trace_PhaseIterGVN(Node* n, Node* nn, const Type* old_type); + void trace_PhaseIterGVN(Node* n, Node* nn, const Type* old_type, bool progress); void init_verifyPhaseIterGVN(); void verify_PhaseIterGVN(bool deep_revisit_converged); #endif diff --git a/src/java.base/share/classes/sun/security/ssl/QuicTLSEngineImpl.java b/src/java.base/share/classes/sun/security/ssl/QuicTLSEngineImpl.java index 74975fc1e5b..b5f1eff179c 100644 --- a/src/java.base/share/classes/sun/security/ssl/QuicTLSEngineImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/QuicTLSEngineImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, 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 @@ -660,7 +660,7 @@ public final class QuicTLSEngineImpl implements QuicTLSEngine, SSLTransport { } Alert alert = ((QuicEngineOutputRecord) conContext.outputRecord).getAlert(); - throw new QuicTransportException(alert.description, keySpace, 0, + throw new QuicTransportException(e.getMessage(), keySpace, 0, BASE_CRYPTO_ERROR + alert.id, e); } catch (IOException e) { throw new RuntimeException(e); diff --git a/src/java.desktop/share/classes/java/awt/MouseInfo.java b/src/java.desktop/share/classes/java/awt/MouseInfo.java index 6b913adf06e..7a30243b06c 100644 --- a/src/java.desktop/share/classes/java/awt/MouseInfo.java +++ b/src/java.desktop/share/classes/java/awt/MouseInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, 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 @@ -58,6 +58,7 @@ public class MouseInfo { * * @throws HeadlessException if GraphicsEnvironment.isHeadless() returns true * @return location of the mouse pointer + * @see GraphicsConfiguration * @since 1.5 */ public static PointerInfo getPointerInfo() throws HeadlessException { diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/quic/TerminationCause.java b/src/java.net.http/share/classes/jdk/internal/net/http/quic/TerminationCause.java index 9e441cf7873..df8c229a000 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/quic/TerminationCause.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/quic/TerminationCause.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, 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 @@ -128,6 +128,9 @@ public abstract sealed class TerminationCause { ? new IOException("connection terminated") : new IOException(fallbackExceptionMsg); } else if (original instanceof QuicTransportException qte) { + if (qte.getCause() instanceof IOException ioe) { + return ioe; + } return new IOException(qte.getMessage()); } else if (original instanceof IOException ioe) { return ioe; diff --git a/test/jdk/java/net/httpclient/InvalidSSLContextTest.java b/test/jdk/java/net/httpclient/InvalidSSLContextTest.java index 0027a7956d5..bbbd1e486ca 100644 --- a/test/jdk/java/net/httpclient/InvalidSSLContextTest.java +++ b/test/jdk/java/net/httpclient/InvalidSSLContextTest.java @@ -23,10 +23,12 @@ /* * @test + * @bug 8381316 * @summary Test to ensure the HTTP client throws an appropriate SSL exception * when SSL context is not valid. - * @library /test/lib + * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run junit/othervm -Djdk.internal.httpclient.debug=true InvalidSSLContextTest */ @@ -44,14 +46,18 @@ import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLSocket; import java.net.http.HttpClient; import java.net.http.HttpClient.Version; +import java.net.http.HttpOption; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; + +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestServer; import jdk.test.lib.net.SimpleSSLContext; import static java.net.http.HttpClient.Builder.NO_PROXY; -import static java.net.http.HttpClient.Version.HTTP_1_1; -import static java.net.http.HttpClient.Version.HTTP_2; +import static java.net.http.HttpClient.Version.*; +import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; +import static jdk.httpclient.test.lib.common.HttpServerAdapters.createClientBuilderForH3; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; @@ -64,25 +70,29 @@ public class InvalidSSLContextTest { private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); static volatile SSLServerSocket sslServerSocket; static volatile String uri; + private static HttpTestServer h3Server; + private static String h3Uri; public static Object[][] versions() { return new Object[][]{ - { HTTP_1_1 }, - { HTTP_2 } + { HTTP_1_1, uri }, + { HTTP_2 , uri }, + { HTTP_3 , h3Uri } }; } @ParameterizedTest @MethodSource("versions") - public void testSync(Version version) throws Exception { + public void testSync(Version version, String uri) throws Exception { // client-side uses a different context to that of the server-side - HttpClient client = HttpClient.newBuilder() + HttpClient client = createClientBuilderForH3() .proxy(NO_PROXY) .sslContext(SSLContext.getDefault()) .build(); HttpRequest request = HttpRequest.newBuilder(URI.create(uri)) .version(version) + .setOption(HttpOption.H3_DISCOVERY, HTTP_3_URI_ONLY) .build(); try { @@ -90,21 +100,22 @@ public class InvalidSSLContextTest { Assertions.fail("UNEXPECTED response" + response); } catch (IOException ex) { System.out.println("Caught expected: " + ex); - assertExceptionOrCause(SSLException.class, ex); + assertException(SSLException.class, ex); } } @ParameterizedTest @MethodSource("versions") - public void testAsync(Version version) throws Exception { + public void testAsync(Version version, String uri) throws Exception { // client-side uses a different context to that of the server-side - HttpClient client = HttpClient.newBuilder() + HttpClient client = createClientBuilderForH3() .proxy(NO_PROXY) .sslContext(SSLContext.getDefault()) .build(); HttpRequest request = HttpRequest.newBuilder(URI.create(uri)) .version(version) + .setOption(HttpOption.H3_DISCOVERY, HTTP_3_URI_ONLY) .build(); assertExceptionally(SSLException.class, @@ -123,26 +134,20 @@ public class InvalidSSLContextTest { if (cause == null) { Assertions.fail("Unexpected null cause: " + error); } - assertExceptionOrCause(clazz, cause); + System.out.println("Caught expected: " + cause); + assertException(clazz, cause); } else { - assertExceptionOrCause(clazz, error); + System.out.println("Caught expected: " + error); + assertException(clazz, error); } return null; }).join(); } - static void assertExceptionOrCause(Class clazz, Throwable t) { - if (t == null) { - Assertions.fail("Expected " + clazz + ", caught nothing"); - } - final Throwable original = t; - do { - if (clazz.isInstance(t)) { - return; // found - } - } while ((t = t.getCause()) != null); - original.printStackTrace(System.out); - Assertions.fail("Expected " + clazz + "in " + original); + static void assertException(Class clazz, Throwable t) { + Assertions.assertInstanceOf(clazz, t); + Assertions.assertTrue(t.getMessage().contains("unable to find valid certification path to requested target"), + "Unexpected exception message: " + t); } @BeforeAll @@ -159,7 +164,7 @@ public class InvalidSSLContextTest { Thread t = new Thread("SSL-Server-Side") { @Override public void run() { - while (true) { + while (!sslServerSocket.isClosed()) { try { SSLSocket s = (SSLSocket) sslServerSocket.accept(); System.out.println("SERVER: accepted: " + s); @@ -177,7 +182,6 @@ public class InvalidSSLContextTest { if (!sslServerSocket.isClosed()) { throw new UncheckedIOException(e); } - break; } catch (InterruptedException ie) { throw new RuntimeException(ie); } @@ -185,10 +189,16 @@ public class InvalidSSLContextTest { } }; t.start(); + + h3Server = HttpTestServer.create(HTTP_3_URI_ONLY, sslContext); + h3Server.addHandler((exchange) -> exchange.sendResponseHeaders(200, 0), "/hello"); + h3Server.start(); + h3Uri = "https://" + h3Server.serverAuthority() + "/hello"; } @AfterAll public static void teardown() throws Exception { + h3Server.stop(); sslServerSocket.close(); } }