comparison c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java @ 1421:6223633ce7dd

changed VMExit/VMEntries to non-static, added eclipse c++ project, CIR interface changes
author Lukas Stadler <lukas.stadler@oracle.com>
date Fri, 23 Jul 2010 15:53:02 -0700
parents 44efca8a02d6
children 3483ec571caf
comparison
equal deleted inserted replaced
1420:44efca8a02d6 1421:6223633ce7dd
19 19
20 import java.lang.reflect.Modifier; 20 import java.lang.reflect.Modifier;
21 import java.util.ArrayList; 21 import java.util.ArrayList;
22 import java.util.List; 22 import java.util.List;
23 23
24 import com.sun.c1x.target.amd64.*;
24 import com.sun.cri.ci.CiKind; 25 import com.sun.cri.ci.CiKind;
25 import com.sun.cri.ri.RiField; 26 import com.sun.cri.ri.RiField;
26 import com.sun.cri.ri.RiMethod; 27 import com.sun.cri.ri.RiMethod;
27 import com.sun.cri.ri.RiRegisterConfig; 28 import com.sun.cri.ri.RiRegisterConfig;
28 import com.sun.cri.ri.RiType; 29 import com.sun.cri.ri.RiType;
29 import com.sun.cri.ri.RiType.Representation; 30 import com.sun.cri.ri.RiType.Representation;
30 import com.sun.cri.xir.CiXirAssembler; 31 import com.sun.cri.xir.*;
31 import com.sun.cri.xir.RiXirGenerator; 32 import com.sun.cri.xir.CiXirAssembler.*;
32 import com.sun.cri.xir.XirArgument;
33 import com.sun.cri.xir.XirSite;
34 import com.sun.cri.xir.XirSnippet;
35 import com.sun.cri.xir.XirTemplate;
36 import com.sun.cri.xir.CiXirAssembler.XirOperand;
37 33
38 /** 34 /**
39 * 35 *
40 * @author Thomas Wuerthinger 36 * @author Thomas Wuerthinger
41 * 37 *
42 */ 38 */
43 public class HotSpotXirGenerator extends RiXirGenerator { 39 public class HotSpotXirGenerator extends RiXirGenerator {
44 40
41 private final HotSpotVMConfig config;
42 private CiXirAssembler asm;
43 private final RiRegisterConfig registerConfig;
44
45 private XirTemplate[] emptyTemplates = new XirTemplate[CiKind.values().length]; 45 private XirTemplate[] emptyTemplates = new XirTemplate[CiKind.values().length];
46 private final HotSpotVMConfig config; 46 private XirTemplate prologueTemplate;
47 47 private XirTemplate staticPrologueTemplate;
48 public HotSpotXirGenerator(HotSpotVMConfig config) { 48 private XirTemplate epilogueTemplate;
49
50 static class XirPair {
51
52 final XirTemplate resolved;
53 final XirTemplate unresolved;
54
55 XirPair(XirTemplate resolved, XirTemplate unresolved) {
56 this.resolved = resolved;
57 this.unresolved = unresolved;
58 }
59 }
60
61 private XirPair[] putFieldTemplates;
62 private XirPair[] getFieldTemplates;
63 private XirPair[] putStaticFieldTemplates;
64 private XirPair[] getStaticFieldTemplates;
65 private XirPair instanceofTemplate;
66 private XirPair instanceofTemplateNonnull;
67
68 public HotSpotXirGenerator(HotSpotVMConfig config, RiRegisterConfig registerConfig) {
49 this.config = config; 69 this.config = config;
70 this.registerConfig = registerConfig;
50 } 71 }
51 72
52 @Override 73 @Override
53 public List<XirTemplate> buildTemplates(CiXirAssembler asm) { 74 public List<XirTemplate> buildTemplates(CiXirAssembler asm) {
75 this.asm = asm;
76
77 putFieldTemplates = new XirPair[CiKind.values().length];
78 getFieldTemplates = new XirPair[CiKind.values().length];
79 putStaticFieldTemplates = new XirPair[CiKind.values().length];
80 getStaticFieldTemplates = new XirPair[CiKind.values().length];
81
54 List<XirTemplate> templates = new ArrayList<XirTemplate>(); 82 List<XirTemplate> templates = new ArrayList<XirTemplate>();
55 for (int i = 0; i < CiKind.values().length; i++) { 83 for (int index = 0; index < CiKind.values().length; index++) {
56 84
57 CiKind curKind = CiKind.values()[i]; 85 CiKind kind = CiKind.values()[index];
58 86
59 if (curKind == CiKind.Float || curKind == CiKind.Double) 87 if (kind == CiKind.Float || kind == CiKind.Double)
60 continue; 88 continue;
61 89
62 if (CiKind.values()[i] == CiKind.Void) { 90 if (CiKind.values()[index] == CiKind.Void) {
63 asm.restart(CiKind.values()[i]); 91 asm.restart(CiKind.values()[index]);
64 emptyTemplates[i] = asm.finishTemplate("empty-" + CiKind.values()[i]); 92 emptyTemplates[index] = asm.finishTemplate("empty-" + CiKind.values()[index]);
65 } else { 93 } else {
66 asm.restart(); 94 asm.restart();
67 XirOperand result = asm.createTemp("result", CiKind.values()[i]); 95 XirOperand result = asm.createTemp("result", CiKind.values()[index]);
68 emptyTemplates[i] = asm.finishTemplate(result, "empty-" + CiKind.values()[i]); 96 emptyTemplates[index] = asm.finishTemplate(result, "empty-" + CiKind.values()[index]);
97
98 putFieldTemplates[index] = buildPutFieldTemplate(kind, kind == CiKind.Object, false);
99 getFieldTemplates[index] = buildGetFieldTemplate(kind, false);
100 putStaticFieldTemplates[index] = buildPutFieldTemplate(kind, kind == CiKind.Object, true);
101 getStaticFieldTemplates[index] = buildGetFieldTemplate(kind, true);
102 // arrayLoadTemplates[index] = buildArrayLoad(kind, asm, true);
103 // arrayStoreTemplates[index] = buildArrayStore(kind, asm, true, kind == CiKind.Object, kind == CiKind.Object);
104 // newArrayTemplates[index] = buildNewArray(kind);
69 } 105 }
70 templates.add(emptyTemplates[i]); 106 templates.add(emptyTemplates[index]);
71 } 107 }
108 prologueTemplate = buildPrologue(false);
109 staticPrologueTemplate = buildPrologue(true);
110 epilogueTemplate = buildEpilogue();
111 instanceofTemplate = buildInstanceof(false);
112 instanceofTemplateNonnull = buildInstanceof(true);
72 113
73 return templates; 114 return templates;
115 }
116
117 private XirTemplate buildPrologue(boolean staticMethod) {
118 asm.restart(CiKind.Void);
119 XirOperand sp = asm.createRegister("stack pointer", CiKind.Word, registerConfig.getStackPointerRegister());
120 XirOperand temp = asm.createRegister("temp (rax)", CiKind.Word, AMD64.rax);
121
122 asm.align(config.codeEntryAlignment);
123 asm.entrypoint(HotSpotRuntime.Entrypoints.UNVERIFIED);
124 if (!staticMethod) {
125 // TODO do some checking...
126 asm.add(temp, temp, asm.i(1));
127 asm.sub(temp, temp, asm.i(1));
128 asm.shouldNotReachHere();
129
130 asm.align(config.codeEntryAlignment);
131 }
132 asm.entrypoint(HotSpotRuntime.Entrypoints.VERIFIED);
133 // stack banging
134 asm.pload(CiKind.Word, temp, sp, asm.i(-config.stackShadowPages * config.vmPageSize), true);
135 asm.pushFrame();
136
137 return asm.finishTemplate(staticMethod ? "static prologue" : "prologue");
138 }
139
140 private XirTemplate buildEpilogue() {
141 asm.restart(CiKind.Void);
142 asm.popFrame();
143 // TODO safepoint check
144 return asm.finishTemplate("epilogue");
145 }
146
147 private XirPair buildGetFieldTemplate(CiKind kind, boolean isStatic) {
148 final XirTemplate resolved;
149 final XirTemplate unresolved;
150 {
151 // resolved case
152 XirOperand result = asm.restart(kind);
153 XirParameter object = asm.createInputParameter("object", CiKind.Object);
154 XirParameter fieldOffset = asm.createConstantInputParameter("fieldOffset", CiKind.Int);
155 asm.pload(kind, result, object, fieldOffset, true);
156 resolved = asm.finishTemplate("getfield<" + kind + ">");
157 }
158 if (isStatic) {
159 asm.restart(kind);
160 asm.shouldNotReachHere();
161 /*
162 * XirParameter object = asm.createInputParameter("object", CiKind.Object); XirParameter guard =
163 * asm.createInputParameter("guard", CiKind.Object); XirOperand fieldOffset = asm.createTemp("fieldOffset",
164 * CiKind.Int); if (isStatic) { callRuntimeThroughStub(asm, "resolveGetStatic", fieldOffset, guard); } else
165 * { callRuntimeThroughStub(asm, "resolveGetField", fieldOffset, guard); } asm.pload(kind, result, object,
166 * fieldOffset, true);
167 */
168
169 unresolved = asm.finishTemplate("getfield<" + kind + ">-unresolved");
170 } else {
171 unresolved = null;
172 }
173 return new XirPair(resolved, unresolved);
174 }
175
176 private XirPair buildPutFieldTemplate(CiKind kind, boolean genWriteBarrier, boolean isStatic) {
177 final XirTemplate resolved;
178 final XirTemplate unresolved;
179 {
180 // resolved case
181 asm.restart(CiKind.Void);
182 XirParameter object = asm.createInputParameter("object", CiKind.Object);
183 XirParameter value = asm.createInputParameter("value", kind);
184 XirParameter fieldOffset = asm.createConstantInputParameter("fieldOffset", CiKind.Int);
185 asm.pstore(kind, object, fieldOffset, value, true);
186 if (genWriteBarrier) {
187 // TODO write barrier
188 // addWriteBarrier(asm, object, value);
189 }
190 resolved = asm.finishTemplate("putfield<" + kind + ", " + genWriteBarrier + ">");
191 }
192 if (isStatic) {
193 // unresolved case
194 asm.restart(CiKind.Void);
195 asm.shouldNotReachHere();
196 /*
197 * XirParameter object = asm.createInputParameter("object", CiKind.Object); XirParameter value =
198 * asm.createInputParameter("value", kind); XirParameter guard = asm.createInputParameter("guard",
199 * CiKind.Object); XirOperand fieldOffset = asm.createTemp("fieldOffset", CiKind.Int); if (isStatic) {
200 * callRuntimeThroughStub(asm, "resolvePutStatic", fieldOffset, guard); } else { callRuntimeThroughStub(asm,
201 * "resolvePutField", fieldOffset, guard); } asm.pstore(kind, object, fieldOffset, value, true); if
202 * (genWriteBarrier) { addWriteBarrier(asm, object, value); }
203 */
204 unresolved = asm.finishTemplate("putfield<" + kind + ", " + genWriteBarrier + ">-unresolved");
205 } else {
206 unresolved = null;
207 }
208 return new XirPair(resolved, unresolved);
209 }
210
211 private XirPair buildInstanceof(boolean nonnull) {
212 XirTemplate resolved;
213 XirTemplate unresolved;
214 {
215 XirOperand result = asm.restart(CiKind.Boolean);
216 asm.callRuntime(config.instanceofStub, result);
217
218 XirParameter object = asm.createInputParameter("object", CiKind.Object);
219 XirParameter hub = asm.createConstantInputParameter("hub", CiKind.Object);
220 XirOperand temp = asm.createTemp("temp", CiKind.Object);
221 XirLabel pass = asm.createInlineLabel("pass");
222 XirLabel fail = asm.createInlineLabel("fail");
223 asm.mov(result, asm.b(false));
224 if (!nonnull) {
225 // first check for null
226 asm.jeq(fail, object, asm.o(null));
227 }
228 asm.pload(CiKind.Object, temp, object, asm.i(config.hubOffset), !nonnull);
229 asm.jneq(fail, temp, hub);
230 asm.bindInline(pass);
231 asm.mov(result, asm.b(true));
232 asm.bindInline(fail);
233 resolved = asm.finishTemplate("instanceof-leaf<" + nonnull + ">");
234 }
235 {/*
236 * // unresolved instanceof unresolved = buildUnresolvedInstanceOf(nonnull);
237 */
238 asm.restart(CiKind.Boolean);
239 asm.shouldNotReachHere();
240 unresolved = asm.finishTemplate("instanceof-leaf<" + nonnull + ">");
241 }
242 return new XirPair(resolved, unresolved);
74 } 243 }
75 244
76 @Override 245 @Override
77 public XirSnippet genArrayLength(XirSite site, XirArgument array) { 246 public XirSnippet genArrayLength(XirSite site, XirArgument array) {
78 return new XirSnippet(emptyTemplates[CiKind.Int.ordinal()]); 247 return new XirSnippet(emptyTemplates[CiKind.Int.ordinal()]);
92 public XirSnippet genCheckCast(XirSite site, XirArgument receiver, XirArgument hub, RiType type) { 261 public XirSnippet genCheckCast(XirSite site, XirArgument receiver, XirArgument hub, RiType type) {
93 return new XirSnippet(emptyTemplates[CiKind.Object.ordinal()]); 262 return new XirSnippet(emptyTemplates[CiKind.Object.ordinal()]);
94 } 263 }
95 264
96 @Override 265 @Override
97 public XirSnippet genEntrypoint(XirSite site) { 266 public XirSnippet genPrologue(XirSite site, RiMethod method) {
98 return new XirSnippet(emptyTemplates[CiKind.Void.ordinal()]); 267 boolean staticMethod = Modifier.isStatic(method.accessFlags());
268 return new XirSnippet(staticMethod ? staticPrologueTemplate : prologueTemplate);
269 }
270
271 @Override
272 public XirSnippet genEpilogue(XirSite site, RiMethod method) {
273 return new XirSnippet(epilogueTemplate);
99 } 274 }
100 275
101 @Override 276 @Override
102 public XirSnippet genGetField(XirSite site, XirArgument receiver, RiField field) { 277 public XirSnippet genGetField(XirSite site, XirArgument receiver, RiField field) {
103 return new XirSnippet(emptyTemplates[field.kind().ordinal()]); 278 XirPair pair = getStaticFieldTemplates[field.kind().ordinal()];
279 assert field.isResolved() : "getfield doesn't expect unresolved fields";
280 XirArgument offset = XirArgument.forInt(((HotSpotField) field).offset());
281 return new XirSnippet(pair.resolved, receiver, offset);
104 } 282 }
105 283
106 @Override 284 @Override
107 public XirSnippet genGetStatic(XirSite site, XirArgument staticTuple, RiField field) { 285 public XirSnippet genGetStatic(XirSite site, XirArgument staticTuple, RiField field) {
108 return new XirSnippet(emptyTemplates[field.kind().ordinal()]); 286 XirPair pair = getStaticFieldTemplates[field.kind().ordinal()];
287 if (field.isResolved()) {
288 XirArgument offset = XirArgument.forInt(((HotSpotField) field).offset());
289 return new XirSnippet(pair.resolved, staticTuple, offset);
290 }
291 return new XirSnippet(pair.unresolved, staticTuple, null);
292 }
293
294 @Override
295 public XirSnippet genPutField(XirSite site, XirArgument receiver, RiField field, XirArgument value) {
296 XirPair pair = putFieldTemplates[field.kind().ordinal()];
297 assert field.isResolved() : "putfield doesn't expect unresolved fields";
298 XirArgument offset = XirArgument.forInt(((HotSpotField) field).offset());
299 return new XirSnippet(pair.resolved, receiver, value, offset);
300 }
301
302 @Override
303 public XirSnippet genPutStatic(XirSite site, XirArgument staticTuple, RiField field, XirArgument value) {
304 XirPair pair = putFieldTemplates[field.kind().ordinal()];
305 if (field.isResolved()) {
306 XirArgument offset = XirArgument.forInt(((HotSpotField) field).offset());
307 return new XirSnippet(pair.resolved, staticTuple, value, offset);
308 }
309 return new XirSnippet(pair.unresolved, staticTuple, value);
109 } 310 }
110 311
111 @Override 312 @Override
112 public XirSnippet genInstanceOf(XirSite site, XirArgument receiver, XirArgument hub, RiType type) { 313 public XirSnippet genInstanceOf(XirSite site, XirArgument receiver, XirArgument hub, RiType type) {
314 /*
315 if (type.isResolved()) {
316 return new XirSnippet(instanceofTemplate.resolved, receiver, hub);
317 }
318 // XirArgument guard = guardFor(type, ResolveClass.SNIPPET);
319 return new XirSnippet(instanceofTemplate.unresolved, receiver);
320 */
113 return new XirSnippet(emptyTemplates[CiKind.Boolean.ordinal()]); 321 return new XirSnippet(emptyTemplates[CiKind.Boolean.ordinal()]);
114 } 322 }
115 323
116 @Override 324 @Override
117 public XirSnippet genIntrinsic(XirSite site, XirArgument[] arguments, RiMethod method) { 325 public XirSnippet genIntrinsic(XirSite site, XirArgument[] arguments, RiMethod method) {
162 public XirSnippet genNewMultiArray(XirSite site, XirArgument[] lengths, RiType type) { 370 public XirSnippet genNewMultiArray(XirSite site, XirArgument[] lengths, RiType type) {
163 return new XirSnippet(emptyTemplates[CiKind.Object.ordinal()]); 371 return new XirSnippet(emptyTemplates[CiKind.Object.ordinal()]);
164 } 372 }
165 373
166 @Override 374 @Override
167 public XirSnippet genPutField(XirSite site, XirArgument receiver, RiField field, XirArgument value) {
168 return new XirSnippet(emptyTemplates[CiKind.Void.ordinal()]);
169 }
170
171 @Override
172 public XirSnippet genPutStatic(XirSite site, XirArgument staticTuple, RiField field, XirArgument value) {
173 return new XirSnippet(emptyTemplates[CiKind.Void.ordinal()]);
174 }
175
176 @Override
177 public XirSnippet genResolveClass(XirSite site, RiType type, Representation representation) { 375 public XirSnippet genResolveClass(XirSite site, RiType type, Representation representation) {
178 return new XirSnippet(emptyTemplates[CiKind.Object.ordinal()]); 376 System.out.println("genResolveClass " + type + ", " + representation);
377 XirOperand result = asm.restart(CiKind.Object);
378 if (type.isResolved()) {
379 System.out.println("resolved");
380 asm.mov(result, asm.o(type));
381 return new XirSnippet(asm.finishTemplate(result, "resolve class"));
382 }
383 asm.shouldNotReachHere();
384 return new XirSnippet(asm.finishTemplate(result, "resolve class"));
385
179 } 386 }
180 387
181 @Override 388 @Override
182 public XirSnippet genSafepoint(XirSite site) { 389 public XirSnippet genSafepoint(XirSite site) {
183 return new XirSnippet(emptyTemplates[CiKind.Void.ordinal()]); 390 return new XirSnippet(emptyTemplates[CiKind.Void.ordinal()]);