HotSpotHostBackend.java revision 12651:6ef01bd40ce2
1139825Simp/*
282899Sjake * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
380708Sjake * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
480708Sjake *
582899Sjake * This code is free software; you can redistribute it and/or modify it
682899Sjake * under the terms of the GNU General Public License version 2 only, as
782899Sjake * published by the Free Software Foundation.
882899Sjake *
980708Sjake * This code is distributed in the hope that it will be useful, but WITHOUT
1080708Sjake * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1180708Sjake * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1280708Sjake * version 2 for more details (a copy is included in the LICENSE file that
1380708Sjake * accompanied this code).
1480708Sjake *
1580708Sjake * You should have received a copy of the GNU General Public License version
1680708Sjake * 2 along with this work; if not, write to the Free Software Foundation,
1782899Sjake * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1882899Sjake *
1982899Sjake * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2080708Sjake * or visit www.oracle.com if you need additional information or have any
2182899Sjake * questions.
2280708Sjake */
2380708Sjakepackage org.graalvm.compiler.hotspot;
2482899Sjake
2580708Sjakeimport static jdk.vm.ci.code.CodeUtil.getCallingConvention;
2680708Sjakeimport static jdk.vm.ci.common.InitTimer.timer;
2780708Sjake
2880708Sjakeimport org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
2980708Sjakeimport org.graalvm.compiler.hotspot.meta.HotSpotHostForeignCallsProvider;
3080708Sjakeimport org.graalvm.compiler.hotspot.meta.HotSpotLoweringProvider;
3180708Sjakeimport org.graalvm.compiler.hotspot.meta.HotSpotProviders;
3280708Sjakeimport org.graalvm.compiler.hotspot.stubs.DeoptimizationStub;
3382899Sjakeimport org.graalvm.compiler.hotspot.stubs.Stub;
3482899Sjakeimport org.graalvm.compiler.hotspot.stubs.UncommonTrapStub;
3582899Sjakeimport org.graalvm.compiler.lir.asm.CompilationResultBuilder;
3680708Sjakeimport org.graalvm.compiler.lir.framemap.ReferenceMapBuilder;
3780708Sjakeimport org.graalvm.compiler.nodes.StructuredGraph;
3880708Sjake
3980708Sjakeimport jdk.vm.ci.code.CallingConvention;
4080708Sjakeimport jdk.vm.ci.common.InitTimer;
4180708Sjakeimport jdk.vm.ci.hotspot.HotSpotCallingConventionType;
42104265Sjakeimport jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
43133451Salcimport jdk.vm.ci.meta.JavaType;
44133451Salcimport jdk.vm.ci.runtime.JVMCICompiler;
45112399Sjake
4680709Sjake/**
4780709Sjake * Common functionality of HotSpot host backends.
4880709Sjake */
4980709Sjakepublic abstract class HotSpotHostBackend extends HotSpotBackend {
5080709Sjake
5180709Sjake    /**
5283053Sobrien     * Descriptor for {@code SharedRuntime::deopt_blob()->unpack()} or
53108166Sjake     * {@link DeoptimizationStub#deoptimizationHandler} depending on
54108166Sjake     * {@link HotSpotBackend.Options#PreferGraalStubs}.
55108166Sjake     */
56108166Sjake    public static final ForeignCallDescriptor DEOPTIMIZATION_HANDLER = new ForeignCallDescriptor("deoptHandler", void.class);
57108166Sjake
5880708Sjake    /**
5980708Sjake     * Descriptor for {@code SharedRuntime::deopt_blob()->uncommon_trap()} or
6083053Sobrien     * {@link UncommonTrapStub#uncommonTrapHandler} depending on
61133451Salc     * {@link HotSpotBackend.Options#PreferGraalStubs}.
6288651Sjake     */
6388651Sjake    public static final ForeignCallDescriptor UNCOMMON_TRAP_HANDLER = new ForeignCallDescriptor("uncommonTrapHandler", void.class);
6480709Sjake
6591288Sjake    protected final GraalHotSpotVMConfig config;
6680709Sjake
6780708Sjake    public HotSpotHostBackend(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) {
6880708Sjake        super(runtime, providers);
69133451Salc        this.config = config;
70133451Salc    }
71133451Salc
72133451Salc    @Override
73133451Salc    @SuppressWarnings("try")
74142045Smarius    public void completeInitialization(HotSpotJVMCIRuntime jvmciRuntime) {
75133451Salc        final HotSpotProviders providers = getProviders();
76133451Salc        HotSpotHostForeignCallsProvider foreignCalls = (HotSpotHostForeignCallsProvider) providers.getForeignCalls();
77133451Salc        final HotSpotLoweringProvider lowerer = (HotSpotLoweringProvider) providers.getLowerer();
78133451Salc
79133451Salc        try (InitTimer st = timer("foreignCalls.initialize")) {
80195649Salc            foreignCalls.initialize(providers);
81195649Salc        }
82195649Salc        try (InitTimer st = timer("lowerer.initialize")) {
83195149Smarius            lowerer.initialize(providers, config);
84113238Sjake        }
85113238Sjake    }
86112312Sjake
87113238Sjake    protected CallingConvention makeCallingConvention(StructuredGraph graph, Stub stub) {
8898813Sjake        if (stub != null) {
89129068Salc            return stub.getLinkage().getIncomingCallingConvention();
9080708Sjake        }
9188651Sjake
9288651Sjake        CallingConvention cc = getCallingConvention(getCodeCache(), HotSpotCallingConventionType.JavaCallee, graph.method(), this);
9388651Sjake        if (graph.getEntryBCI() != JVMCICompiler.INVOCATION_ENTRY_BCI) {
9497447Sjake            // for OSR, only a pointer is passed to the method.
9597447Sjake            JavaType[] parameterTypes = new JavaType[]{getMetaAccess().lookupJavaType(long.class)};
9697447Sjake            CallingConvention tmp = getCodeCache().getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCallee, getMetaAccess().lookupJavaType(void.class), parameterTypes, this);
9797447Sjake            cc = new CallingConvention(cc.getStackSize(), cc.getReturn(), tmp.getArgument(0));
9897447Sjake        }
9989041Sjake        return cc;
10089041Sjake    }
101153179Sjhb
10284844Stmm    public void emitStackOverflowCheck(CompilationResultBuilder crb) {
10388651Sjake        if (config.useStackBanging) {
10488651Sjake            // Each code entry causes one stack bang n pages down the stack where n
105113238Sjake            // is configurable by StackShadowPages. The setting depends on the maximum
10680708Sjake            // depth of VM call stack or native before going back into java code,
10780708Sjake            // since only java code can raise a stack overflow exception using the
10880708Sjake            // stack banging mechanism. The VM and native code does not detect stack
109108700Sjake            // overflow.
110108700Sjake            // The code in JavaCalls::call() checks that there is at least n pages
111108700Sjake            // available, so all entry code needs to do is bang once for the end of
112108700Sjake            // this shadow zone.
113108700Sjake            // The entry code may need to bang additional pages if the framesize
114108700Sjake            // is greater than a page.
115113171Sjake
116108700Sjake            int pageSize = config.vmPageSize;
117108700Sjake            int bangEnd = config.stackShadowPages * pageSize;
118108700Sjake
119108700Sjake            // This is how far the previous frame's stack banging extended.
120108700Sjake            int bangEndSafe = bangEnd;
121108700Sjake
122108700Sjake            int frameSize = Math.max(crb.frameMap.frameSize(), crb.compilationResult.getMaxInterpreterFrameSize());
123108700Sjake            if (frameSize > pageSize) {
124108700Sjake                bangEnd += frameSize;
125108700Sjake            }
126108700Sjake
127108700Sjake            int bangOffset = bangEndSafe;
12880708Sjake            if (bangOffset <= bangEnd) {
129                crb.blockComment("[stack overflow check]");
130            }
131            while (bangOffset <= bangEnd) {
132                // Need at least one stack bang at end of shadow zone.
133                bangStackWithOffset(crb, bangOffset);
134                bangOffset += pageSize;
135            }
136        }
137    }
138
139    protected abstract void bangStackWithOffset(CompilationResultBuilder crb, int bangOffset);
140
141    @Override
142    public ReferenceMapBuilder newReferenceMapBuilder(int totalFrameSize) {
143        return new HotSpotReferenceMapBuilder(totalFrameSize, config.maxOopMapStackOffset);
144    }
145
146}
147