Merge
This commit is contained in:
commit
c79baaa811
@ -32,15 +32,9 @@
|
||||
frame JavaThread::pd_last_frame() {
|
||||
assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
|
||||
|
||||
intptr_t* sp = last_Java_sp();
|
||||
intptr_t* sp = Atomic::load_acquire(&_anchor._last_Java_sp);
|
||||
address pc = _anchor.last_Java_pc();
|
||||
|
||||
// Last_Java_pc is not set, if we come here from compiled code.
|
||||
// Assume spill slot for link register contains a suitable pc.
|
||||
// Should have been filled by method entry code.
|
||||
if (pc == NULL)
|
||||
pc = (address) *(sp + 2);
|
||||
|
||||
return frame(sp, pc);
|
||||
}
|
||||
|
||||
|
@ -31,16 +31,9 @@
|
||||
frame JavaThread::pd_last_frame() {
|
||||
assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
|
||||
|
||||
intptr_t* sp = last_Java_sp();
|
||||
intptr_t* sp = Atomic::load_acquire(&_anchor._last_Java_sp);
|
||||
address pc = _anchor.last_Java_pc();
|
||||
|
||||
// Last_Java_pc is not set, if we come here from compiled code.
|
||||
// Assume spill slot for link register contains a suitable pc.
|
||||
// Should have been filled by method entry code.
|
||||
if (pc == NULL) {
|
||||
pc = (address) *(sp + 2);
|
||||
}
|
||||
|
||||
return frame(sp, pc);
|
||||
}
|
||||
|
||||
|
@ -693,7 +693,7 @@ void G1ConcurrentMark::clear_bitmap(WorkerThreads* workers, bool may_yield) {
|
||||
|
||||
log_debug(gc, ergo)("Running %s with %u workers for " SIZE_FORMAT " work units.", cl.name(), num_workers, num_chunks);
|
||||
workers->run_task(&cl, num_workers);
|
||||
guarantee(!may_yield || cl.is_complete(), "Must have completed iteration when not yielding.");
|
||||
guarantee(may_yield || cl.is_complete(), "Must have completed iteration when not yielding.");
|
||||
}
|
||||
|
||||
void G1ConcurrentMark::cleanup_for_next_mark() {
|
||||
|
@ -417,12 +417,11 @@ class ThreadLocalCheckpointWriteOp {
|
||||
};
|
||||
|
||||
typedef CheckpointWriteOp<JfrCheckpointManager::Buffer> WriteOperation;
|
||||
typedef ThreadLocalCheckpointWriteOp<JfrCheckpointManager::Buffer> ThreadLocalWriteOperation;
|
||||
typedef MutexedWriteOp<WriteOperation> MutexedWriteOperation;
|
||||
typedef MutexedWriteOp<ThreadLocalWriteOperation> ThreadLocalMutexedWriteOperation;
|
||||
typedef ThreadLocalCheckpointWriteOp<JfrCheckpointManager::Buffer> ThreadLocalCheckpointOperation;
|
||||
typedef MutexedWriteOp<ThreadLocalCheckpointOperation> ThreadLocalWriteOperation;
|
||||
typedef ReleaseWithExcisionOp<JfrCheckpointMspace, JfrCheckpointMspace::LiveList> ReleaseOperation;
|
||||
typedef CompositeOperation<MutexedWriteOperation, ReleaseOperation> WriteReleaseOperation;
|
||||
typedef CompositeOperation<ThreadLocalMutexedWriteOperation, ReleaseOperation> ThreadLocalWriteReleaseOperation;
|
||||
typedef ExclusiveOp<WriteOperation> GlobalWriteOperation;
|
||||
typedef CompositeOperation<GlobalWriteOperation, ReleaseOperation> GlobalWriteReleaseOperation;
|
||||
|
||||
void JfrCheckpointManager::begin_epoch_shift() {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "invariant");
|
||||
@ -439,31 +438,33 @@ void JfrCheckpointManager::end_epoch_shift() {
|
||||
size_t JfrCheckpointManager::write() {
|
||||
DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(JavaThread::current()));
|
||||
WriteOperation wo(_chunkwriter);
|
||||
MutexedWriteOperation mwo(wo);
|
||||
GlobalWriteOperation gwo(wo);
|
||||
assert(_global_mspace->free_list_is_empty(), "invariant");
|
||||
ReleaseOperation ro(_global_mspace, _global_mspace->live_list(true));
|
||||
WriteReleaseOperation wro(&mwo, &ro);
|
||||
process_live_list(wro, _global_mspace, true); // previous epoch list
|
||||
// Do thread local list after global. Careful, the tlwo destructor writes to chunk.
|
||||
ThreadLocalWriteOperation tlwo(_chunkwriter);
|
||||
ThreadLocalMutexedWriteOperation tlmwo(tlwo);
|
||||
_thread_local_mspace->iterate(tlmwo, true); // previous epoch list
|
||||
return wo.processed() + tlwo.processed();
|
||||
GlobalWriteReleaseOperation gwro(&gwo, &ro);
|
||||
process_live_list(gwro, _global_mspace, true); // previous epoch list
|
||||
// Do thread local list after global. Careful, the tlco destructor writes to chunk.
|
||||
ThreadLocalCheckpointOperation tlco(_chunkwriter);
|
||||
ThreadLocalWriteOperation tlwo(tlco);
|
||||
_thread_local_mspace->iterate(tlwo, true); // previous epoch list
|
||||
return wo.processed() + tlco.processed();
|
||||
}
|
||||
|
||||
typedef DiscardOp<DefaultDiscarder<JfrCheckpointManager::Buffer> > DiscardOperation;
|
||||
typedef CompositeOperation<DiscardOperation, ReleaseOperation> DiscardReleaseOperation;
|
||||
typedef DiscardOp<DefaultDiscarder<JfrCheckpointManager::Buffer> > ThreadLocalDiscardOperation;
|
||||
typedef ExclusiveDiscardOp<DefaultDiscarder<JfrCheckpointManager::Buffer> > GlobalDiscardOperation;
|
||||
typedef CompositeOperation<GlobalDiscardOperation, ReleaseOperation> DiscardReleaseOperation;
|
||||
|
||||
size_t JfrCheckpointManager::clear() {
|
||||
JfrTraceIdLoadBarrier::clear();
|
||||
clear_type_set();
|
||||
DiscardOperation discard_operation(mutexed); // mutexed discard mode
|
||||
_thread_local_mspace->iterate(discard_operation, true); // previous epoch list
|
||||
ReleaseOperation ro(_global_mspace, _global_mspace->live_list(true));
|
||||
DiscardReleaseOperation discard_op(&discard_operation, &ro);
|
||||
ThreadLocalDiscardOperation tldo(mutexed); // mutexed discard mode
|
||||
_thread_local_mspace->iterate(tldo, true); // previous epoch list
|
||||
GlobalDiscardOperation gdo(mutexed); // mutexed discard mode
|
||||
ReleaseOperation ro(_global_mspace, _global_mspace->live_list(true)); // previous epoch list
|
||||
DiscardReleaseOperation dro(&gdo, &ro);
|
||||
assert(_global_mspace->free_list_is_empty(), "invariant");
|
||||
process_live_list(discard_op, _global_mspace, true); // previous epoch list
|
||||
return discard_operation.elements();
|
||||
process_live_list(dro, _global_mspace, true); // previous epoch list
|
||||
return tldo.elements() + gdo.elements();
|
||||
}
|
||||
|
||||
size_t JfrCheckpointManager::write_static_type_set(Thread* thread) {
|
||||
@ -560,14 +561,17 @@ size_t JfrCheckpointManager::flush_type_set() {
|
||||
}
|
||||
}
|
||||
if (_new_checkpoint.is_signaled_with_reset()) {
|
||||
assert(_global_mspace->free_list_is_empty(), "invariant");
|
||||
assert(_global_mspace->live_list_is_nonempty(), "invariant");
|
||||
WriteOperation wo(_chunkwriter);
|
||||
MutexedWriteOperation mwo(wo);
|
||||
process_live_list(mwo, _global_mspace); // current epoch list
|
||||
// Do thread local list after global. Careful, the tlwo destructor writes to chunk.
|
||||
ThreadLocalWriteOperation tlwo(_chunkwriter);
|
||||
ThreadLocalMutexedWriteOperation tlmwo(tlwo);
|
||||
_thread_local_mspace->iterate(tlmwo); // current epoch list
|
||||
GlobalWriteOperation gwo(wo);
|
||||
ReleaseOperation ro(_global_mspace, _global_mspace->live_list()); // current epoch list
|
||||
GlobalWriteReleaseOperation gwro(&gwo, &ro);
|
||||
process_live_list(gwro, _global_mspace); // current epoch list
|
||||
// Do thread local list after global. Careful, the tlco destructor writes to chunk.
|
||||
ThreadLocalCheckpointOperation tlco(_chunkwriter);
|
||||
ThreadLocalWriteOperation tlwo(tlco);
|
||||
_thread_local_mspace->iterate(tlwo); // current epoch list
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
@ -154,9 +154,11 @@ class PredicatedConcurrentWriteOp : public ConcurrentWriteOp<Operation> {
|
||||
|
||||
template <typename Operation>
|
||||
class ExclusiveOp : private MutexedWriteOp<Operation> {
|
||||
private:
|
||||
Thread* const _thread;
|
||||
public:
|
||||
typedef typename Operation::Type Type;
|
||||
ExclusiveOp(Operation& operation) : MutexedWriteOp<Operation>(operation) {}
|
||||
ExclusiveOp(Operation& operation);
|
||||
bool process(Type* t);
|
||||
size_t processed() const { return MutexedWriteOp<Operation>::processed(); }
|
||||
};
|
||||
@ -181,9 +183,11 @@ class DiscardOp {
|
||||
|
||||
template <typename Operation>
|
||||
class ExclusiveDiscardOp : private DiscardOp<Operation> {
|
||||
private:
|
||||
Thread* const _thread;
|
||||
public:
|
||||
typedef typename Operation::Type Type;
|
||||
ExclusiveDiscardOp(jfr_operation_mode mode = concurrent) : DiscardOp<Operation>(mode) {}
|
||||
ExclusiveDiscardOp(jfr_operation_mode mode = concurrent);
|
||||
bool process(Type* t);
|
||||
size_t processed() const { return DiscardOp<Operation>::processed(); }
|
||||
size_t elements() const { return DiscardOp<Operation>::elements(); }
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2022, 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
|
||||
@ -91,12 +91,13 @@ inline bool MutexedWriteOp<Operation>::process(typename Operation::Type* t) {
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
static void retired_sensitive_acquire(Type* t) {
|
||||
static void retired_sensitive_acquire(Type* t, Thread* thread) {
|
||||
assert(t != NULL, "invariant");
|
||||
assert(thread != nullptr, "invariant");
|
||||
assert(thread == Thread::current(), "invariant");
|
||||
if (t->retired()) {
|
||||
return;
|
||||
}
|
||||
Thread* const thread = Thread::current();
|
||||
while (!t->try_acquire(thread)) {
|
||||
if (t->retired()) {
|
||||
return;
|
||||
@ -104,11 +105,14 @@ static void retired_sensitive_acquire(Type* t) {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Operation>
|
||||
inline ExclusiveOp<Operation>::ExclusiveOp(Operation& operation) : MutexedWriteOp<Operation>(operation), _thread(Thread::current()) {}
|
||||
|
||||
template <typename Operation>
|
||||
inline bool ExclusiveOp<Operation>::process(typename Operation::Type* t) {
|
||||
retired_sensitive_acquire(t);
|
||||
retired_sensitive_acquire(t, _thread);
|
||||
assert(t->acquired_by_self() || t->retired(), "invariant");
|
||||
// User is required to ensure proper release of the acquisition
|
||||
// The user is required to ensure proper release of the acquisition.
|
||||
return MutexedWriteOp<Operation>::process(t);
|
||||
}
|
||||
|
||||
@ -133,11 +137,14 @@ inline bool DiscardOp<Operation>::process(typename Operation::Type* t) {
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Operation>
|
||||
inline ExclusiveDiscardOp<Operation>::ExclusiveDiscardOp(jfr_operation_mode mode) : DiscardOp<Operation>(mode), _thread(Thread::current()) {}
|
||||
|
||||
template <typename Operation>
|
||||
inline bool ExclusiveDiscardOp<Operation>::process(typename Operation::Type* t) {
|
||||
retired_sensitive_acquire(t);
|
||||
retired_sensitive_acquire(t, _thread);
|
||||
assert(t->acquired_by_self() || t->retired(), "invariant");
|
||||
// User is required to ensure proper release of the acquisition
|
||||
// The user is required to ensure proper release of the acquisition.
|
||||
return DiscardOp<Operation>::process(t);
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ import java.lang.invoke.MethodType;
|
||||
* is currently executing. This linker also provides access, via its {@linkplain #defaultLookup() default lookup},
|
||||
* to the native libraries loaded with the Java runtime.
|
||||
*
|
||||
* <h2><a id = "downcall-method-handles">Downcall method handles</a></h2>
|
||||
* <h2 id="downcall-method-handles">Downcall method handles</h2>
|
||||
*
|
||||
* {@linkplain #downcallHandle(FunctionDescriptor) Linking a foreign function} is a process which requires a function descriptor,
|
||||
* a set of memory layouts which, together, specify the signature of the foreign function to be linked, and returns,
|
||||
@ -91,7 +91,7 @@ import java.lang.invoke.MethodType;
|
||||
* memory region associated with the struct returned by the downcall method handle.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h2><a id = "upcall-stubs">Upcall stubs</a></h2>
|
||||
* <h2 id="upcall-stubs">Upcall stubs</h2>
|
||||
*
|
||||
* {@linkplain #upcallStub(MethodHandle, FunctionDescriptor, MemorySession) Creating an upcall stub} requires a method
|
||||
* handle and a function descriptor; in this case, the set of memory layouts in the function descriptor
|
||||
@ -114,7 +114,7 @@ import java.lang.invoke.MethodType;
|
||||
* downcall method handles (as {@link MemorySegment} implements the {@link Addressable} interface) and,
|
||||
* when no longer required, they can be {@linkplain MemorySession#close() released}, via their associated {@linkplain MemorySession session}.
|
||||
*
|
||||
* <h2>Safety considerations</h2>
|
||||
* <h2 id="safety">Safety considerations</h2>
|
||||
*
|
||||
* Creating a downcall method handle is intrinsically unsafe. A symbol in a foreign library does not, in general,
|
||||
* contain enough signature information (e.g. arity and types of foreign function parameters). As a consequence,
|
||||
|
@ -44,7 +44,7 @@ import java.lang.invoke.MethodHandle;
|
||||
* </ul>
|
||||
* A memory address is backed by a raw machine pointer, expressed as a {@linkplain #toRawLongValue() long value}.
|
||||
*
|
||||
* <h2>Dereferencing memory addresses</h2>
|
||||
* <h2 id="dereferencing">Dereferencing memory addresses</h2>
|
||||
*
|
||||
* A memory address can be read or written using various methods provided in this class (e.g. {@link #get(ValueLayout.OfInt, long)}).
|
||||
* Each dereference method takes a {@linkplain ValueLayout value layout}, which specifies the size,
|
||||
|
@ -77,7 +77,7 @@ import jdk.internal.javac.PreviewFeature;
|
||||
* ).withName("TaggedValues");
|
||||
* }
|
||||
*
|
||||
* <h2><a id = "layout-align">Size, alignment and byte order</a></h2>
|
||||
* <h2 id="layout-align">Size, alignment and byte order</h2>
|
||||
*
|
||||
* All layouts have a size; layout size for value and padding layouts is always explicitly denoted; this means that a layout description
|
||||
* always has the same size in bits, regardless of the platform in which it is used. For derived layouts, the size is computed
|
||||
@ -105,7 +105,7 @@ import jdk.internal.javac.PreviewFeature;
|
||||
* <p>
|
||||
* All value layouts have an <em>explicit</em> byte order (see {@link java.nio.ByteOrder}) which is set when the layout is created.
|
||||
*
|
||||
* <h2><a id = "layout-paths">Layout paths</a></h2>
|
||||
* <h2 id="layout-paths">Layout paths</h2>
|
||||
*
|
||||
* A <em>layout path</em> originates from a <em>root</em> layout (typically a group or a sequence layout) and terminates
|
||||
* at a layout nested within the root layout - this is the layout <em>selected</em> by the layout path.
|
||||
|
@ -69,7 +69,7 @@ import jdk.internal.vm.annotation.ForceInline;
|
||||
* {@link ByteBuffer#allocateDirect(int)} method will be backed by off-heap memory.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h2>Lifecycle and confinement</h2>
|
||||
* <h2 id="lifecyle-confinement">Lifecycle and confinement</h2>
|
||||
*
|
||||
* Memory segments are associated with a {@linkplain MemorySegment#session() memory session}. As for all resources associated
|
||||
* with a memory session, a segment cannot be accessed after its underlying session has been closed. For instance,
|
||||
@ -91,7 +91,7 @@ import jdk.internal.vm.annotation.ForceInline;
|
||||
* from byte buffer instances obtained calling the {@link #asByteBuffer()} method on a memory segment {@code S}
|
||||
* are associated with the same memory session as {@code S}.
|
||||
*
|
||||
* <h2><a id = "segment-deref">Dereferencing memory segments</a></h2>
|
||||
* <h2 id="segment-deref">Dereferencing memory segments</h2>
|
||||
*
|
||||
* A memory segment can be read or written using various methods provided in this class (e.g. {@link #get(ValueLayout.OfInt, long)}).
|
||||
* Each dereference method takes a {@linkplain ValueLayout value layout}, which specifies the size,
|
||||
@ -136,7 +136,7 @@ import jdk.internal.vm.annotation.ForceInline;
|
||||
* intHandle.get(segment, 3L); // get int element at offset 3 * 4 = 12
|
||||
* }
|
||||
*
|
||||
* <h2>Slicing memory segments</h2>
|
||||
* <h2 id="slicing">Slicing memory segments</h2>
|
||||
*
|
||||
* Memory segments support <em>slicing</em>. A memory segment can be used to {@linkplain MemorySegment#asSlice(long, long) obtain}
|
||||
* other segments backed by the same underlying memory region, but with <em>stricter</em> spatial bounds than the ones
|
||||
@ -220,7 +220,7 @@ import jdk.internal.vm.annotation.ForceInline;
|
||||
* constructed from a {@code byte[]} might have a subset of addresses {@code S} which happen to be 8-byte aligned. But determining
|
||||
* which segment addresses belong to {@code S} requires reasoning about details which are ultimately implementation-dependent.
|
||||
*
|
||||
* <h2>Restricted memory segments</h2>
|
||||
* <h2 id="restricted-segments">Restricted memory segments</h2>
|
||||
* Sometimes it is necessary to turn a memory address obtained from native code into a memory segment with
|
||||
* full spatial, temporal and confinement bounds. To do this, clients can {@linkplain #ofAddress(MemoryAddress, long, MemorySession) obtain}
|
||||
* a native segment <em>unsafely</em> from a give memory address, by providing the segment size, as well as the segment {@linkplain MemorySession session}.
|
||||
@ -737,6 +737,12 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
|
||||
* sequences with this charset's default replacement string. The {@link
|
||||
* java.nio.charset.CharsetDecoder} class should be used when more control
|
||||
* over the decoding process is required.
|
||||
* <p>
|
||||
* If the given string contains any {@code '\0'} characters, they will be
|
||||
* copied as well. This means that, depending on the method used to read
|
||||
* the string, such as {@link MemorySegment#getUtf8String(long)}, the string
|
||||
* will appear truncated when read again.
|
||||
*
|
||||
* @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@linkplain #isNative() native} segment,
|
||||
* the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
|
||||
* @param str the Java string to be written into this segment.
|
||||
|
@ -51,7 +51,7 @@ import jdk.internal.javac.PreviewFeature;
|
||||
* As a result, resources associated with the global session are never released. Examples of resources associated with
|
||||
* the global memory session are {@linkplain MemorySegment#ofArray(int[]) heap segments}.
|
||||
*
|
||||
* <h2><a id = "thread-confinement">Thread confinement</a></h2>
|
||||
* <h2 id = "thread-confinement">Thread confinement</h2>
|
||||
*
|
||||
* Memory sessions can be divided into two categories: <em>thread-confined</em> memory sessions, and <em>shared</em>
|
||||
* memory sessions.
|
||||
@ -66,7 +66,7 @@ import jdk.internal.javac.PreviewFeature;
|
||||
* can be accessed by multiple threads. This might be useful when multiple threads need to access the same resource concurrently
|
||||
* (e.g. in the case of parallel processing).
|
||||
*
|
||||
* <h2>Closeable memory sessions</h2>
|
||||
* <h2 id="closeable">Closeable memory sessions</h2>
|
||||
*
|
||||
* When a session is associated with off-heap resources, it is often desirable for said resources to be released in a timely fashion,
|
||||
* rather than waiting for the session to be deemed <a href="../../../java/lang/ref/package.html#reachability">unreachable</a>
|
||||
@ -96,7 +96,7 @@ import jdk.internal.javac.PreviewFeature;
|
||||
* the session becomes unreachable; that is, {@linkplain #addCloseAction(Runnable) close actions} associated with a
|
||||
* memory session, whether managed or not, are called <em>exactly once</em>.
|
||||
*
|
||||
* <h2>Non-closeable views</h2>
|
||||
* <h2 id="non-closeable">Non-closeable views</h2>
|
||||
*
|
||||
* There are situations in which it might not be desirable for a memory session to be reachable from one or
|
||||
* more resources associated with it. For instance, an API might create a private memory session, and allocate
|
||||
|
@ -71,6 +71,11 @@ public interface SegmentAllocator {
|
||||
* sequences with this charset's default replacement byte array. The
|
||||
* {@link java.nio.charset.CharsetEncoder} class should be used when more
|
||||
* control over the encoding process is required.
|
||||
* <p>
|
||||
* If the given string contains any {@code '\0'} characters, they will be
|
||||
* copied as well. This means that, depending on the method used to read
|
||||
* the string, such as {@link MemorySegment#getUtf8String(long)}, the string
|
||||
* will appear truncated when read again.
|
||||
*
|
||||
* @implSpec the default implementation for this method copies the contents of the provided Java string
|
||||
* into a new memory segment obtained by calling {@code this.allocate(str.length() + 1)}.
|
||||
|
@ -57,7 +57,7 @@ import java.util.function.BiFunction;
|
||||
* {@link MemorySegment#ofAddress(MemoryAddress, long, MemorySession) resizing} the segment first).</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h2>Obtaining a symbol lookup</h2>
|
||||
* <h2 id="obtaining">Obtaining a symbol lookup</h2>
|
||||
*
|
||||
* The factory methods {@link #libraryLookup(String, MemorySession)} and {@link #libraryLookup(Path, MemorySession)}
|
||||
* create a symbol lookup for a library known to the operating system. The library is specified by either its name or a path.
|
||||
|
@ -27,7 +27,7 @@
|
||||
/**
|
||||
* <p>Provides low-level access to memory and functions outside the Java runtime.
|
||||
*
|
||||
* <h2>Foreign memory access</h2>
|
||||
* <h2 id="fma">Foreign memory access</h2>
|
||||
*
|
||||
* <p>
|
||||
* The main abstraction introduced to support foreign memory access is {@link java.lang.foreign.MemorySegment}, which
|
||||
@ -58,7 +58,7 @@
|
||||
* where the size of each slot is exactly 4 bytes, the initialization logic above will set each slot
|
||||
* so that {@code s[i] = i}, again where {@code 0 <= i < 10}.
|
||||
*
|
||||
* <h3><a id="deallocation"></a>Deterministic deallocation</h3>
|
||||
* <h3 id="deallocation">Deterministic deallocation</h3>
|
||||
*
|
||||
* When writing code that manipulates memory segments, especially if backed by memory which resides outside the Java heap, it is
|
||||
* often crucial that the resources associated with a memory segment are released when the segment is no longer in use,
|
||||
@ -81,7 +81,7 @@
|
||||
* <em>try-with-resources</em> construct: this idiom ensures that all the memory resources associated with the segment will be released
|
||||
* at the end of the block, according to the semantics described in Section {@jls 14.20.3} of <cite>The Java Language Specification</cite>.
|
||||
*
|
||||
* <h3><a id="safety"></a>Safety</h3>
|
||||
* <h3 id="safety">Safety</h3>
|
||||
*
|
||||
* This API provides strong safety guarantees when it comes to memory access. First, when dereferencing a memory segment,
|
||||
* the access coordinates are validated (upon access), to make sure that access does not occur at any address which resides
|
||||
@ -94,7 +94,7 @@
|
||||
* We call this guarantee <em>temporal safety</em>. Together, spatial and temporal safety ensure that each memory access
|
||||
* operation either succeeds - and accesses a valid memory location - or fails.
|
||||
*
|
||||
* <h2>Foreign function access</h2>
|
||||
* <h2 id="ffa">Foreign function access</h2>
|
||||
* The key abstractions introduced to support foreign function access are {@link java.lang.foreign.SymbolLookup},
|
||||
* {@link java.lang.foreign.FunctionDescriptor} and {@link java.lang.foreign.Linker}. The first is used to look up symbols
|
||||
* inside libraries; the second is used to model the signature of foreign functions, while the third provides
|
||||
@ -134,7 +134,7 @@
|
||||
* {@linkplain java.lang.foreign.MemorySegment#setUtf8String(long, java.lang.String) into} zero-terminated, UTF-8 strings and
|
||||
* {@linkplain java.lang.foreign.MemorySegment#getUtf8String(long) back}, as demonstrated in the above example.
|
||||
*
|
||||
* <h3>Foreign addresses</h3>
|
||||
* <h3 id="addresses">Foreign addresses</h3>
|
||||
*
|
||||
* When a memory segment is created from Java code, the segment properties (spatial bounds, temporal bounds and confinement)
|
||||
* are fully known at segment creation. But when interacting with foreign functions, clients will often receive <em>raw</em> pointers.
|
||||
@ -165,7 +165,7 @@
|
||||
* int x = segment.get(ValueLayout.JAVA_INT, 0);
|
||||
* }
|
||||
*
|
||||
* <h3>Upcalls</h3>
|
||||
* <h3 id="upcalls">Upcalls</h3>
|
||||
* The {@link java.lang.foreign.Linker} interface also allows clients to turn an existing method handle (which might point
|
||||
* to a Java method) into a memory address, so that Java code can effectively be passed to other foreign functions.
|
||||
* For instance, we can write a method that compares two integer values, as follows:
|
||||
@ -213,8 +213,7 @@
|
||||
* provided when the upcall stub is created. This same session is made available by the {@link java.lang.foreign.MemorySegment}
|
||||
* instance returned by that method.
|
||||
*
|
||||
* <a id="restricted"></a>
|
||||
* <h2>Restricted methods</h2>
|
||||
* <h2 id="restricted">Restricted methods</h2>
|
||||
* Some methods in this package are considered <em>restricted</em>. Restricted methods are typically used to bind native
|
||||
* foreign data and/or functions to first-class Java API elements which can then be used directly by clients. For instance
|
||||
* the restricted method {@link java.lang.foreign.MemorySegment#ofAddress(MemoryAddress, long, MemorySession)}
|
||||
|
@ -2571,7 +2571,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||
* without resizing the map.
|
||||
*
|
||||
* @param numMappings the expected number of mappings
|
||||
* @param <K> the type of keys maintained by this map
|
||||
* @param <K> the type of keys maintained by the new map
|
||||
* @param <V> the type of mapped values
|
||||
* @return the newly created map
|
||||
* @throws IllegalArgumentException if numMappings is negative
|
||||
|
@ -803,7 +803,7 @@ public class LinkedHashMap<K,V>
|
||||
* without resizing the map.
|
||||
*
|
||||
* @param numMappings the expected number of mappings
|
||||
* @param <K> the type of keys maintained by this map
|
||||
* @param <K> the type of keys maintained by the new map
|
||||
* @param <V> the type of mapped values
|
||||
* @return the newly created map
|
||||
* @throws IllegalArgumentException if numMappings is negative
|
||||
|
@ -1350,7 +1350,7 @@ public class WeakHashMap<K,V>
|
||||
* without resizing the map.
|
||||
*
|
||||
* @param numMappings the expected number of mappings
|
||||
* @param <K> the type of keys maintained by this map
|
||||
* @param <K> the type of keys maintained by the new map
|
||||
* @param <V> the type of mapped values
|
||||
* @return the newly created map
|
||||
* @throws IllegalArgumentException if numMappings is negative
|
||||
|
@ -407,7 +407,9 @@
|
||||
* <tr>
|
||||
* <th scope="row" style="font-weight:normal" id="XPATH">XPath</th>
|
||||
* <td style="text-align:center">XPath</td>
|
||||
* <td>N/A
|
||||
* <td>
|
||||
* {@code XPathFactory factory = XPathFactory.newInstance();}<br>
|
||||
* {@code factory.setProperty(name, value);}
|
||||
* </td>
|
||||
* <td>
|
||||
* {@code XPathFactory factory = XPathFactory.newInstance();} <br>
|
||||
@ -616,7 +618,7 @@
|
||||
* <td style="text-align:center">9</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td id="extensionClassLoader">jdk.xml.xpathExprGrpLimit</td>
|
||||
* <td id="xpathExprGrpLimit">jdk.xml.xpathExprGrpLimit</td>
|
||||
* <td>Limits the number of groups an XPath expression can contain.
|
||||
* </td>
|
||||
* <td style="text-align:center" rowspan="2">
|
||||
@ -638,14 +640,14 @@
|
||||
* <td style="text-align:center" rowspan="3">19</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td id="extensionClassLoader">jdk.xml.xpathExprOpLimit</td>
|
||||
* <td id="xpathExprGrpLimit">jdk.xml.xpathExprGrpLimit</td>
|
||||
* <td>Limits the number of operators an XPath expression can contain.
|
||||
* </td>
|
||||
* <td style="text-align:center">100</td>
|
||||
* <td style="text-align:center">100</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td id="extensionClassLoader">jdk.xml.xpathTotalOpLimit</td>
|
||||
* <td id="xpathTotalOpLimit">jdk.xml.xpathTotalOpLimit</td>
|
||||
* <td>Limits the total number of XPath operators in an XSL Stylesheet.
|
||||
* </td>
|
||||
* <td style="text-align:center">yes</td>
|
||||
|
@ -4351,6 +4351,9 @@ public class Check {
|
||||
wasDefault = true;
|
||||
} else {
|
||||
JCPattern pat = ((JCPatternCaseLabel) label).pat;
|
||||
while (pat instanceof JCParenthesizedPattern parenthesized) {
|
||||
pat = parenthesized.pattern;
|
||||
}
|
||||
boolean isTypePattern = pat.hasTag(BINDINGPATTERN);
|
||||
if (wasPattern || wasConstant || wasDefault ||
|
||||
(wasNullPattern && (!isTypePattern || wasNonEmptyFallThrough))) {
|
||||
|
@ -531,7 +531,21 @@ public class TransPatterns extends TreeTranslator {
|
||||
currentValue = temp;
|
||||
JCExpression test = (JCExpression) this.<JCTree>translate(label.pat);
|
||||
if (label.guard != null) {
|
||||
test = makeBinary(Tag.AND, test, translate(label.guard));
|
||||
JCExpression guard = translate(label.guard);
|
||||
if (hasJoinedNull) {
|
||||
JCPattern pattern = label.pat;
|
||||
while (pattern instanceof JCParenthesizedPattern parenthesized) {
|
||||
pattern = parenthesized.pattern;
|
||||
}
|
||||
Assert.check(pattern.hasTag(Tag.BINDINGPATTERN));
|
||||
VarSymbol binding = ((JCBindingPattern) pattern).var.sym;
|
||||
guard = makeBinary(Tag.OR,
|
||||
makeBinary(Tag.EQ,
|
||||
make.Ident(binding),
|
||||
makeNull()),
|
||||
guard);
|
||||
}
|
||||
test = makeBinary(Tag.AND, test, guard);
|
||||
}
|
||||
c.stats = translate(c.stats);
|
||||
JCContinue continueSwitch = make.at(clearedPatterns.head.pos()).Continue(null);
|
||||
|
@ -38,7 +38,9 @@ import static jdk.jpackage.internal.StandardBundlerParam.SIGN_BUNDLE;
|
||||
|
||||
public class MacAppBundler extends AppImageBundler {
|
||||
public MacAppBundler() {
|
||||
setAppImageSupplier(MacAppImageBuilder::new);
|
||||
setAppImageSupplier(imageOutDir -> {
|
||||
return new MacAppImageBuilder(imageOutDir, isDependentTask());
|
||||
});
|
||||
setParamsValidator(MacAppBundler::doValidate);
|
||||
}
|
||||
|
||||
|
@ -90,6 +90,8 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
|
||||
private final Path runtimeDir;
|
||||
private final Path runtimeRoot;
|
||||
|
||||
private final boolean withPackageFile;
|
||||
|
||||
private static List<String> keyChains;
|
||||
|
||||
public static final BundlerParamInfo<Boolean>
|
||||
@ -243,10 +245,11 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
|
||||
(s, p) -> Arrays.asList(s.split("(,|\\s)+"))
|
||||
);
|
||||
|
||||
public MacAppImageBuilder(Path imageOutDir) {
|
||||
public MacAppImageBuilder(Path imageOutDir, boolean withPackageFile) {
|
||||
super(imageOutDir);
|
||||
|
||||
this.root = imageOutDir;
|
||||
this.withPackageFile = withPackageFile;
|
||||
this.contentsDir = root.resolve("Contents");
|
||||
this.resourcesDir = appLayout.destktopIntegrationDirectory();
|
||||
this.macOSDir = appLayout.launchersDirectory();
|
||||
@ -309,6 +312,11 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
|
||||
// Copy class path entries to Java folder
|
||||
copyApplication(params);
|
||||
|
||||
if (withPackageFile) {
|
||||
new PackageFile(APP_NAME.fetchFrom(params)).save(
|
||||
ApplicationLayout.macAppImage().resolveAt(root));
|
||||
}
|
||||
|
||||
/*********** Take care of "config" files *******/
|
||||
|
||||
createResource(TEMPLATE_BUNDLE_ICON, params)
|
||||
|
@ -29,6 +29,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.LinkOption;
|
||||
import java.nio.file.Path;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
@ -113,7 +114,8 @@ public abstract class MacBaseInstallerBundler extends AbstractBundler {
|
||||
}
|
||||
|
||||
public MacBaseInstallerBundler() {
|
||||
appImageBundler = new MacAppBundler().setDependentTask(true);
|
||||
appImageBundler = new MacAppBundler()
|
||||
.setDependentTask(true);
|
||||
}
|
||||
|
||||
protected void validateAppImageAndBundeler(
|
||||
@ -136,11 +138,18 @@ public abstract class MacBaseInstallerBundler extends AbstractBundler {
|
||||
I18N.getString(
|
||||
"message.app-image-requires-app-name.advice"));
|
||||
}
|
||||
if (Optional.ofNullable(
|
||||
SIGN_BUNDLE.fetchFrom(params)).orElse(Boolean.FALSE)) {
|
||||
// if signing bundle with app-image, warn user if app-image
|
||||
// is not already signed.
|
||||
if (!(AppImageFile.load(applicationImage).isSigned())) {
|
||||
if (AppImageFile.load(applicationImage).isSigned()) {
|
||||
if (!Files.exists(
|
||||
PackageFile.getPathInAppImage(applicationImage))) {
|
||||
Log.info(MessageFormat.format(I18N.getString(
|
||||
"warning.per.user.app.image.signed"),
|
||||
PackageFile.getPathInAppImage(applicationImage)));
|
||||
}
|
||||
} else {
|
||||
if (Optional.ofNullable(
|
||||
SIGN_BUNDLE.fetchFrom(params)).orElse(Boolean.FALSE)) {
|
||||
// if signing bundle with app-image, warn user if app-image
|
||||
// is not already signed.
|
||||
Log.info(MessageFormat.format(I18N.getString(
|
||||
"warning.unsigned.app.image"), getID()));
|
||||
}
|
||||
@ -158,17 +167,19 @@ public abstract class MacBaseInstallerBundler extends AbstractBundler {
|
||||
StandardBundlerParam.getPredefinedAppImage(params);
|
||||
if (predefinedImage != null) {
|
||||
appDir = appImageRoot.resolve(APP_NAME.fetchFrom(params) + ".app");
|
||||
IOUtils.copyRecursive(predefinedImage, appDir);
|
||||
IOUtils.copyRecursive(predefinedImage, appDir,
|
||||
LinkOption.NOFOLLOW_LINKS);
|
||||
|
||||
// Create PackageFile if predefined app image is not signed
|
||||
if (!StandardBundlerParam.isRuntimeInstaller(params) &&
|
||||
!AppImageFile.load(predefinedImage).isSigned()) {
|
||||
new PackageFile(APP_NAME.fetchFrom(params)).save(
|
||||
ApplicationLayout.macAppImage().resolveAt(appDir));
|
||||
}
|
||||
} else {
|
||||
appDir = appImageBundler.execute(params, appImageRoot);
|
||||
}
|
||||
|
||||
if (!StandardBundlerParam.isRuntimeInstaller(params)) {
|
||||
new PackageFile(APP_NAME.fetchFrom(params)).save(
|
||||
ApplicationLayout.macAppImage().resolveAt(appDir));
|
||||
Files.deleteIfExists(AppImageFile.getPathInAppImage(appDir));
|
||||
}
|
||||
|
||||
return appDir;
|
||||
}
|
||||
|
||||
|
@ -94,3 +94,4 @@ message.signing.pkg=Warning: For signing PKG, you might need to set "Always Trus
|
||||
message.setfile.dmg=Setting custom icon on DMG file skipped because 'SetFile' utility was not found. Installing Xcode with Command Line Tools should resolve this issue.
|
||||
message.install-dir-ignored=Warning: "--install-dir" is not supported by DMG and will be default to /Applications.
|
||||
warning.unsigned.app.image=Warning: Using unsigned app-image to build signed {0}.
|
||||
warning.per.user.app.image.signed=Warning: Support for per-user configuration of the installed application will not be supported due to missing "{0}" in predefined signed application image.
|
||||
|
@ -90,3 +90,4 @@ message.signing.pkg=Warnung: Zum Signieren von PKG m\u00FCssen Sie m\u00F6gliche
|
||||
message.setfile.dmg=Das Festlegen des benutzerdefinierten Symbols f\u00FCr die DMG-Datei wurde \u00FCbersprungen, weil das Utility "SetFile" nicht gefunden wurde. Durch Installieren von Xcode mit Befehlszeilentools sollte dieses Problem behoben werden.
|
||||
message.install-dir-ignored=Warnung: "--install-dir" wird von DMG nicht unterst\u00FCtzt. Stattdessen wird standardm\u00E4\u00DFig /Applications verwendet.
|
||||
warning.unsigned.app.image=Warnung: Nicht signiertes app-image wird zum Erstellen von signiertem {0} verwendet.
|
||||
warning.per.user.app.image.signed=Warning: Support for per-user configuration of the installed application will not be supported due to missing "{0}" in predefined signed application image.
|
||||
|
@ -94,3 +94,4 @@ message.signing.pkg=\u8B66\u544A: PKG\u3078\u306E\u7F72\u540D\u306E\u5834\u5408\
|
||||
message.setfile.dmg='SetFile'\u30E6\u30FC\u30C6\u30A3\u30EA\u30C6\u30A3\u304C\u898B\u3064\u304B\u3089\u306A\u3044\u305F\u3081\u3001DMG\u30D5\u30A1\u30A4\u30EB\u3067\u306E\u30AB\u30B9\u30BF\u30E0\u30FB\u30A2\u30A4\u30B3\u30F3\u306E\u8A2D\u5B9A\u304C\u30B9\u30AD\u30C3\u30D7\u3055\u308C\u307E\u3057\u305F\u3002Xcode\u3068\u30B3\u30DE\u30F3\u30C9\u30FB\u30E9\u30A4\u30F3\u30FB\u30C4\u30FC\u30EB\u3092\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3059\u308B\u3068\u3001\u3053\u306E\u554F\u984C\u306F\u89E3\u6C7A\u3055\u308C\u307E\u3059\u3002
|
||||
message.install-dir-ignored=\u8B66\u544A: "--install-dir"\u306FDMG\u3067\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002/Applications\u306B\u30C7\u30D5\u30A9\u30EB\u30C8\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002
|
||||
warning.unsigned.app.image=\u8B66\u544A: \u7F72\u540D\u3055\u308C\u3066\u3044\u306A\u3044app-image\u3092\u4F7F\u7528\u3057\u3066\u7F72\u540D\u3055\u308C\u305F{0}\u3092\u4F5C\u6210\u3057\u307E\u3059\u3002
|
||||
warning.per.user.app.image.signed=Warning: Support for per-user configuration of the installed application will not be supported due to missing "{0}" in predefined signed application image.
|
||||
|
@ -94,3 +94,4 @@ message.signing.pkg=\u8B66\u544A\uFF1A\u8981\u5BF9 PKG \u8FDB\u884C\u7B7E\u540D\
|
||||
message.setfile.dmg=\u7531\u4E8E\u672A\u627E\u5230 'SetFile' \u5B9E\u7528\u7A0B\u5E8F\uFF0C\u8DF3\u8FC7\u4E86\u9488\u5BF9 DMG \u6587\u4EF6\u8BBE\u7F6E\u5B9A\u5236\u56FE\u6807\u7684\u64CD\u4F5C\u3002\u5B89\u88C5\u5E26\u547D\u4EE4\u884C\u5DE5\u5177\u7684 Xcode \u5E94\u80FD\u89E3\u51B3\u6B64\u95EE\u9898\u3002
|
||||
message.install-dir-ignored=\u8B66\u544A\uFF1A"--install-dir" \u4E0D\u53D7 DMG \u652F\u6301\uFF0C\u5C06\u9ED8\u8BA4\u4E3A /Applications\u3002
|
||||
warning.unsigned.app.image=\u8B66\u544A\uFF1A\u4F7F\u7528\u672A\u7B7E\u540D\u7684 app-image \u751F\u6210\u5DF2\u7B7E\u540D\u7684 {0}\u3002
|
||||
warning.per.user.app.image.signed=Warning: Support for per-user configuration of the installed application will not be supported due to missing "{0}" in predefined signed application image.
|
||||
|
@ -76,7 +76,9 @@ public abstract class AbstractAppImageBuilder {
|
||||
IOUtils.copyRecursive(SOURCE_DIR.fetchFrom(params),
|
||||
appLayout.appDirectory());
|
||||
}
|
||||
|
||||
AppImageFile.save(root, params);
|
||||
|
||||
List<String> items = APP_CONTENT.fetchFrom(params);
|
||||
for (String item : items) {
|
||||
IOUtils.copyRecursive(Path.of(item),
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2022, 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
|
||||
@ -112,6 +112,10 @@ class AppImageBundler extends AbstractBundler {
|
||||
return this;
|
||||
}
|
||||
|
||||
final boolean isDependentTask() {
|
||||
return dependentTask;
|
||||
}
|
||||
|
||||
final AppImageBundler setAppImageSupplier(
|
||||
Function<Path, AbstractAppImageBuilder> v) {
|
||||
appImageSupplier = v;
|
||||
|
@ -146,7 +146,7 @@ public final class AppImageFile {
|
||||
return mainClass;
|
||||
}
|
||||
|
||||
boolean isSigned() {
|
||||
public boolean isSigned() {
|
||||
return signed;
|
||||
}
|
||||
|
||||
@ -218,7 +218,7 @@ public final class AppImageFile {
|
||||
* @return valid info about application image or null
|
||||
* @throws IOException
|
||||
*/
|
||||
static AppImageFile load(Path appImageDir) {
|
||||
public static AppImageFile load(Path appImageDir) {
|
||||
try {
|
||||
Document doc = readXml(appImageDir);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2022, 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
|
||||
@ -35,6 +35,7 @@ import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.CopyOption;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
@ -112,12 +113,14 @@ public class IOUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyRecursive(Path src, Path dest) throws IOException {
|
||||
copyRecursive(src, dest, List.of());
|
||||
public static void copyRecursive(Path src, Path dest, CopyOption... options)
|
||||
throws IOException {
|
||||
copyRecursive(src, dest, List.of(), options);
|
||||
}
|
||||
|
||||
public static void copyRecursive(Path src, Path dest,
|
||||
final List<String> excludes) throws IOException {
|
||||
final List<String> excludes, CopyOption... options)
|
||||
throws IOException {
|
||||
Files.walkFileTree(src, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(final Path dir,
|
||||
@ -134,7 +137,7 @@ public class IOUtils {
|
||||
public FileVisitResult visitFile(final Path file,
|
||||
final BasicFileAttributes attrs) throws IOException {
|
||||
if (!excludes.contains(file.toFile().getName())) {
|
||||
Files.copy(file, dest.resolve(src.relativize(file)));
|
||||
Files.copy(file, dest.resolve(src.relativize(file)), options);
|
||||
}
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
@ -28,13 +28,12 @@
|
||||
#############################################################################
|
||||
|
||||
vmTestbase/nsk/jvmti/AttachOnDemand/attach022/TestDescription.java 8277573 generic-all
|
||||
|
||||
vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw001/TestDescription.java 8205957 generic-all
|
||||
|
||||
serviceability/sa/TestJhsdbJstackMixed.java 8248675 linux-aarch64
|
||||
|
||||
vmTestbase/nsk/jvmti/scenarios/sampling/SP07/sp07t002/TestDescription.java 8245680 windows-x64
|
||||
|
||||
vmTestbase/vm/mlvm/mixed/stress/regression/b6969574/INDIFY_Test.java 8265295 linux-x64,windows-x64
|
||||
|
||||
serviceability/sa/TestJhsdbJstackMixed.java 8248675 linux-aarch64
|
||||
|
||||
serviceability/jvmti/VMObjectAlloc/VMObjectAllocTest.java 8288430 generic-all
|
||||
serviceability/jvmti/GetLocalVariable/GetLocalWithoutSuspendTest.java 8290013 windows-x64
|
||||
|
@ -754,6 +754,7 @@ jdk/jfr/startupargs/TestStartDuration.java 8214685 windows-
|
||||
jdk/jfr/jvm/TestWaste.java 8282427 generic-all
|
||||
jdk/jfr/api/consumer/recordingstream/TestOnEvent.java 8255404 linux-x64
|
||||
jdk/jfr/event/runtime/TestActiveSettingEvent.java 8287832 generic-all
|
||||
jdk/jfr/api/consumer/TestRecordingFileWrite.java 8287699 linux-x64,macosx-x64
|
||||
|
||||
############################################################################
|
||||
|
||||
|
@ -31,7 +31,8 @@ exclusiveAccess.dirs=java/math/BigInteger/largeMemory \
|
||||
java/rmi/Naming java/util/prefs sun/management/jmxremote \
|
||||
sun/tools/jstatd sun/security/mscapi java/util/Arrays/largeMemory \
|
||||
java/util/BitSet/stream javax/rmi java/net/httpclient/websocket \
|
||||
com/sun/net/httpserver/simpleserver
|
||||
com/sun/net/httpserver/simpleserver \
|
||||
java/nio/channels/FileChannel/largeMemory
|
||||
|
||||
# Group definitions
|
||||
groups=TEST.groups
|
||||
|
@ -820,7 +820,7 @@ public final class JPackageCommand extends CommandArguments<JPackageCommand> {
|
||||
private void assertAppImageFile() {
|
||||
final Path lookupPath = AppImageFile.getPathInAppImage(Path.of(""));
|
||||
|
||||
if (isRuntime() || !isImagePackageType()) {
|
||||
if (isRuntime() || (!isImagePackageType() && !TKit.isOSX())) {
|
||||
assertFileInAppImage(lookupPath, null);
|
||||
} else {
|
||||
assertFileInAppImage(lookupPath, lookupPath);
|
||||
@ -833,7 +833,17 @@ public final class JPackageCommand extends CommandArguments<JPackageCommand> {
|
||||
if (isRuntime() || isImagePackageType() || TKit.isLinux()) {
|
||||
assertFileInAppImage(lookupPath, null);
|
||||
} else {
|
||||
assertFileInAppImage(lookupPath, lookupPath);
|
||||
if (TKit.isOSX() && hasArgument("--app-image")) {
|
||||
String appImage = getArgumentValue("--app-image",
|
||||
() -> null);
|
||||
if (AppImageFile.load(Path.of(appImage)).isSigned()) {
|
||||
assertFileInAppImage(lookupPath, null);
|
||||
} else {
|
||||
assertFileInAppImage(lookupPath, lookupPath);
|
||||
}
|
||||
} else {
|
||||
assertFileInAppImage(lookupPath, lookupPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2022, 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,6 +22,7 @@
|
||||
*/
|
||||
|
||||
import java.nio.file.Path;
|
||||
import jdk.jpackage.internal.ApplicationLayout;
|
||||
import jdk.jpackage.test.JPackageCommand;
|
||||
import jdk.jpackage.test.PackageTest;
|
||||
import jdk.jpackage.test.PackageType;
|
||||
@ -75,7 +76,8 @@ public class SigningPackageTest {
|
||||
|
||||
private static void verifyAppImageInDMG(JPackageCommand cmd) {
|
||||
MacHelper.withExplodedDmg(cmd, dmgImage -> {
|
||||
Path launcherPath = dmgImage.resolve(Path.of("Contents", "MacOS", cmd.name()));
|
||||
Path launcherPath = ApplicationLayout.platformAppImage()
|
||||
.resolveAt(dmgImage).launchersDirectory().resolve(cmd.name());
|
||||
// We will be called with all folders in DMG since JDK-8263155, but
|
||||
// we only need to verify app.
|
||||
if (dmgImage.endsWith(cmd.name() + ".app")) {
|
||||
|
142
test/jdk/tools/jpackage/macosx/SigningPackageTwoStepTest.java
Normal file
142
test/jdk/tools/jpackage/macosx/SigningPackageTwoStepTest.java
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 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.
|
||||
*/
|
||||
|
||||
import java.nio.file.Path;
|
||||
import jdk.jpackage.internal.ApplicationLayout;
|
||||
import jdk.jpackage.test.JPackageCommand;
|
||||
import jdk.jpackage.test.TKit;
|
||||
import jdk.jpackage.test.PackageTest;
|
||||
import jdk.jpackage.test.PackageType;
|
||||
import jdk.jpackage.test.MacHelper;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.Annotations.Parameter;
|
||||
|
||||
/**
|
||||
* Note: Testing unsgined app image is done to verify support for per-user
|
||||
* configuration by checking for PackageFile.
|
||||
* Tests generation of dmg and pkg from signed or unsigned predefined app image.
|
||||
* Test will generate pkg and verifies its signature. It verifies that dmg
|
||||
* is not signed, but app image inside dmg is signed or unsigned. This test
|
||||
* requires that the machine is configured with test certificate for
|
||||
* "Developer ID Installer: jpackage.openjdk.java.net" in
|
||||
* jpackagerTest keychain with
|
||||
* always allowed access to this keychain for user which runs test.
|
||||
* note:
|
||||
* "jpackage.openjdk.java.net" can be over-ridden by systerm property
|
||||
* "jpackage.mac.signing.key.user.name", and
|
||||
* "jpackagerTest" can be over-ridden by system property
|
||||
* "jpackage.mac.signing.keychain"
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary jpackage with --type pkg,dmg --app-image
|
||||
* @library ../helpers
|
||||
* @library /test/lib
|
||||
* @library base
|
||||
* @key jpackagePlatformPackage
|
||||
* @build SigningBase
|
||||
* @build SigningCheck
|
||||
* @build jtreg.SkippedException
|
||||
* @build jdk.jpackage.test.*
|
||||
* @build SigningPackageTwoStepTest
|
||||
* @modules jdk.jpackage/jdk.jpackage.internal
|
||||
* @requires (os.family == "mac")
|
||||
* @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main
|
||||
* --jpt-run=SigningPackageTwoStepTest
|
||||
*/
|
||||
public class SigningPackageTwoStepTest {
|
||||
|
||||
private static void verifyPKG(JPackageCommand cmd) {
|
||||
if (!cmd.hasArgument("--mac-sign")) {
|
||||
return; // Nothing to check if not signed
|
||||
}
|
||||
|
||||
Path outputBundle = cmd.outputBundle();
|
||||
SigningBase.verifyPkgutil(outputBundle);
|
||||
SigningBase.verifySpctl(outputBundle, "install");
|
||||
}
|
||||
|
||||
private static void verifyDMG(JPackageCommand cmd) {
|
||||
// DMG always unsigned, so we will check it
|
||||
Path outputBundle = cmd.outputBundle();
|
||||
SigningBase.verifyCodesign(outputBundle, false);
|
||||
}
|
||||
|
||||
private static void verifyAppImageInDMG(JPackageCommand cmd) {
|
||||
MacHelper.withExplodedDmg(cmd, dmgImage -> {
|
||||
// We will be called with all folders in DMG since JDK-8263155, but
|
||||
// we only need to verify app.
|
||||
if (dmgImage.endsWith(cmd.name() + ".app")) {
|
||||
boolean isSigned = cmd.hasArgument("--mac-sign");
|
||||
Path launcherPath = ApplicationLayout.platformAppImage()
|
||||
.resolveAt(dmgImage).launchersDirectory().resolve(cmd.name());
|
||||
SigningBase.verifyCodesign(launcherPath, isSigned);
|
||||
SigningBase.verifyCodesign(dmgImage, isSigned);
|
||||
if (isSigned) {
|
||||
SigningBase.verifySpctl(dmgImage, "exec");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@Parameter("true")
|
||||
@Parameter("false")
|
||||
public static void test(boolean signAppImage) throws Exception {
|
||||
SigningCheck.checkCertificates();
|
||||
|
||||
Path appimageOutput = TKit.createTempDirectory("appimage");
|
||||
|
||||
JPackageCommand appImageCmd = JPackageCommand.helloAppImage()
|
||||
.setArgumentValue("--dest", appimageOutput);
|
||||
if (signAppImage) {
|
||||
appImageCmd.addArguments("--mac-sign")
|
||||
.addArguments("--mac-signing-key-user-name",
|
||||
SigningBase.DEV_NAME)
|
||||
.addArguments("--mac-signing-keychain",
|
||||
SigningBase.KEYCHAIN);
|
||||
}
|
||||
|
||||
new PackageTest()
|
||||
.addRunOnceInitializer(() -> appImageCmd.execute())
|
||||
.forTypes(PackageType.MAC)
|
||||
.addInitializer(cmd -> {
|
||||
cmd.addArguments("--app-image", appImageCmd.outputBundle());
|
||||
cmd.removeArgumentWithValue("--input");
|
||||
if (signAppImage) {
|
||||
cmd.addArguments("--mac-sign",
|
||||
"--mac-signing-key-user-name",
|
||||
SigningBase.DEV_NAME,
|
||||
"--mac-signing-keychain",
|
||||
SigningBase.KEYCHAIN);
|
||||
}
|
||||
})
|
||||
.forTypes(PackageType.MAC_PKG)
|
||||
.addBundleVerifier(SigningPackageTwoStepTest::verifyPKG)
|
||||
.forTypes(PackageType.MAC_DMG)
|
||||
.addBundleVerifier(SigningPackageTwoStepTest::verifyDMG)
|
||||
.addBundleVerifier(SigningPackageTwoStepTest::verifyAppImageInDMG)
|
||||
.run();
|
||||
}
|
||||
}
|
@ -95,7 +95,7 @@ public class CaseStructureTest extends ComboInstance<CaseStructureTest> {
|
||||
task.generate(result -> {
|
||||
boolean shouldPass = true;
|
||||
long patternCases = Arrays.stream(caseLabels).filter(l -> l == CaseLabel.TYPE_PATTERN || l == CaseLabel.PARENTHESIZED_PATTERN).count();
|
||||
long typePatternCases = Arrays.stream(caseLabels).filter(l -> l == CaseLabel.TYPE_PATTERN).count();
|
||||
long typePatternCases = Arrays.stream(caseLabels).filter(l -> l == CaseLabel.TYPE_PATTERN || l == CaseLabel.PARENTHESIZED_PATTERN).count();
|
||||
long constantCases = Arrays.stream(caseLabels).filter(l -> l == CaseLabel.CONSTANT).count();
|
||||
long nullCases = Arrays.stream(caseLabels).filter(l -> l == CaseLabel.NULL).count();
|
||||
long defaultCases = Arrays.stream(caseLabels).filter(l -> l == CaseLabel.DEFAULT).count();
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8262891 8268663
|
||||
* @bug 8262891 8268663 8289894
|
||||
* @summary Check guards implementation.
|
||||
* @compile --enable-preview -source ${jdk.version} Guards.java
|
||||
* @run main/othervm --enable-preview Guards
|
||||
@ -164,18 +164,18 @@ public class Guards {
|
||||
}
|
||||
|
||||
void testGuardNPE() {
|
||||
assertEquals("empty", guardNPE(""));
|
||||
assertEquals("A", guardNPE("A"));
|
||||
assertEquals("other", guardNPE(1));
|
||||
try {
|
||||
guardNPE(null);
|
||||
throw new AssertionError("Expected exception missing.");
|
||||
} catch (NullPointerException ex) {
|
||||
//expected
|
||||
}
|
||||
doTestGuardNPE(this::guardNPE1);
|
||||
doTestGuardNPE(this::guardNPE2);
|
||||
}
|
||||
|
||||
String guardNPE(Object o) {
|
||||
void doTestGuardNPE(Function<Object, String> test) {
|
||||
assertEquals("empty", test.apply(""));
|
||||
assertEquals("A", test.apply("A"));
|
||||
assertEquals("other", test.apply(1));
|
||||
assertEquals("empty", test.apply(null));
|
||||
}
|
||||
|
||||
String guardNPE1(Object o) {
|
||||
return switch (o) {
|
||||
case null, String s when s.isEmpty() -> "empty";
|
||||
case String s -> s;
|
||||
@ -183,6 +183,14 @@ public class Guards {
|
||||
};
|
||||
}
|
||||
|
||||
String guardNPE2(Object o) {
|
||||
return switch (o) {
|
||||
case null, ((((String s)))) when s.isEmpty() -> "empty";
|
||||
case ((((String s)))) -> s;
|
||||
case Object x -> "other";
|
||||
};
|
||||
}
|
||||
|
||||
record Box(Object o) {}
|
||||
|
||||
void assertEquals(String expected, String actual) {
|
||||
|
@ -254,4 +254,32 @@ public class SwitchErrors {
|
||||
case int j: break;
|
||||
}
|
||||
}
|
||||
void nullAndParenthesized1(Object o) {
|
||||
record R(Object o) {}
|
||||
switch (o) {
|
||||
case null, ((R r)): break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
void nullAndParenthesized2(Object o) {
|
||||
record R(Object o) {}
|
||||
switch (o) {
|
||||
case null, ((R(var v))): break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
void nullAndParenthesized3(Object o) {
|
||||
record R(Object o) {}
|
||||
switch (o) {
|
||||
case ((R r)): case null: break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
void nullAndParenthesized4(Object o) {
|
||||
record R(Object o) {}
|
||||
switch (o) {
|
||||
case ((R(var v))): case null: break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ SwitchErrors.java:232:47: compiler.err.flows.through.from.pattern
|
||||
SwitchErrors.java:244:18: compiler.err.duplicate.unconditional.pattern
|
||||
SwitchErrors.java:249:18: compiler.err.prob.found.req: (compiler.misc.not.applicable.types: int, java.lang.Integer)
|
||||
SwitchErrors.java:254:18: compiler.err.type.found.req: int, (compiler.misc.type.req.class.array)
|
||||
SwitchErrors.java:267:24: compiler.err.flows.through.to.pattern
|
||||
SwitchErrors.java:281:37: compiler.err.flows.through.from.pattern
|
||||
SwitchErrors.java:9:9: compiler.err.not.exhaustive.statement
|
||||
SwitchErrors.java:15:9: compiler.err.not.exhaustive.statement
|
||||
SwitchErrors.java:21:9: compiler.err.not.exhaustive.statement
|
||||
@ -55,4 +57,4 @@ SwitchErrors.java:164:9: compiler.err.not.exhaustive.statement
|
||||
SwitchErrors.java:237:9: compiler.err.not.exhaustive.statement
|
||||
- compiler.note.preview.filename: SwitchErrors.java, DEFAULT
|
||||
- compiler.note.preview.recompile
|
||||
55 errors
|
||||
57 errors
|
Loading…
x
Reference in New Issue
Block a user