changeset 58835: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();
     }
 
--- a/test/jdk/java/foreign/TestMemoryAlignment.java	Thu Jan 30 10:31:43 2020 -0500
+++ b/test/jdk/java/foreign/TestMemoryAlignment.java	Fri Jan 24 17:41:44 2020 +0800
@@ -23,7 +23,6 @@
 
 /*
  * @test
- * @requires vm.bits != "32"
  * @run testng TestMemoryAlignment
  */