mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-20 12:53:29 +00:00
8178047: Aliasing problem with raw memory accesses
Require equal bases when unaliasing offsets for raw accesses Reviewed-by: kvn
This commit is contained in:
parent
1457155505
commit
34dec39bc2
@ -61,6 +61,15 @@ const TypePtr *MemNode::adr_type() const {
|
||||
return calculate_adr_type(adr->bottom_type(), cross_check);
|
||||
}
|
||||
|
||||
bool MemNode::check_if_adr_maybe_raw(Node* adr) {
|
||||
if (adr != NULL) {
|
||||
if (adr->bottom_type()->base() == Type::RawPtr || adr->bottom_type()->base() == Type::AnyPtr) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void MemNode::dump_spec(outputStream *st) const {
|
||||
if (in(Address) == NULL) return; // node is dead
|
||||
@ -560,6 +569,7 @@ Node* MemNode::find_previous_store(PhaseTransform* phase) {
|
||||
if (offset == Type::OffsetBot)
|
||||
return NULL; // cannot unalias unless there are precise offsets
|
||||
|
||||
const bool adr_maybe_raw = check_if_adr_maybe_raw(adr);
|
||||
const TypeOopPtr *addr_t = adr->bottom_type()->isa_oopptr();
|
||||
|
||||
intptr_t size_in_bytes = memory_size();
|
||||
@ -577,6 +587,13 @@ Node* MemNode::find_previous_store(PhaseTransform* phase) {
|
||||
Node* st_base = AddPNode::Ideal_base_and_offset(st_adr, phase, st_offset);
|
||||
if (st_base == NULL)
|
||||
break; // inscrutable pointer
|
||||
|
||||
// For raw accesses it's not enough to prove that constant offsets don't intersect.
|
||||
// We need the bases to be the equal in order for the offset check to make sense.
|
||||
if ((adr_maybe_raw || check_if_adr_maybe_raw(st_adr)) && st_base != base) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (st_offset != offset && st_offset != Type::OffsetBot) {
|
||||
const int MAX_STORE = BytesPerLong;
|
||||
if (st_offset >= offset + size_in_bytes ||
|
||||
|
||||
@ -78,6 +78,7 @@ protected:
|
||||
}
|
||||
|
||||
virtual Node* find_previous_arraycopy(PhaseTransform* phase, Node* ld_alloc, Node*& mem, bool can_see_stored_value) const { return NULL; }
|
||||
static bool check_if_adr_maybe_raw(Node* adr);
|
||||
|
||||
public:
|
||||
// Helpers for the optimizer. Documented in memnode.cpp.
|
||||
|
||||
71
hotspot/test/compiler/unsafe/TestRawAliasing.java
Normal file
71
hotspot/test/compiler/unsafe/TestRawAliasing.java
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8178047
|
||||
* @run main/othervm -XX:CompileCommand=exclude,*.main -XX:-TieredCompilation -XX:-BackgroundCompilation compiler.unsafe.TestRawAliasing
|
||||
* @modules java.base/jdk.internal.misc:+open
|
||||
*/
|
||||
|
||||
package compiler.unsafe;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class TestRawAliasing {
|
||||
static private final jdk.internal.misc.Unsafe UNSAFE;
|
||||
static {
|
||||
try {
|
||||
Field f = jdk.internal.misc.Unsafe.class.getDeclaredField("theUnsafe");
|
||||
f.setAccessible(true);
|
||||
UNSAFE = (jdk.internal.misc.Unsafe) f.get(null);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to get Unsafe instance.", e);
|
||||
}
|
||||
}
|
||||
|
||||
static private final int OFFSET_X = 50;
|
||||
static private final int OFFSET_Y = 100;
|
||||
|
||||
private static int test(long base_plus_offset_x, long base_plus_offset_y, int magic_value) {
|
||||
// write 0 to a location
|
||||
UNSAFE.putByte(base_plus_offset_x - OFFSET_X, (byte)0);
|
||||
// write unfoldable value to really the same location with another base
|
||||
UNSAFE.putByte(base_plus_offset_y - OFFSET_Y, (byte)magic_value);
|
||||
// read the value back, should be equal to "unfoldable_value"
|
||||
return UNSAFE.getByte(base_plus_offset_x - OFFSET_X);
|
||||
}
|
||||
|
||||
private static final int OFF_HEAP_AREA_SIZE = 128;
|
||||
private static final byte MAGIC = 123;
|
||||
|
||||
// main is excluded from compilation since we don't want the test method to inline and make base values fold
|
||||
public static void main(String... args) {
|
||||
long base = UNSAFE.allocateMemory(OFF_HEAP_AREA_SIZE);
|
||||
for (int i = 0; i < 100_000; i++) {
|
||||
if (test(base + OFFSET_X, base + OFFSET_Y, MAGIC) != MAGIC) {
|
||||
throw new RuntimeException("Unexpected magic value");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user