AArch64HotSpotSafepointOp.java revision 12657:6ef01bd40ce2
1/*
2 * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23package org.graalvm.compiler.hotspot.aarch64;
24
25import static jdk.vm.ci.aarch64.AArch64.zr;
26import static jdk.vm.ci.code.ValueUtil.asRegister;
27
28import org.graalvm.compiler.asm.NumUtil;
29import org.graalvm.compiler.asm.aarch64.AArch64Address;
30import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
31import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
32import org.graalvm.compiler.lir.LIRFrameState;
33import org.graalvm.compiler.lir.LIRInstructionClass;
34import org.graalvm.compiler.lir.Opcode;
35import org.graalvm.compiler.lir.aarch64.AArch64LIRInstruction;
36import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
37
38import jdk.vm.ci.code.Register;
39import jdk.vm.ci.code.site.InfopointReason;
40import jdk.vm.ci.meta.AllocatableValue;
41
42/**
43 * Emits a safepoint poll.
44 */
45@Opcode("SAFEPOINT")
46public class AArch64HotSpotSafepointOp extends AArch64LIRInstruction {
47    public static final LIRInstructionClass<AArch64HotSpotSafepointOp> TYPE = LIRInstructionClass.create(AArch64HotSpotSafepointOp.class);
48
49    @State protected LIRFrameState state;
50    @Temp protected AllocatableValue scratchValue;
51
52    private final GraalHotSpotVMConfig config;
53
54    public AArch64HotSpotSafepointOp(LIRFrameState state, GraalHotSpotVMConfig config, AllocatableValue scratch) {
55        super(TYPE);
56        this.state = state;
57        this.config = config;
58        this.scratchValue = scratch;
59    }
60
61    @Override
62    public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
63        Register scratch = asRegister(scratchValue);
64        emitCode(crb, masm, config, false, scratch, state);
65    }
66
67    /**
68     * Conservatively checks whether we can load the safepoint polling address with a single ldr
69     * instruction or not.
70     *
71     * @return true if it is guaranteed that polling page offset will always fit into a 21-bit
72     *         signed integer, false otherwise.
73     */
74    private static boolean isPollingPageFar(GraalHotSpotVMConfig config) {
75        final long pollingPageAddress = config.safepointPollingAddress;
76        return !NumUtil.isSignedNbit(21, pollingPageAddress - config.codeCacheLowBound) || !NumUtil.isSignedNbit(21, pollingPageAddress - config.codeCacheHighBound);
77    }
78
79    public static void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm, GraalHotSpotVMConfig config, boolean onReturn, Register scratch, LIRFrameState state) {
80        int pos = masm.position();
81        if (isPollingPageFar(config)) {
82            crb.recordMark(onReturn ? config.MARKID_POLL_RETURN_FAR : config.MARKID_POLL_FAR);
83            masm.movNativeAddress(scratch, config.safepointPollingAddress);
84            if (state != null) {
85                crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
86            }
87            masm.ldr(32, zr, AArch64Address.createBaseRegisterOnlyAddress(scratch));
88        } else {
89            crb.recordMark(onReturn ? config.MARKID_POLL_RETURN_NEAR : config.MARKID_POLL_NEAR);
90            if (state != null) {
91                crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
92            }
93            masm.ldr(32, zr, AArch64Address.createPcLiteralAddress(0));
94        }
95    }
96
97}
98