Merge branch 'master' of https://github.com/openjdk/jdk into feature/class-is-class-or-interface-1

This commit is contained in:
Chen Liang 2026-07-31 10:45:35 -05:00
commit 8240dea2de
15 changed files with 76 additions and 159 deletions

View File

@ -2671,14 +2671,6 @@ LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
return EXCEPTION_CONTINUE_EXECUTION;
}
static inline void report_error(Thread* t, DWORD exception_code,
address addr, void* siginfo, void* context) {
VMError::report_and_die(t, exception_code, addr, siginfo, context);
// If UseOSErrorReporting, this will return here and save the error file
// somewhere where we can find it in the minidump.
}
//-----------------------------------------------------------------------------
JNIEXPORT
LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
@ -2750,9 +2742,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
// Fatal red zone violation.
overflow_state->disable_stack_red_zone();
tty->print_raw_cr("An unrecoverable stack overflow has occurred.");
report_error(t, exception_code, pc, exception_record,
exceptionInfo->ContextRecord);
return EXCEPTION_CONTINUE_SEARCH;
VMError::report_and_die(t, exception_code, pc, exception_record,
exceptionInfo->ContextRecord);
}
} else if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
if (in_java) {
@ -2789,9 +2780,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
if (stub != nullptr) return Handle_Exception(exceptionInfo, stub);
}
report_error(t, exception_code, pc, exception_record,
exceptionInfo->ContextRecord);
return EXCEPTION_CONTINUE_SEARCH;
VMError::report_and_die(t, exception_code, pc, exception_record,
exceptionInfo->ContextRecord);
}
// Special care for fast JNI field accessors.
@ -2803,9 +2793,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
}
// Stack overflow or null pointer exception in native code.
report_error(t, exception_code, pc, exception_record,
exceptionInfo->ContextRecord);
return EXCEPTION_CONTINUE_SEARCH;
VMError::report_and_die(t, exception_code, pc, exception_record,
exceptionInfo->ContextRecord);
} // /EXCEPTION_ACCESS_VIOLATION
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -2873,8 +2862,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
#endif
if (should_report_error) {
report_error(t, exception_code, pc, exception_record,
exceptionInfo->ContextRecord);
VMError::report_and_die(t, exception_code, pc, exception_record,
exceptionInfo->ContextRecord);
}
return EXCEPTION_CONTINUE_SEARCH;
@ -2894,8 +2883,8 @@ LONG WINAPI topLevelUnhandledExceptionFilter(struct _EXCEPTION_POINTERS* excepti
Thread* thread = Thread::current_or_null_safe();
if (exceptionCode != EXCEPTION_BREAKPOINT) {
report_error(thread, exceptionCode, pc, exceptionInfo->ExceptionRecord,
exceptionInfo->ContextRecord);
VMError::report_and_die(thread, exceptionCode, pc, exceptionInfo->ExceptionRecord,
exceptionInfo->ContextRecord);
}
}

View File

@ -240,10 +240,6 @@ void report_vm_out_of_memory(const char* file, int line, size_t size,
VMError::report_and_die(Thread::current_or_null(), file, line, size, vm_err_type, detail_fmt, detail_args);
va_end(detail_args);
// The UseOSErrorReporting option in report_and_die() may allow a return
// to here. If so then we'll have to figure out how to handle it.
guarantee(false, "report_and_die() should not return here");
}
void report_should_not_call(const char* file, int line) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 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
@ -183,7 +183,7 @@ public class BufferingSubscriber<T> implements TrustedSubscriber<T>
}
private final SequentialScheduler pushDemandedScheduler =
new SequentialScheduler(new PushDemandedTask());
SequentialScheduler.lockingScheduler(new PushDemandedTask());
void pushDemanded() {
if (cancelled.get())
@ -191,7 +191,7 @@ public class BufferingSubscriber<T> implements TrustedSubscriber<T>
pushDemandedScheduler.runOrSchedule();
}
class PushDemandedTask extends SequentialScheduler.CompleteRestartableTask {
class PushDemandedTask implements Runnable {
@Override
public void run() {
try {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 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
@ -52,7 +52,6 @@ import jdk.internal.net.http.common.Demand;
import jdk.internal.net.http.common.FlowTube;
import jdk.internal.net.http.common.Logger;
import jdk.internal.net.http.common.SequentialScheduler;
import jdk.internal.net.http.common.SequentialScheduler.DeferredCompleter;
import jdk.internal.net.http.common.Log;
import jdk.internal.net.http.common.Utils;
@ -554,7 +553,7 @@ abstract class HttpConnection implements Closeable {
volatile Flow.Subscriber<? super List<ByteBuffer>> subscriber;
volatile HttpWriteSubscription subscription;
final SequentialScheduler writeScheduler =
new SequentialScheduler(this::flushTask);
SequentialScheduler.lockingScheduler(this::flushTask);
@Override
public void subscribe(Flow.Subscriber<? super List<ByteBuffer>> subscriber) {
synchronized (reading) {
@ -570,13 +569,9 @@ abstract class HttpConnection implements Closeable {
signal();
}
void flushTask(DeferredCompleter completer) {
try {
HttpWriteSubscription sub = subscription;
if (sub != null) sub.flush();
} finally {
completer.complete();
}
void flushTask() {
HttpWriteSubscription sub = subscription;
if (sub != null) sub.flush();
}
void signal() {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 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
@ -85,7 +85,7 @@ class PullPublisher<T> implements Flow.Publisher<T> {
private volatile boolean completed;
private volatile boolean cancelled;
private volatile Throwable error;
final SequentialScheduler pullScheduler = new SequentialScheduler(new PullTask());
final SequentialScheduler pullScheduler = SequentialScheduler.lockingScheduler(new PullTask());
private final Demand demand = new Demand();
Subscription(Flow.Subscriber<? super T> subscriber,
@ -96,9 +96,9 @@ class PullPublisher<T> implements Flow.Publisher<T> {
this.error = throwable;
}
final class PullTask extends SequentialScheduler.CompleteRestartableTask {
final class PullTask implements Runnable {
@Override
protected void run() {
public void run() {
if (completed || cancelled) {
return;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 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
@ -29,15 +29,12 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Flow;
import java.util.concurrent.atomic.AtomicReference;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import java.util.function.Supplier;
import jdk.internal.net.http.common.BufferSupplier;
@ -46,8 +43,6 @@ import jdk.internal.net.http.common.FlowTube;
import jdk.internal.net.http.common.Log;
import jdk.internal.net.http.common.Logger;
import jdk.internal.net.http.common.SequentialScheduler;
import jdk.internal.net.http.common.SequentialScheduler.DeferredCompleter;
import jdk.internal.net.http.common.SequentialScheduler.RestartableTask;
import jdk.internal.net.http.common.Utils;
/**
@ -160,34 +155,6 @@ final class SocketTube implements FlowTube {
new IOException("connection closed locally", cause));
}
/**
* A restartable task used to process tasks in sequence.
*/
private static class SocketFlowTask implements RestartableTask {
final Runnable task;
private final Lock lock = new ReentrantLock();
SocketFlowTask(Runnable task) {
this.task = task;
}
@Override
public final void run(DeferredCompleter taskCompleter) {
try {
// The logics of the sequential scheduler should ensure that
// the restartable task is running in only one thread at
// a given time: there should never be contention.
boolean locked = lock.tryLock();
assert locked : "contention detected in SequentialScheduler";
try {
task.run();
} finally {
if (locked) lock.unlock();
}
} finally {
taskCompleter.complete();
}
}
}
// This is best effort - there's no guarantee that the printed set of values
// is consistent. It should only be considered as weakly accurate - in
// particular in what concerns the events states, especially when displaying
@ -682,7 +649,7 @@ final class SocketTube implements FlowTube {
private final AsyncEvent subscribeEvent;
InternalReadSubscription() {
readScheduler = new SequentialScheduler(new SocketFlowTask(this::read));
readScheduler = SequentialScheduler.lockingScheduler(this::read);
subscribeEvent = new AsyncTriggerEvent(this::signalError,
this::handleSubscribeEvent);
readEvent = new ReadEvent(channel, this);

View File

@ -244,17 +244,10 @@ public class SSLFlowDelegate {
final ReentrantLock readBufferLock = new ReentrantLock();
final Logger debugr = Utils.getDebugLogger(this::dbgString, Utils.DEBUG);
private final class ReaderDownstreamPusher implements Runnable {
@Override
public void run() {
processData();
}
}
Reader() {
super();
scheduler = SequentialScheduler.lockingScheduler(
new ReaderDownstreamPusher());
this::processData);
this.readBuf = ByteBuffer.allocate(1024);
readBuf.limit(0); // keep in read mode
}
@ -588,14 +581,10 @@ public class SSLFlowDelegate {
volatile boolean completing;
boolean completed; // only accessed in processData
class WriterDownstreamPusher extends SequentialScheduler.CompleteRestartableTask {
@Override public void run() { processData(); }
}
Writer() {
super();
writeList = Collections.synchronizedList(new LinkedList<>());
scheduler = new SequentialScheduler(new WriterDownstreamPusher());
scheduler = SequentialScheduler.lockingScheduler(this::processData);
}
@Override

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 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
@ -111,7 +111,7 @@ public final class SequentialScheduler {
* later time, and maybe in different thread. This type exists for
* readability purposes at use-sites only.
*/
public abstract static class DeferredCompleter {
private abstract static class DeferredCompleter {
/** Extensible from this (outer) class ONLY. */
private DeferredCompleter() { }
@ -124,7 +124,7 @@ public final class SequentialScheduler {
* A restartable task.
*/
@FunctionalInterface
public interface RestartableTask {
private interface RestartableTask {
/**
* The body of the task.
@ -140,7 +140,7 @@ public final class SequentialScheduler {
* A simple and self-contained task that completes once its {@code run}
* method returns.
*/
public abstract static class CompleteRestartableTask
private abstract static class CompleteRestartableTask
implements RestartableTask
{
@Override
@ -161,7 +161,7 @@ public final class SequentialScheduler {
* memory visibility between runs. Since the main loop can't run concurrently,
* the lock shouldn't be contended and no deadlock should ever be possible.
*/
public static final class LockingRestartableTask
private static final class LockingRestartableTask
extends CompleteRestartableTask {
private final Runnable mainLoop;
@ -208,7 +208,7 @@ public final class SequentialScheduler {
}
}
public SequentialScheduler(RestartableTask restartableTask) {
private SequentialScheduler(RestartableTask restartableTask) {
this.restartableTask = requireNonNull(restartableTask);
this.completer = new TryEndDeferredCompleter();
this.schedulableTask = new SchedulableTask();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 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
@ -29,7 +29,6 @@ import jdk.internal.net.http.common.Demand;
import jdk.internal.net.http.common.Logger;
import jdk.internal.net.http.common.MinimalFuture;
import jdk.internal.net.http.common.SequentialScheduler;
import jdk.internal.net.http.common.SequentialScheduler.CompleteRestartableTask;
import jdk.internal.net.http.common.Utils;
import java.io.IOException;
@ -58,7 +57,7 @@ public class TransportImpl implements Transport {
/* Used for correlating enters to and exists from a method */
private final AtomicLong counter = new AtomicLong();
private final SequentialScheduler sendScheduler = new SequentialScheduler(new SendTask());
private final SequentialScheduler sendScheduler = SequentialScheduler.lockingScheduler(new SendTask());
private final MessageQueue queue;
private final MessageEncoder encoder = new MessageEncoder();
@ -93,7 +92,7 @@ public class TransportImpl implements Transport {
// To ensure the initial non-final `data` will be visible
// (happens-before) when `readEvent.handle()` invokes `receiveScheduler`
// the following assignment is done last:
receiveScheduler = new SequentialScheduler(new ReceiveTask());
receiveScheduler = SequentialScheduler.lockingScheduler(new ReceiveTask());
}
private ByteBuffer createWriteBuffer() {
@ -361,7 +360,7 @@ public class TransportImpl implements Transport {
}
@SuppressWarnings({"rawtypes"})
private class SendTask extends CompleteRestartableTask {
private class SendTask implements Runnable {
private final MessageQueue.QueueCallback<Boolean, IOException>
encodingCallback = new MessageQueue.QueueCallback<>() {
@ -654,7 +653,7 @@ public class TransportImpl implements Transport {
}
}
private class ReceiveTask extends CompleteRestartableTask {
private class ReceiveTask implements Runnable {
@Override
public void run() {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 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
@ -116,7 +116,7 @@ public final class WebSocketImpl implements WebSocket {
private final AtomicBoolean pendingPingOrPong = new AtomicBoolean();
private final Transport transport;
private final SequentialScheduler receiveScheduler
= new SequentialScheduler(new ReceiveTask());
= SequentialScheduler.lockingScheduler(new ReceiveTask());
private final Demand demand = new Demand();
private final Executor clientExecutor;
@ -416,7 +416,7 @@ public final class WebSocketImpl implements WebSocket {
* - after the state has been observed as CLOSE/ERROR, the scheduler
* is stopped
*/
private class ReceiveTask extends SequentialScheduler.CompleteRestartableTask {
private class ReceiveTask implements Runnable {
// Transport only asked here and nowhere else because we must make sure
// onOpen is invoked first and no messages become pending before onOpen

View File

@ -1,10 +0,0 @@
grant {
permission javax.security.auth.AuthPermission "modifyPrincipals";
permission javax.security.auth.AuthPermission "doAsPrivileged";
permission java.util.PropertyPermission "*", "read,write";
};
grant Principal MyPrincipal "test" {
permission java.net.SocketPermission "${host.name}", "resolve";
};

View File

@ -1,3 +0,0 @@
grant {
};

View File

@ -1,4 +0,0 @@
grant {
permission java.lang.RuntimePermission "setFactory";
};

View File

@ -74,7 +74,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
* @build jdk.test.lib.net.SimpleSSLContext jdk.test.lib.RandomFactory jdk.test.lib.net.URIBuilder
* @comment An arbitrary high value for idle connection timeout to prevent idle
* connection management from closing the HTTP/2 connection
* @run junit/othervm -Djdk.httpclient.keepalive.timeout.h2=36000 ${test.main.class}
* @run junit/othervm -Djdk.httpclient.keepalive.timeout.h2=36000
* -Djdk.internal.httpclient.debug=true
* ${test.main.class}
*/
class H2GoAwayPromptConnectionClose {

View File

@ -265,7 +265,7 @@ public class SSLEchoTubeTest extends AbstractSSLTubeTest {
private final Queue<Object> queue = new ConcurrentLinkedQueue<>();
private final int maxQueueSize;
private final SequentialScheduler processingScheduler =
new SequentialScheduler(createProcessingTask());
SequentialScheduler.lockingScheduler(createProcessingTask());
/* Writing into this tube */
private volatile long requested;
@ -360,11 +360,11 @@ public class SSLEchoTubeTest extends AbstractSSLTubeTest {
}
int transmitted = 0;
private SequentialScheduler.RestartableTask createProcessingTask() {
return new SequentialScheduler.CompleteRestartableTask() {
private Runnable createProcessingTask() {
return new Runnable() {
@Override
protected void run() {
public void run() {
try {
while (!cancelled.get()) {
Object item = queue.peek();
@ -374,39 +374,36 @@ public class SSLEchoTubeTest extends AbstractSSLTubeTest {
requestMore();
return;
}
try {
System.out.printf("EchoTube processing item, requested=%s, demand=%s, transmitted=%s%n",
requested, demand.get(), transmitted);
if (item instanceof List) {
if (!demand.tryDecrement()) {
System.out.println("EchoTube no demand");
return;
}
@SuppressWarnings("unchecked")
List<ByteBuffer> bytes = (List<ByteBuffer>) item;
Object removed = queue.remove();
assert removed == item;
System.out.println("EchoTube processing "
+ Utils.remaining(bytes));
transmitted++;
subscriber.onNext(bytes);
requestMore();
} else if (item instanceof Throwable) {
cancelled.set(true);
Object removed = queue.remove();
assert removed == item;
System.out.println("EchoTube processing " + item);
subscriber.onError((Throwable) item);
} else if (item == EOF) {
cancelled.set(true);
Object removed = queue.remove();
assert removed == item;
System.out.println("EchoTube processing EOF");
subscriber.onComplete();
} else {
throw new InternalError(String.valueOf(item));
System.out.printf("EchoTube processing item, requested=%s, demand=%s, transmitted=%s%n",
requested, demand.get(), transmitted);
if (item instanceof List) {
if (!demand.tryDecrement()) {
System.out.println("EchoTube no demand");
return;
}
} finally {
@SuppressWarnings("unchecked")
List<ByteBuffer> bytes = (List<ByteBuffer>) item;
Object removed = queue.remove();
assert removed == item;
System.out.println("EchoTube processing "
+ Utils.remaining(bytes));
transmitted++;
subscriber.onNext(bytes);
requestMore();
} else if (item instanceof Throwable) {
cancelled.set(true);
Object removed = queue.remove();
assert removed == item;
System.out.println("EchoTube processing " + item);
subscriber.onError((Throwable) item);
} else if (item == EOF) {
cancelled.set(true);
Object removed = queue.remove();
assert removed == item;
System.out.println("EchoTube processing EOF");
subscriber.onComplete();
} else {
throw new InternalError(String.valueOf(item));
}
}
} catch(Throwable t) {