Mercurial > hg > graal-compiler
comparison graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiStackSlot.java @ 4199:aaac4894175c
Renamed cri packages from sun to oracle.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Tue, 03 Jan 2012 16:29:28 +0100 |
parents | graal/com.oracle.max.cri/src/com/sun/cri/ci/CiStackSlot.java@de7b3e7ae528 |
children | a051fafaa4a9 |
comparison
equal
deleted
inserted
replaced
4198:8c9c0e1eaab1 | 4199:aaac4894175c |
---|---|
1 /* | |
2 * Copyright (c) 2010, 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 */ | |
23 package com.oracle.max.cri.ci; | |
24 | |
25 import static com.oracle.max.cri.ci.CiKind.*; | |
26 | |
27 /** | |
28 * Represents a compiler spill slot or an outgoing stack-based argument in a method's frame | |
29 * or an incoming stack-based argument in a method's {@linkplain #inCallerFrame() caller's frame}. | |
30 */ | |
31 public final class CiStackSlot extends CiValue { | |
32 private static final long serialVersionUID = -7725071921307318433L; | |
33 | |
34 private final int offset; | |
35 private final boolean addFrameSize; | |
36 | |
37 /** | |
38 * Gets a {@link CiStackSlot} instance representing a stack slot at a given index | |
39 * holding a value of a given kind. | |
40 * | |
41 * @param kind The kind of the value stored in the stack slot. | |
42 * @param offset The offset of the stack slot (in bytes) | |
43 * @param inCallerFrame Specifies if the offset is relative to the stack pointer, | |
44 * or the beginning of the frame (stack pointer + total frame size). | |
45 */ | |
46 public static CiStackSlot get(CiKind kind, int offset, boolean addFrameSize) { | |
47 assert kind.stackKind() == kind; | |
48 assert addFrameSize || offset >= 0; | |
49 | |
50 if (offset % CACHE_GRANULARITY == 0) { | |
51 CiStackSlot[][] cache; | |
52 int index = offset / CACHE_GRANULARITY; | |
53 if (!addFrameSize) { | |
54 cache = OUT_CACHE; | |
55 } else if (offset >= 0) { | |
56 cache = IN_CACHE; | |
57 } else { | |
58 cache = SPILL_CACHE; | |
59 index = -index; | |
60 } | |
61 CiStackSlot[] slots = cache[kind.ordinal()]; | |
62 if (index < slots.length) { | |
63 CiStackSlot slot = slots[index]; | |
64 assert slot.kind == kind && slot.offset == offset && slot.addFrameSize == addFrameSize; | |
65 return slot; | |
66 } | |
67 } | |
68 return new CiStackSlot(kind, offset, addFrameSize); | |
69 } | |
70 | |
71 /** | |
72 * Private constructor to enforce use of {@link #get()} so that a cache can be used. | |
73 */ | |
74 private CiStackSlot(CiKind kind, int offset, boolean addFrameSize) { | |
75 super(kind); | |
76 this.offset = offset; | |
77 this.addFrameSize = addFrameSize; | |
78 } | |
79 | |
80 /** | |
81 * Gets the offset of this stack slot, relative to the stack pointer. | |
82 * @return The offset of this slot (in bytes). | |
83 */ | |
84 public int offset(int totalFrameSize) { | |
85 assert totalFrameSize > 0 || !addFrameSize; | |
86 int result = offset + (addFrameSize ? totalFrameSize : 0); | |
87 assert result >= 0; | |
88 return result; | |
89 } | |
90 | |
91 public boolean inCallerFrame() { | |
92 return addFrameSize && offset >= 0; | |
93 } | |
94 | |
95 public int rawOffset() { | |
96 return offset; | |
97 } | |
98 | |
99 public boolean rawAddFrameSize() { | |
100 return addFrameSize; | |
101 } | |
102 | |
103 @Override | |
104 public int hashCode() { | |
105 return kind.ordinal() ^ (offset << 4) ^ (addFrameSize ? 15 : 0); | |
106 } | |
107 | |
108 @Override | |
109 public boolean equals(Object o) { | |
110 if (o == this) { | |
111 return true; | |
112 } | |
113 if (o instanceof CiStackSlot) { | |
114 CiStackSlot l = (CiStackSlot) o; | |
115 return l.kind == kind && l.offset == offset && l.addFrameSize == addFrameSize; | |
116 } | |
117 return false; | |
118 } | |
119 | |
120 @Override | |
121 public String toString() { | |
122 String s; | |
123 if (!addFrameSize) { | |
124 s = "out:"; | |
125 } else if (offset >= 0) { | |
126 s = "in:"; | |
127 } else { | |
128 s = "spill:"; | |
129 } | |
130 return s + offset + kindSuffix(); | |
131 } | |
132 | |
133 /** | |
134 * Gets this stack slot used to pass an argument from the perspective of a caller. | |
135 */ | |
136 public CiStackSlot asOutArg() { | |
137 assert offset >= 0; | |
138 if (addFrameSize) { | |
139 return get(kind, offset, false); | |
140 } | |
141 return this; | |
142 } | |
143 | |
144 /** | |
145 * Gets this stack slot used to pass an argument from the perspective of a callee. | |
146 */ | |
147 public CiStackSlot asInArg() { | |
148 assert offset >= 0; | |
149 if (!addFrameSize) { | |
150 return get(kind, offset, true); | |
151 } | |
152 return this; | |
153 } | |
154 | |
155 | |
156 private static final int CACHE_GRANULARITY = 8; | |
157 private static final int SPILL_CACHE_PER_KIND_SIZE = 100; | |
158 private static final int PARAM_CACHE_PER_KIND_SIZE = 10; | |
159 | |
160 private static final CiStackSlot[][] SPILL_CACHE = makeCache(SPILL_CACHE_PER_KIND_SIZE, -1, true); | |
161 private static final CiStackSlot[][] IN_CACHE = makeCache(PARAM_CACHE_PER_KIND_SIZE, 1, true); | |
162 private static final CiStackSlot[][] OUT_CACHE = makeCache(PARAM_CACHE_PER_KIND_SIZE, 1, false); | |
163 | |
164 private static CiStackSlot[][] makeCache(int cachePerKindSize, int sign, boolean addFrameSize) { | |
165 CiStackSlot[][] cache = new CiStackSlot[CiKind.VALUES.length][]; | |
166 for (CiKind kind : new CiKind[] {Illegal, Int, Long, Float, Double, Object, Jsr}) { | |
167 CiStackSlot[] slots = new CiStackSlot[cachePerKindSize]; | |
168 for (int i = 0; i < cachePerKindSize; i++) { | |
169 slots[i] = new CiStackSlot(kind, sign * i * CACHE_GRANULARITY, addFrameSize); | |
170 } | |
171 cache[kind.ordinal()] = slots; | |
172 } | |
173 return cache; | |
174 } | |
175 } |