8237521: Memory Access API fixes for 32-bit

Reviewed-by: mcimadamore, dholmes
This commit is contained in:
Nick Gasson 2020-01-24 17:41:44 +08:00
parent 44444bb249
commit 987ba9f3a4
7 changed files with 49 additions and 22 deletions
src
hotspot/share/prims
java.base/share/classes/jdk/internal/misc
jdk.incubator.foreign/share/classes/jdk/internal/foreign
test

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2020, 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
@ -360,7 +360,8 @@ UNSAFE_ENTRY(jobject, Unsafe_AllocateInstance(JNIEnv *env, jobject unsafe, jclas
UNSAFE_ENTRY(jlong, Unsafe_AllocateMemory0(JNIEnv *env, jobject unsafe, jlong size)) {
size_t sz = (size_t)size;
sz = align_up(sz, HeapWordSize);
assert(is_aligned(sz, HeapWordSize), "sz not aligned");
void* x = os::malloc(sz, mtOther);
return addr_to_java(x);
@ -369,7 +370,8 @@ UNSAFE_ENTRY(jlong, Unsafe_AllocateMemory0(JNIEnv *env, jobject unsafe, jlong si
UNSAFE_ENTRY(jlong, Unsafe_ReallocateMemory0(JNIEnv *env, jobject unsafe, jlong addr, jlong size)) {
void* p = addr_from_java(addr);
size_t sz = (size_t)size;
sz = align_up(sz, HeapWordSize);
assert(is_aligned(sz, HeapWordSize), "sz not aligned");
void* x = os::realloc(p, sz, mtOther);

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2020, 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
@ -583,6 +583,17 @@ public final class Unsafe {
/// wrappers for malloc, realloc, free:
/**
* Round up allocation size to a multiple of HeapWordSize.
*/
private long alignToHeapWordSize(long bytes) {
if (bytes >= 0) {
return (bytes + ADDRESS_SIZE - 1) & ~(ADDRESS_SIZE - 1);
} else {
throw invalidInput();
}
}
/**
* Allocates a new block of native memory, of the given size in bytes. The
* contents of the memory are uninitialized; they will generally be
@ -608,6 +619,8 @@ public final class Unsafe {
* @see #putByte(long, byte)
*/
public long allocateMemory(long bytes) {
bytes = alignToHeapWordSize(bytes);
allocateMemoryChecks(bytes);
if (bytes == 0) {
@ -661,6 +674,8 @@ public final class Unsafe {
* @see #allocateMemory
*/
public long reallocateMemory(long address, long bytes) {
bytes = alignToHeapWordSize(bytes);
reallocateMemoryChecks(address, bytes);
if (bytes == 0) {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020, 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
@ -49,8 +49,9 @@ public final class Utils {
private static Unsafe unsafe = Unsafe.getUnsafe();
// The maximum alignment supported by malloc - typically 16 on 64-bit platforms.
private final static long MAX_ALIGN = 16;
// The maximum alignment supported by malloc - typically 16 on
// 64-bit platforms and 8 on 32-bit platforms.
private final static long MAX_ALIGN = Unsafe.ADDRESS_SIZE == 4 ? 8 : 16;
private static final JavaNioAccess javaNioAccess = SharedSecrets.getJavaNioAccess();

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2020, 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
@ -59,10 +59,29 @@ public class AllocateMemory {
// we test this by limiting the malloc using -XX:MallocMaxTestWords
try {
address = unsafe.allocateMemory(100 * 1024 * 1024 * 8);
throw new RuntimeException("Did not get expected OutOfMemoryError");
} catch (OutOfMemoryError e) {
// Expected
return;
}
throw new RuntimeException("Did not get expected OutOfMemoryError");
// Allocation should fail on a 32-bit system if the aligned-up
// size overflows a size_t
if (Unsafe.ADDRESS_SIZE == 4) {
try {
address = unsafe.allocateMemory((long)Integer.MAX_VALUE * 2);
throw new RuntimeException("Did not get expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// Expected
}
}
// Allocation should fail if the aligned-up size overflows a
// Java long
try {
address = unsafe.allocateMemory((long)Long.MAX_VALUE);
throw new RuntimeException("Did not get expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// Expected
}
}
}

@ -38,7 +38,6 @@ import java.lang.invoke.VarHandle;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.testng.SkipException;
import org.testng.annotations.*;
import static org.testng.Assert.*;
@ -105,12 +104,8 @@ public class TestArrays {
}
@Test(expectedExceptions = { UnsupportedOperationException.class,
OutOfMemoryError.class })
IllegalArgumentException.class })
public void testTooBigForArray() {
if (System.getProperty("sun.arch.data.model").equals("32")) {
throw new SkipException("32-bit Unsafe does not support this allocation size");
}
MemorySegment.allocateNative((long) Integer.MAX_VALUE * 2).toByteArray();
}

@ -394,12 +394,8 @@ public class TestByteBuffer {
}
@Test(expectedExceptions = { UnsupportedOperationException.class,
OutOfMemoryError.class })
IllegalArgumentException.class })
public void testTooBigForByteBuffer() {
if (System.getProperty("sun.arch.data.model").equals("32")) {
throw new SkipException("32-bit Unsafe does not support this allocation size");
}
MemorySegment.allocateNative((long) Integer.MAX_VALUE * 2).asByteBuffer();
}

@ -23,7 +23,6 @@
/*
* @test
* @requires vm.bits != "32"
* @run testng TestMemoryAlignment
*/