8339285: Test fails with assert(depth < max_critical_stack_depth) failed: can't have more than 10 critical frames

Reviewed-by: alanb
This commit is contained in:
Maurizio Cimadamore 2024-09-05 18:11:18 +00:00
parent 48d79431c9
commit 9e1af8cc7c
9 changed files with 241 additions and 41 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 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
@ -46,9 +46,8 @@ static long calculate_number_of_pages_in_range(void* address, size_t len, size_t
return numPages;
}
JNIEXPORT jboolean JNICALL
Java_java_nio_MappedMemoryUtils_isLoaded0(JNIEnv *env, jobject obj, jlong address,
jlong len, jlong numPages)
jboolean JNICALL MappedMemoryUtils_isLoaded0(JNIEnv *env, jobject obj, jlong address,
jlong len, jlong numPages)
{
jboolean loaded = JNI_TRUE;
int result = 0;
@ -93,8 +92,7 @@ Java_java_nio_MappedMemoryUtils_isLoaded0(JNIEnv *env, jobject obj, jlong addres
}
JNIEXPORT void JNICALL
Java_java_nio_MappedMemoryUtils_load0(JNIEnv *env, jobject obj, jlong address,
void JNICALL MappedMemoryUtils_load0(JNIEnv *env, jobject obj, jlong address,
jlong len)
{
char *a = (char *)jlong_to_ptr(address);
@ -104,9 +102,8 @@ Java_java_nio_MappedMemoryUtils_load0(JNIEnv *env, jobject obj, jlong address,
}
}
JNIEXPORT void JNICALL
Java_java_nio_MappedMemoryUtils_unload0(JNIEnv *env, jobject obj, jlong address,
jlong len)
void JNICALL MappedMemoryUtils_unload0(JNIEnv *env, jobject obj, jlong address,
jlong len)
{
char *a = (char *)jlong_to_ptr(address);
int result = madvise((caddr_t)a, (size_t)len, MADV_DONTNEED);
@ -198,8 +195,7 @@ static int validate_msync_address(size_t address)
return 0;
}
JNIEXPORT void JNICALL
Java_java_nio_MappedMemoryUtils_force0(JNIEnv *env, jobject obj, jobject fdo,
void JNICALL MappedMemoryUtils_force0(JNIEnv *env, jobject obj, jobject fdo,
jlong address, jlong len)
{
void* a = (void *)jlong_to_ptr(address);
@ -218,3 +214,19 @@ Java_java_nio_MappedMemoryUtils_force0(JNIEnv *env, jobject obj, jobject fdo,
JNU_ThrowIOExceptionWithMessageAndLastError(env, "msync with parameter MS_SYNC failed");
}
}
#define FD "Ljava/io/FileDescriptor;"
static JNINativeMethod methods[] = {
{"isLoaded0", "(JJJ)Z", (void *)&MappedMemoryUtils_isLoaded0},
{"load0", "(JJ)V", (void *)&MappedMemoryUtils_load0},
{"unload0", "(JJ)V", (void *)&MappedMemoryUtils_unload0},
{"force0", "(" FD "JJ)V", (void *)&MappedMemoryUtils_force0},
};
JNIEXPORT void JNICALL
Java_java_nio_MappedMemoryUtils_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls,
methods, sizeof(methods)/sizeof(methods[0]));
}

View file

@ -2450,7 +2450,8 @@ public abstract class ClassLoader {
* @param javaName the native method's declared name
*/
static long findNative(ClassLoader loader, Class<?> clazz, String entryName, String javaName) {
long addr = findNativeInternal(loader, entryName);
NativeLibraries nativeLibraries = nativeLibrariesFor(loader);
long addr = nativeLibraries.find(entryName);
if (addr != 0 && loader != null) {
Reflection.ensureNativeAccess(clazz, clazz, javaName, true);
}
@ -2462,11 +2463,11 @@ public abstract class ClassLoader {
* to avoid a restricted check, as that check has already been performed when
* obtaining the lookup.
*/
static long findNativeInternal(ClassLoader loader, String entryName) {
static NativeLibraries nativeLibrariesFor(ClassLoader loader) {
if (loader == null) {
return BootLoader.getNativeLibraries().find(entryName);
return BootLoader.getNativeLibraries();
} else {
return loader.libraries.find(entryName);
return loader.libraries;
}
}

View file

@ -70,6 +70,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
import jdk.internal.javac.Restricted;
import jdk.internal.loader.NativeLibraries;
import jdk.internal.logger.LoggerFinderLoader.TemporaryLoggerFinder;
import jdk.internal.misc.Blocker;
import jdk.internal.misc.CarrierThreadLocal;
@ -2662,8 +2663,8 @@ public final class System {
}
@Override
public long findNative(ClassLoader loader, String entry) {
return ClassLoader.findNativeInternal(loader, entry);
public NativeLibraries nativeLibrariesFor(ClassLoader loader) {
return ClassLoader.nativeLibrariesFor(loader);
}
@Override

View file

@ -31,6 +31,7 @@ import jdk.internal.foreign.MemorySessionImpl;
import jdk.internal.foreign.Utils;
import jdk.internal.javac.Restricted;
import jdk.internal.loader.BuiltinClassLoader;
import jdk.internal.loader.NativeLibraries;
import jdk.internal.loader.NativeLibrary;
import jdk.internal.loader.RawNativeLibraries;
import jdk.internal.reflect.CallerSensitive;
@ -256,7 +257,8 @@ public interface SymbolLookup {
if (Utils.containsNullChars(name)) return Optional.empty();
JavaLangAccess javaLangAccess = SharedSecrets.getJavaLangAccess();
// note: ClassLoader::findNative supports a null loader
long addr = javaLangAccess.findNative(loader, name);
NativeLibraries nativeLibraries = javaLangAccess.nativeLibrariesFor(loader);
long addr = nativeLibraries.find(name);
return addr == 0L ?
Optional.empty() :
Optional.of(MemorySegment.ofAddress(addr)

View file

@ -116,6 +116,18 @@ import jdk.internal.misc.Unsafe;
private static native void unload0(long address, long length);
private static native void force0(FileDescriptor fd, long address, long length) throws IOException;
/* Register the natives via the static initializer.
*
* This is required, as these native methods are "scoped methods" (see ScopedMemoryAccess).
* As such, it's better not to end up doing a full JNI lookup while in a scoped method context,
* as that will make the stack trace too deep.
*/
private static native void registerNatives();
static {
registerNatives();
isLoaded0(0, 0, 0);
}
// utility methods
// Returns the distance (in bytes) of the buffer start from the

View file

@ -29,6 +29,7 @@ import java.io.InputStream;
import java.io.PrintStream;
import java.lang.annotation.Annotation;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SymbolLookup;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
import java.lang.module.ModuleDescriptor;
@ -46,6 +47,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.RejectedExecutionException;
import java.util.stream.Stream;
import jdk.internal.loader.NativeLibraries;
import jdk.internal.misc.CarrierThreadLocal;
import jdk.internal.module.ServicesCatalog;
import jdk.internal.reflect.ConstantPool;
@ -478,7 +480,11 @@ public interface JavaLangAccess {
int getCharsUTF16(long i, int index, byte[] buf);
long findNative(ClassLoader loader, String entry);
/**
* Returns the {@link NativeLibraries} object associated with the provided class loader.
* This is used by {@link SymbolLookup#loaderLookup()}.
*/
NativeLibraries nativeLibrariesFor(ClassLoader loader);
/**
* Direct access to Shutdown.exit to avoid security manager checks

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 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
@ -40,9 +40,8 @@ typedef unsigned char mincore_vec_t;
typedef char mincore_vec_t;
#endif
JNIEXPORT jboolean JNICALL
Java_java_nio_MappedMemoryUtils_isLoaded0(JNIEnv *env, jobject obj, jlong address,
jlong len, jlong numPages)
jboolean JNICALL MappedMemoryUtils_isLoaded0(JNIEnv *env, jobject obj, jlong address,
jlong len, jlong numPages)
{
jboolean loaded = JNI_TRUE;
int result = 0;
@ -80,8 +79,7 @@ Java_java_nio_MappedMemoryUtils_isLoaded0(JNIEnv *env, jobject obj, jlong addres
}
JNIEXPORT void JNICALL
Java_java_nio_MappedMemoryUtils_load0(JNIEnv *env, jobject obj, jlong address,
void JNICALL MappedMemoryUtils_load0(JNIEnv *env, jobject obj, jlong address,
jlong len)
{
char *a = (char *)jlong_to_ptr(address);
@ -91,9 +89,8 @@ Java_java_nio_MappedMemoryUtils_load0(JNIEnv *env, jobject obj, jlong address,
}
}
JNIEXPORT void JNICALL
Java_java_nio_MappedMemoryUtils_unload0(JNIEnv *env, jobject obj, jlong address,
jlong len)
void JNICALL MappedMemoryUtils_unload0(JNIEnv *env, jobject obj, jlong address,
jlong len)
{
char *a = (char *)jlong_to_ptr(address);
int result = madvise((caddr_t)a, (size_t)len, MADV_DONTNEED);
@ -102,8 +99,7 @@ Java_java_nio_MappedMemoryUtils_unload0(JNIEnv *env, jobject obj, jlong address,
}
}
JNIEXPORT void JNICALL
Java_java_nio_MappedMemoryUtils_force0(JNIEnv *env, jobject obj, jobject fdo,
void JNICALL MappedMemoryUtils_force0(JNIEnv *env, jobject obj, jobject fdo,
jlong address, jlong len)
{
void* a = (void *)jlong_to_ptr(address);
@ -112,3 +108,19 @@ Java_java_nio_MappedMemoryUtils_force0(JNIEnv *env, jobject obj, jobject fdo,
JNU_ThrowIOExceptionWithMessageAndLastError(env, "msync with parameter MS_SYNC failed");
}
}
#define FD "Ljava/io/FileDescriptor;"
static JNINativeMethod methods[] = {
{"isLoaded0", "(JJJ)Z", (void *)&MappedMemoryUtils_isLoaded0},
{"load0", "(JJ)V", (void *)&MappedMemoryUtils_load0},
{"unload0", "(JJ)V", (void *)&MappedMemoryUtils_unload0},
{"force0", "(" FD "JJ)V", (void *)&MappedMemoryUtils_force0},
};
JNIEXPORT void JNICALL
Java_java_nio_MappedMemoryUtils_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls,
methods, sizeof(methods)/sizeof(methods[0]));
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 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
@ -30,9 +30,8 @@
#include "java_nio_MappedMemoryUtils.h"
#include <stdlib.h>
JNIEXPORT jboolean JNICALL
Java_java_nio_MappedMemoryUtils_isLoaded0(JNIEnv *env, jobject obj, jlong address,
jlong len, jlong numPages)
jboolean JNICALL MappedMemoryUtils_isLoaded0(JNIEnv *env, jobject obj, jlong address,
jlong len, jlong numPages)
{
jboolean loaded = JNI_FALSE;
/* Information not available?
@ -43,22 +42,19 @@ Java_java_nio_MappedMemoryUtils_isLoaded0(JNIEnv *env, jobject obj, jlong addres
return loaded;
}
JNIEXPORT void JNICALL
Java_java_nio_MappedMemoryUtils_load0(JNIEnv *env, jobject obj, jlong address,
void JNICALL MappedMemoryUtils_load0(JNIEnv *env, jobject obj, jlong address,
jlong len)
{
// no madvise available
}
JNIEXPORT void JNICALL
Java_java_nio_MappedMemoryUtils_unload0(JNIEnv *env, jobject obj, jlong address,
jlong len)
void JNICALL MappedMemoryUtils_unload0(JNIEnv *env, jobject obj, jlong address,
jlong len)
{
// no madvise available
}
JNIEXPORT void JNICALL
Java_java_nio_MappedMemoryUtils_force0(JNIEnv *env, jobject obj, jobject fdo,
void JNICALL MappedMemoryUtils_force0(JNIEnv *env, jobject obj, jobject fdo,
jlong address, jlong len)
{
void *a = (void *) jlong_to_ptr(address);
@ -106,3 +102,19 @@ Java_java_nio_MappedMemoryUtils_force0(JNIEnv *env, jobject obj, jobject fdo,
JNU_ThrowIOExceptionWithLastError(env, "Flush failed");
}
}
#define FD "Ljava/io/FileDescriptor;"
static JNINativeMethod methods[] = {
{"isLoaded0", "(JJJ)Z", (void *)&MappedMemoryUtils_isLoaded0},
{"load0", "(JJ)V", (void *)&MappedMemoryUtils_load0},
{"unload0", "(JJ)V", (void *)&MappedMemoryUtils_unload0},
{"force0", "(" FD "JJ)V", (void *)&MappedMemoryUtils_force0},
};
JNIEXPORT void JNICALL
Java_java_nio_MappedMemoryUtils_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls,
methods, sizeof(methods)/sizeof(methods[0]));
}