blob: 3f125ca2c700e441768d3ca0a22377ce8d7e9076 [file] [log] [blame]
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class Main {
private static final Unsafe unsafe = getUnsafe();
public int i = 0;
public long l = 0;
public static void main(String[] args) {
$noinline$testGetAndAdd();
}
private static void $noinline$testGetAndAdd() {
final Main m = new Main();
final long intOffset, longOffset;
try {
Field intField = Main.class.getDeclaredField("i");
Field longField = Main.class.getDeclaredField("l");
intOffset = unsafe.objectFieldOffset(intField);
longOffset = unsafe.objectFieldOffset(longField);
} catch (NoSuchFieldException e) {
throw new Error("No offset: " + e);
}
$noinline$add(m, intOffset, 11);
assertEquals(11, m.i);
$noinline$add(m, intOffset, 13);
assertEquals(24, m.i);
$noinline$add(m, longOffset, 11L);
assertEquals(11L, m.l);
$noinline$add(m, longOffset, 13L);
assertEquals(24L, m.l);
}
// UnsafeGetAndAddInt/Long are part of core-oj and we will not inline on host.
/// CHECK-START-{ARM,ARM64}: int Main.$noinline$add(java.lang.Object, long, int) inliner (before)
/// CHECK: InvokeVirtual intrinsic:UnsafeGetAndAddInt
/// CHECK-START-{ARM,ARM64}: int Main.$noinline$add(java.lang.Object, long, int) inliner (after)
/// CHECK-NOT: InvokeVirtual intrinsic:UnsafeGetAndAddInt
private static int $noinline$add(Object o, long offset, int delta) {
return unsafe.getAndAddInt(o, offset, delta);
}
/// CHECK-START-{ARM,ARM64}: long Main.$noinline$add(java.lang.Object, long, long) inliner (before)
/// CHECK: InvokeVirtual intrinsic:UnsafeGetAndAddLong
/// CHECK-START-{ARM,ARM64}: long Main.$noinline$add(java.lang.Object, long, long) inliner (after)
/// CHECK-NOT: InvokeVirtual intrinsic:UnsafeGetAndAddLong
private static long $noinline$add(Object o, long offset, long delta) {
return unsafe.getAndAddLong(o, offset, delta);
}
private static Unsafe getUnsafe() {
try {
Class<?> unsafeClass = Unsafe.class;
Field f = unsafeClass.getDeclaredField("theUnsafe");
f.setAccessible(true);
return (Unsafe) f.get(null);
} catch (Exception e) {
throw new Error("Cannot get Unsafe instance");
}
}
private static void assertEquals(int expected, int result) {
if (expected != result) {
throw new Error("Expected: " + expected + ", found: " + result);
}
}
private static void assertEquals(long expected, long result) {
if (expected != result) {
throw new Error("Expected: " + expected + ", found: " + result);
}
}
}