Skip to content

Commit

Permalink
AArch64: Compressed pointer decoding optimization when base is zero.
Browse files Browse the repository at this point in the history
Currently decoding a compressed pointer with zero base will generate
the following code:
add x0, xzr, x0, lsl #3

This patch will optimize it to:
lsl x0, x0, #3

Here is a jmh benchmark to decode a compressed pointer:
public class UncompressPointer {
    private static final int field0 = 1000000;
    private int field1;

    static class A {
        B b;

        A(B b) {
            this.b = b;
        }
    }

    static class B {
        int field;

        B(int i) {
            this.field = i;
        }
    }

    static A[] arr;

    static {
        arr = new A[field0];
        for (int i = 0; i < field0; i++)
           arr[i] = new A(new B(i));
    }

    public static int func() {
        int result = 0;
        for (int i = 0; i < field0; i++) {
            result += arr[i].b.field;
        }
        return result;
    }

    @benchmark
    public void jmhUncompressPointer() {
        field1 = func();
    }
}
And the performance results:
                         Score      Error    Units
Without this patch     21598.534 ? 2188.242  us/op
With this patch        19322.791 ? 1219.022  us/op

Change-Id: I5af6799eb82470d5598f5991e9210f99874f458a
  • Loading branch information
Xiaohong Gong committed Mar 25, 2019
1 parent 5961eb3 commit a44a5dc
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 3 deletions.
1 change: 1 addition & 0 deletions compiler/mx.compiler/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@
"dependencies" : [
"org.graalvm.compiler.asm.aarch64",
"org.graalvm.compiler.hotspot.test",
"org.graalvm.compiler.hotspot.aarch64",
],
"annotationProcessors" : ["GRAAL_NODEINFO_PROCESSOR"],
"checkstyle" : "org.graalvm.compiler.graph",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, Arm Limited and 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/

package org.graalvm.compiler.hotspot.aarch64.test;

import jdk.vm.ci.aarch64.AArch64;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.runtime.JVMCI;
import org.graalvm.compiler.asm.aarch64.AArch64Assembler;
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.hotspot.aarch64.AArch64HotSpotMove;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assume.assumeTrue;

public class AArch64UncompressPointerTest extends GraalCompilerTest {

private AArch64MacroAssembler masm1;
private AArch64MacroAssembler masm2;
private Register input;
private Register result;

@Before
public void checkAArch64() {
assumeTrue("skipping AArch64 specific test", JVMCI.getRuntime().getHostJVMCIBackend().getTarget().arch instanceof AArch64);
}

@Before
public void setupEnvironment() {
TargetDescription target = JVMCI.getRuntime().getHostJVMCIBackend().getTarget();
masm1 = new AArch64MacroAssembler(target);
masm2 = new AArch64MacroAssembler(target);
input = AArch64.r10;
result = AArch64.r11;
}

private void emitUncompressPointer(Register base, int shift) {
AArch64HotSpotMove.UncompressPointer.emitUncompressCode(masm2, input, result, base, shift, true);
}

private void compareAssembly() {
byte[] expected = masm1.close(false);
byte[] actual = masm2.close(false);
assertArrayEquals(expected, actual);
}

@Test
public void testUncompressPointerWithBase() {
Register base = AArch64.r12;
int shift = 3;
masm1.add(64, result, base, input, AArch64Assembler.ShiftType.LSL, shift);
emitUncompressPointer(base, shift);
compareAssembly();
}

@Test
public void testUncompressPointerWithZeroBase() {
int shift = 3;
masm1.shl(64, result, input, shift);
emitUncompressPointer(null, shift);
compareAssembly();
}

@Test
public void testUncompressPointerWithZeroBaseAndShift() {
masm1.or(64, result, AArch64.zr, input);
emitUncompressPointer(null, 0);
compareAssembly();
}

static class A {
String str;

A(String str) {
this.str = str;
}
}

public static String getObjectField(A a) {
return a.str;
}

@Test
public void testGetObjectField() {
test("getObjectField", new A("asfghjkjhgfd"));
}

static String[] strings = {"asf", "egfda", "fsdasere", "eqwred", "fgdadgtre", "qwrrtreety"};

public static String getArrayMember(int index) {
return strings[index];
}

@Test
public void testGetArrayMember() {
test("getArrayMember", 4);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2019, 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
Expand Down Expand Up @@ -194,9 +194,19 @@ public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
}

public static void emitUncompressCode(AArch64MacroAssembler masm, Register inputRegister, Register resReg, Register baseReg, int shift, boolean nonNull) {
// result = ptr << shift
if (baseReg == null) {
if (shift != 0) {
masm.shl(64, resReg, inputRegister, shift);
} else if (!resReg.equals(inputRegister)) {
masm.movx(resReg, inputRegister);
}
return;
}

// result = base + (ptr << shift)
if (nonNull || baseReg == null) {
masm.add(64, resReg, baseReg == null ? zr : baseReg, inputRegister, AArch64Assembler.ShiftType.LSL, shift);
if (nonNull) {
masm.add(64, resReg, baseReg, inputRegister, AArch64Assembler.ShiftType.LSL, shift);
} else {
// if ptr is null it has to be null after decompression
Label done = new Label();
Expand Down

0 comments on commit a44a5dc

Please sign in to comment.