Mercurial > hg > truffle
comparison graal/com.oracle.max.cri/src/com/sun/cri/ci/CiStackSlot.java @ 3733:e233f5660da4
Added Java files from Maxine project.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sat, 17 Dec 2011 19:59:18 +0100 |
parents | |
children | bc8527f3071c |
comparison
equal
deleted
inserted
replaced
3732:3e2e8b8abdaf | 3733:e233f5660da4 |
---|---|
1 /* | |
2 * Copyright (c) 2010, 2011, 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 */ | |
23 package com.sun.cri.ci; | |
24 | |
25 /** | |
26 * Represents a compiler spill slot or an outgoing stack-based argument in a method's frame | |
27 * or an incoming stack-based argument in a method's {@linkplain #inCallerFrame() caller's frame}. | |
28 */ | |
29 public final class CiStackSlot extends CiValue { | |
30 | |
31 /** | |
32 * @see CiStackSlot#index() | |
33 */ | |
34 private final int index; | |
35 | |
36 /** | |
37 * Gets a {@link CiStackSlot} instance representing a stack slot in the current frame | |
38 * at a given index holding a value of a given kind. | |
39 * | |
40 * @param kind the kind of the value stored in the stack slot | |
41 * @param index the index of the stack slot | |
42 */ | |
43 public static CiStackSlot get(CiKind kind, int index) { | |
44 return get(kind, index, false); | |
45 } | |
46 | |
47 /** | |
48 * Gets a {@link CiStackSlot} instance representing a stack slot at a given index | |
49 * holding a value of a given kind. | |
50 * | |
51 * @param kind the kind of the value stored in the stack slot | |
52 * @param index the index of the stack slot | |
53 * @param inCallerFrame specifies if the slot is in the current frame or in the caller's frame | |
54 */ | |
55 public static CiStackSlot get(CiKind kind, int index, boolean inCallerFrame) { | |
56 assert kind.stackKind() == kind; | |
57 CiStackSlot[][] cache = inCallerFrame ? CALLER_FRAME_CACHE : CACHE; | |
58 CiStackSlot[] slots = cache[kind.ordinal()]; | |
59 CiStackSlot slot; | |
60 if (index < slots.length) { | |
61 slot = slots[index]; | |
62 } else { | |
63 slot = new CiStackSlot(kind, inCallerFrame ? -(index + 1) : index); | |
64 } | |
65 assert slot.inCallerFrame() == inCallerFrame; | |
66 return slot; | |
67 } | |
68 | |
69 /** | |
70 * Private constructor to enforce use of {@link #get(CiKind, int)} so that the | |
71 * shared instance {@linkplain #CACHE cache} is used. | |
72 */ | |
73 private CiStackSlot(CiKind kind, int index) { | |
74 super(kind); | |
75 this.index = index; | |
76 } | |
77 | |
78 /** | |
79 * Gets the index of this stack slot. If this is a spill slot or outgoing stack argument to a call, | |
80 * then the index is relative to the current frame pointer. Otherwise this is an incoming stack | |
81 * argument and the index is relative to the caller frame pointer. | |
82 * | |
83 * @return the index of this slot | |
84 * @see #inCallerFrame() | |
85 */ | |
86 public int index() { | |
87 return index < 0 ? -(index + 1) : index; | |
88 } | |
89 | |
90 @Override | |
91 public int hashCode() { | |
92 return kind.ordinal() + index; | |
93 } | |
94 | |
95 @Override | |
96 public boolean equals(Object o) { | |
97 if (o == this) { | |
98 return true; | |
99 } | |
100 if (o instanceof CiStackSlot) { | |
101 CiStackSlot l = (CiStackSlot) o; | |
102 return l.kind == kind && l.index == index; | |
103 } | |
104 return false; | |
105 } | |
106 | |
107 @Override | |
108 public boolean equalsIgnoringKind(CiValue o) { | |
109 if (o == this) { | |
110 return true; | |
111 } | |
112 if (o instanceof CiStackSlot) { | |
113 CiStackSlot l = (CiStackSlot) o; | |
114 return l.index == index; | |
115 } | |
116 return false; | |
117 } | |
118 | |
119 @Override | |
120 public String name() { | |
121 return (inCallerFrame() ? "caller-stack" : "stack:") + index(); | |
122 } | |
123 | |
124 /** | |
125 * Determines if this is a stack slot in the caller's frame. | |
126 */ | |
127 public boolean inCallerFrame() { | |
128 return index < 0; | |
129 } | |
130 | |
131 /** | |
132 * Gets this stack slot used to pass an argument from the perspective of a caller. | |
133 */ | |
134 public CiStackSlot asOutArg() { | |
135 if (inCallerFrame()) { | |
136 return get(kind, index(), false); | |
137 } | |
138 return this; | |
139 } | |
140 | |
141 /** | |
142 * Gets this stack slot used to pass an argument from the perspective of a callee. | |
143 */ | |
144 public CiStackSlot asInArg() { | |
145 if (!inCallerFrame()) { | |
146 return get(kind, index(), true); | |
147 } | |
148 return this; | |
149 } | |
150 | |
151 /** | |
152 * Default size of the cache to generate per kind. | |
153 */ | |
154 private static final int CACHE_PER_KIND_SIZE = 100; | |
155 | |
156 private static final int CALLER_FRAME_CACHE_PER_KIND_SIZE = 10; | |
157 | |
158 /** | |
159 * A cache of {@linkplain #inCallerFrame() non-caller-frame} stack slots. | |
160 */ | |
161 private static final CiStackSlot[][] CACHE = makeCache(CACHE_PER_KIND_SIZE, false); | |
162 | |
163 /** | |
164 * A cache of {@linkplain #inCallerFrame() caller-frame} stack slots. | |
165 */ | |
166 private static final CiStackSlot[][] CALLER_FRAME_CACHE = makeCache(CALLER_FRAME_CACHE_PER_KIND_SIZE, true); | |
167 | |
168 private static CiStackSlot[][] makeCache(int cachePerKindSize, boolean inCallerFrame) { | |
169 CiStackSlot[][] cache = new CiStackSlot[CiKind.VALUES.length][]; | |
170 cache[CiKind.Illegal.ordinal()] = makeCacheForKind(CiKind.Illegal, cachePerKindSize, inCallerFrame); | |
171 cache[CiKind.Int.ordinal()] = makeCacheForKind(CiKind.Int, cachePerKindSize, inCallerFrame); | |
172 cache[CiKind.Long.ordinal()] = makeCacheForKind(CiKind.Long, cachePerKindSize, inCallerFrame); | |
173 cache[CiKind.Float.ordinal()] = makeCacheForKind(CiKind.Float, cachePerKindSize, inCallerFrame); | |
174 cache[CiKind.Double.ordinal()] = makeCacheForKind(CiKind.Double, cachePerKindSize, inCallerFrame); | |
175 cache[CiKind.Object.ordinal()] = makeCacheForKind(CiKind.Object, cachePerKindSize, inCallerFrame); | |
176 cache[CiKind.Jsr.ordinal()] = makeCacheForKind(CiKind.Jsr, cachePerKindSize, inCallerFrame); | |
177 return cache; | |
178 } | |
179 | |
180 /** | |
181 * Creates an array of {@code CiStackSlot} objects for a given {@link CiKind}. | |
182 * The {@link #index} values range from {@code 0} to {@code count - 1}. | |
183 * | |
184 * @param kind the {@code CiKind} of the stack slot | |
185 * @param count the size of the array to create | |
186 * @return the generated {@code CiStackSlot} array | |
187 */ | |
188 private static CiStackSlot[] makeCacheForKind(CiKind kind, int count, boolean inCallerFrame) { | |
189 CiStackSlot[] slots = new CiStackSlot[count]; | |
190 for (int i = 0; i < count; ++i) { | |
191 slots[i] = new CiStackSlot(kind, inCallerFrame ? -(i + 1) : i); | |
192 } | |
193 return slots; | |
194 } | |
195 } |