CallingConvention.java revision 12651:6ef01bd40ce2
1/*
2 * Copyright (c) 2009, 2012, 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 jdk.vm.ci.code;
24
25import static jdk.vm.ci.code.ValueUtil.isAllocatableValue;
26import static jdk.vm.ci.code.ValueUtil.isStackSlot;
27import jdk.vm.ci.meta.AllocatableValue;
28import jdk.vm.ci.meta.Value;
29
30/**
31 * A calling convention describes the locations in which the arguments for a call are placed and the
32 * location in which the return value is placed if the call is not void.
33 */
34public class CallingConvention {
35
36    /**
37     * Marker interface denoting the type of a call for which a calling convention is requested.
38     */
39    public interface Type {
40    }
41
42    /**
43     * The amount of stack space (in bytes) required for the stack-based arguments of the call.
44     */
45    private final int stackSize;
46
47    private final AllocatableValue returnLocation;
48
49    /**
50     * The ordered locations in which the arguments are placed.
51     */
52    private final AllocatableValue[] argumentLocations;
53
54    /**
55     * Creates a description of the registers and stack locations used by a call.
56     *
57     * @param stackSize amount of stack space (in bytes) required for the stack-based arguments of
58     *            the call
59     * @param returnLocation the location for the return value or {@link Value#ILLEGAL} if a void
60     *            call
61     * @param argumentLocations the ordered locations in which the arguments are placed
62     */
63    public CallingConvention(int stackSize, AllocatableValue returnLocation, AllocatableValue... argumentLocations) {
64        assert argumentLocations != null;
65        assert returnLocation != null;
66        this.argumentLocations = argumentLocations;
67        this.stackSize = stackSize;
68        this.returnLocation = returnLocation;
69        assert verify();
70    }
71
72    /**
73     * Gets the location for the return value or {@link Value#ILLEGAL} if a void call.
74     */
75    public AllocatableValue getReturn() {
76        return returnLocation;
77    }
78
79    /**
80     * Gets the location for the {@code index}'th argument.
81     */
82    public AllocatableValue getArgument(int index) {
83        return argumentLocations[index];
84    }
85
86    /**
87     * Gets the amount of stack space (in bytes) required for the stack-based arguments of the call.
88     */
89    public int getStackSize() {
90        return stackSize;
91    }
92
93    /**
94     * Gets the number of locations required for the arguments.
95     */
96    public int getArgumentCount() {
97        return argumentLocations.length;
98    }
99
100    /**
101     * Gets the locations required for the arguments.
102     */
103    @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "FB false positive")
104    public AllocatableValue[] getArguments() {
105        if (argumentLocations.length == 0) {
106            return argumentLocations;
107        }
108        return argumentLocations.clone();
109    }
110
111    @Override
112    public String toString() {
113        StringBuilder sb = new StringBuilder();
114        sb.append("CallingConvention[");
115        String sep = "";
116        for (Value op : argumentLocations) {
117            sb.append(sep).append(op);
118            sep = ", ";
119        }
120        if (!returnLocation.equals(Value.ILLEGAL)) {
121            sb.append(" -> ").append(returnLocation);
122        }
123        sb.append("]");
124        return sb.toString();
125    }
126
127    private boolean verify() {
128        for (int i = 0; i < argumentLocations.length; i++) {
129            Value location = argumentLocations[i];
130            assert isStackSlot(location) || isAllocatableValue(location);
131        }
132        return true;
133    }
134}
135