8339686: java/foreign/TestMappedHandshake.java fails with assert(depth < max_critical_stack_depth) failed: can't have more than 10 critical frames

8339780: TestByteBuffer fails on AIX after 8339285

Reviewed-by: alanb, jvernee
This commit is contained in:
Maurizio Cimadamore 2024-09-11 11:18:38 +00:00
parent 0b3f2e64e8
commit 5977888500
7 changed files with 99 additions and 57 deletions

@ -27,6 +27,7 @@ package java.nio;
import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.access.foreign.MappedMemoryUtilsProxy;
import jdk.internal.access.foreign.UnmapperProxy;
import jdk.internal.foreign.AbstractMemorySegmentImpl;
import jdk.internal.foreign.MemorySessionImpl;
@ -804,6 +805,7 @@ public abstract sealed class Buffer
}
static {
// setup access to this package in SharedSecrets
SharedSecrets.setJavaNioAccess(
new JavaNioAccess() {
@ -886,23 +888,8 @@ public abstract sealed class Buffer
}
@Override
public void force(FileDescriptor fd, long address, boolean isSync, long offset, long size) {
MappedMemoryUtils.force(fd, address, isSync, offset, size);
}
@Override
public void load(long address, boolean isSync, long size) {
MappedMemoryUtils.load(address, isSync, size);
}
@Override
public void unload(long address, boolean isSync, long size) {
MappedMemoryUtils.unload(address, isSync, size);
}
@Override
public boolean isLoaded(long address, boolean isSync, long size) {
return MappedMemoryUtils.isLoaded(address, isSync, size);
public MappedMemoryUtilsProxy mappedMemoryUtils() {
return MappedMemoryUtils.PROXY;
}
@Override

@ -31,6 +31,7 @@ import java.lang.foreign.MemorySegment;
import java.lang.ref.Reference;
import java.util.Objects;
import jdk.internal.access.foreign.MappedMemoryUtilsProxy;
import jdk.internal.access.foreign.UnmapperProxy;
import jdk.internal.misc.ScopedMemoryAccess;
import jdk.internal.misc.Unsafe;
@ -194,7 +195,7 @@ public abstract sealed class MappedByteBuffer
if (fd == null) {
return true;
}
return SCOPED_MEMORY_ACCESS.isLoaded(session(), address, isSync, capacity());
return SCOPED_MEMORY_ACCESS.isLoaded(session(), MappedMemoryUtils.PROXY, address, isSync, capacity());
}
/**
@ -212,7 +213,7 @@ public abstract sealed class MappedByteBuffer
return this;
}
try {
SCOPED_MEMORY_ACCESS.load(session(), address, isSync, capacity());
SCOPED_MEMORY_ACCESS.load(session(), MappedMemoryUtils.PROXY, address, isSync, capacity());
} finally {
Reference.reachabilityFence(this);
}
@ -312,7 +313,7 @@ public abstract sealed class MappedByteBuffer
if ((address != 0) && (capacity != 0)) {
// check inputs
Objects.checkFromIndexSize(index, length, capacity);
SCOPED_MEMORY_ACCESS.force(session(), fd, address, isSync, index, length);
SCOPED_MEMORY_ACCESS.force(session(), MappedMemoryUtils.PROXY, fd, address, isSync, index, length);
}
return this;
}

@ -28,6 +28,8 @@ package java.nio;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.UncheckedIOException;
import jdk.internal.access.foreign.MappedMemoryUtilsProxy;
import jdk.internal.misc.Blocker;
import jdk.internal.misc.Unsafe;
@ -125,7 +127,6 @@ import jdk.internal.misc.Unsafe;
private static native void registerNatives();
static {
registerNatives();
isLoaded0(0, 0, 0);
}
// utility methods
@ -176,4 +177,26 @@ import jdk.internal.misc.Unsafe;
// pageSize must be a power of 2
return address & ~(pageSize - 1);
}
static final MappedMemoryUtilsProxy PROXY = new MappedMemoryUtilsProxy() {
@Override
public boolean isLoaded(long address, boolean isSync, long size) {
return MappedMemoryUtils.isLoaded(address, isSync, size);
}
@Override
public void load(long address, boolean isSync, long size) {
MappedMemoryUtils.load(address, isSync, size);
}
@Override
public void unload(long address, boolean isSync, long size) {
MappedMemoryUtils.unload(address, isSync, size);
}
@Override
public void force(FileDescriptor fd, long address, boolean isSync, long index, long length) {
MappedMemoryUtils.force(fd, address, isSync, index, length);
}
};
}

@ -25,6 +25,7 @@
package jdk.internal.access;
import jdk.internal.access.foreign.MappedMemoryUtilsProxy;
import jdk.internal.access.foreign.UnmapperProxy;
import jdk.internal.misc.VM.BufferPool;
@ -107,25 +108,10 @@ public interface JavaNioAccess {
boolean hasSession(Buffer buffer);
/**
* Used by {@code jdk.internal.foreign.MappedMemorySegmentImpl} and byte buffer var handle views.
*/
void force(FileDescriptor fd, long address, boolean isSync, long offset, long size);
/**
* Used by {@code jdk.internal.foreign.MappedMemorySegmentImpl} and byte buffer var handle views.
*/
void load(long address, boolean isSync, long size);
/**
* Used by {@code jdk.internal.foreign.MappedMemorySegmentImpl}.
*/
void unload(long address, boolean isSync, long size);
/**
* Used by {@code jdk.internal.foreign.MappedMemorySegmentImpl} and byte buffer var handle views.
*/
boolean isLoaded(long address, boolean isSync, long size);
MappedMemoryUtilsProxy mappedMemoryUtils();
/**
* Used by {@code jdk.internal.foreign.NativeMemorySegmentImpl}.

@ -0,0 +1,39 @@
/*
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.internal.access.foreign;
import java.io.FileDescriptor;
/**
* This proxy interface is required to allow access to @{code MappedMemoryUtils} methods from {@code ScopedMemoryAccess}.
* This allows to avoid pesky initialization issues in the middle of memory mapped scoped methods.
*/
public interface MappedMemoryUtilsProxy {
boolean isLoaded(long address, boolean isSync, long size);
void load(long address, boolean isSync, long size);
void unload(long address, boolean isSync, long size);
void force(FileDescriptor fd, long address, boolean isSync, long index, long length);
}

@ -72,23 +72,28 @@ final class MappedMemorySegmentImpl extends NativeMemorySegmentImpl {
public void load() {
if (unmapper != null) {
SCOPED_MEMORY_ACCESS.load(sessionImpl(), min, unmapper.isSync(), length);
SCOPED_MEMORY_ACCESS.load(sessionImpl(), NIO_ACCESS.mappedMemoryUtils(),
min, unmapper.isSync(), length);
}
}
public void unload() {
if (unmapper != null) {
SCOPED_MEMORY_ACCESS.unload(sessionImpl(), min, unmapper.isSync(), length);
SCOPED_MEMORY_ACCESS.unload(sessionImpl(), NIO_ACCESS.mappedMemoryUtils(),
min, unmapper.isSync(), length);
}
}
public boolean isLoaded() {
return unmapper == null || SCOPED_MEMORY_ACCESS.isLoaded(sessionImpl(), min, unmapper.isSync(), length);
return unmapper == null ||
SCOPED_MEMORY_ACCESS.isLoaded(sessionImpl(),
NIO_ACCESS.mappedMemoryUtils(), min, unmapper.isSync(), length);
}
public void force() {
if (unmapper != null) {
SCOPED_MEMORY_ACCESS.force(sessionImpl(), unmapper.fileDescriptor(), min, unmapper.isSync(), 0, length);
SCOPED_MEMORY_ACCESS.force(sessionImpl(), NIO_ACCESS.mappedMemoryUtils(),
unmapper.fileDescriptor(), min, unmapper.isSync(), 0, length);
}
}

@ -34,6 +34,7 @@ import java.lang.ref.Reference;
import java.io.FileDescriptor;
import java.util.function.Supplier;
import jdk.internal.access.foreign.MappedMemoryUtilsProxy;
import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.foreign.AbstractMemorySegmentImpl;
@ -237,84 +238,84 @@ public class ScopedMemoryAccess {
}
@ForceInline
public boolean isLoaded(MemorySessionImpl session, long address, boolean isSync, long size) {
public boolean isLoaded(MemorySessionImpl session, MappedMemoryUtilsProxy mappedUtils, long address, boolean isSync, long size) {
try {
return isLoadedInternal(session, address, isSync, size);
return isLoadedInternal(session, mappedUtils, address, isSync, size);
} catch (ScopedAccessError ex) {
throw ex.newRuntimeException();
}
}
@ForceInline @Scoped
public boolean isLoadedInternal(MemorySessionImpl session, long address, boolean isSync, long size) {
public boolean isLoadedInternal(MemorySessionImpl session, MappedMemoryUtilsProxy mappedUtils, long address, boolean isSync, long size) {
try {
if (session != null) {
session.checkValidStateRaw();
}
return SharedSecrets.getJavaNioAccess().isLoaded(address, isSync, size);
return mappedUtils.isLoaded(address, isSync, size);
} finally {
Reference.reachabilityFence(session);
}
}
@ForceInline
public void load(MemorySessionImpl session, long address, boolean isSync, long size) {
public void load(MemorySessionImpl session, MappedMemoryUtilsProxy mappedUtils, long address, boolean isSync, long size) {
try {
loadInternal(session, address, isSync, size);
loadInternal(session, mappedUtils, address, isSync, size);
} catch (ScopedAccessError ex) {
throw ex.newRuntimeException();
}
}
@ForceInline @Scoped
public void loadInternal(MemorySessionImpl session, long address, boolean isSync, long size) {
public void loadInternal(MemorySessionImpl session, MappedMemoryUtilsProxy mappedUtils, long address, boolean isSync, long size) {
try {
if (session != null) {
session.checkValidStateRaw();
}
SharedSecrets.getJavaNioAccess().load(address, isSync, size);
mappedUtils.load(address, isSync, size);
} finally {
Reference.reachabilityFence(session);
}
}
@ForceInline
public void unload(MemorySessionImpl session, long address, boolean isSync, long size) {
public void unload(MemorySessionImpl session, MappedMemoryUtilsProxy mappedUtils, long address, boolean isSync, long size) {
try {
unloadInternal(session, address, isSync, size);
unloadInternal(session, mappedUtils, address, isSync, size);
} catch (ScopedAccessError ex) {
throw ex.newRuntimeException();
}
}
@ForceInline @Scoped
public void unloadInternal(MemorySessionImpl session, long address, boolean isSync, long size) {
public void unloadInternal(MemorySessionImpl session, MappedMemoryUtilsProxy mappedUtils, long address, boolean isSync, long size) {
try {
if (session != null) {
session.checkValidStateRaw();
}
SharedSecrets.getJavaNioAccess().unload(address, isSync, size);
mappedUtils.unload(address, isSync, size);
} finally {
Reference.reachabilityFence(session);
}
}
@ForceInline
public void force(MemorySessionImpl session, FileDescriptor fd, long address, boolean isSync, long index, long length) {
public void force(MemorySessionImpl session, MappedMemoryUtilsProxy mappedUtils, FileDescriptor fd, long address, boolean isSync, long index, long length) {
try {
forceInternal(session, fd, address, isSync, index, length);
forceInternal(session, mappedUtils, fd, address, isSync, index, length);
} catch (ScopedAccessError ex) {
throw ex.newRuntimeException();
}
}
@ForceInline @Scoped
public void forceInternal(MemorySessionImpl session, FileDescriptor fd, long address, boolean isSync, long index, long length) {
public void forceInternal(MemorySessionImpl session, MappedMemoryUtilsProxy mappedUtils, FileDescriptor fd, long address, boolean isSync, long index, long length) {
try {
if (session != null) {
session.checkValidStateRaw();
}
SharedSecrets.getJavaNioAccess().force(fd, address, isSync, index, length);
mappedUtils.force(fd, address, isSync, index, length);
} finally {
Reference.reachabilityFence(session);
}