Skip to content
Permalink
Browse files

8237521: Memory Access API fixes for 32-bit

Reviewed-by: mcimadamore, dholmes
  • Loading branch information
nick-arm committed Jan 24, 2020
1 parent 44444bb commit 987ba9f3a4c3e5f903d7e12593596b81ac128801
@@ -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 @@ private void checkPrimitivePointer(Object o, long offset) {

/// 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 @@ private void checkPrimitivePointer(Object o, long offset) {
* @see #putByte(long, byte)
*/
public long allocateMemory(long bytes) {
bytes = alignToHeapWordSize(bytes);

allocateMemoryChecks(bytes);

if (bytes == 0) {
@@ -661,6 +674,8 @@ private void allocateMemoryChecks(long bytes) {
* @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 @@

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 static void main(String args[]) throws Exception {
// 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.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 void testArrays(Consumer<MemoryAddress> init, SequenceLayout layout) {
}

@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 void testBufferOnClosedScope() {
}

@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
*/

0 comments on commit 987ba9f

Please sign in to comment.