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 }