OpenJDK / jdk / jdk
changeset 57894:41f1e738b639
8237521: Memory Access API fixes for 32-bit
Reviewed-by: mcimadamore, dholmes
author | ngasson |
---|---|
date | Fri, 24 Jan 2020 17:41:44 +0800 |
parents | abb879864b99 |
children | 2dbf459b5577 |
files | src/hotspot/share/prims/unsafe.cpp src/java.base/share/classes/jdk/internal/misc/Unsafe.java src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/Utils.java test/hotspot/jtreg/runtime/Unsafe/AllocateMemory.java test/jdk/java/foreign/TestArrays.java test/jdk/java/foreign/TestByteBuffer.java test/jdk/java/foreign/TestMemoryAlignment.java |
diffstat | 7 files changed, 49 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/src/hotspot/share/prims/unsafe.cpp Thu Jan 30 10:31:43 2020 -0500 +++ b/src/hotspot/share/prims/unsafe.cpp Fri Jan 24 17:41:44 2020 +0800 @@ -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(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_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);
--- a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java Thu Jan 30 10:31:43 2020 -0500 +++ b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java Fri Jan 24 17:41:44 2020 +0800 @@ -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 @@ -584,6 +584,17 @@ /// 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 * garbage. The resulting native pointer will never be zero, and will be @@ -608,6 +619,8 @@ * @see #putByte(long, byte) */ public long allocateMemory(long bytes) { + bytes = alignToHeapWordSize(bytes); + allocateMemoryChecks(bytes); if (bytes == 0) { @@ -661,6 +674,8 @@ * @see #allocateMemory */ public long reallocateMemory(long address, long bytes) { + bytes = alignToHeapWordSize(bytes); + reallocateMemoryChecks(address, bytes); if (bytes == 0) {
--- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/Utils.java Thu Jan 30 10:31:43 2020 -0500 +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/Utils.java Fri Jan 24 17:41:44 2020 +0800 @@ -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 @@ 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();
--- a/test/hotspot/jtreg/runtime/Unsafe/AllocateMemory.java Thu Jan 30 10:31:43 2020 -0500 +++ b/test/hotspot/jtreg/runtime/Unsafe/AllocateMemory.java Fri Jan 24 17:41:44 2020 +0800 @@ -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 @@ // 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 + } } }
--- a/test/jdk/java/foreign/TestArrays.java Thu Jan 30 10:31:43 2020 -0500 +++ b/test/jdk/java/foreign/TestArrays.java Fri Jan 24 17:41:44 2020 +0800 @@ -38,7 +38,6 @@ 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 @@ } @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(); }
--- a/test/jdk/java/foreign/TestByteBuffer.java Thu Jan 30 10:31:43 2020 -0500 +++ b/test/jdk/java/foreign/TestByteBuffer.java Fri Jan 24 17:41:44 2020 +0800 @@ -394,12 +394,8 @@ } @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(); }