Mercurial > hg > truffle
comparison c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java @ 1434:72cfb36c6bb2
* enabled all jtt tests
* added proxy that counts jni calls
* honor hotspot stackshadowpages
* constant pool caching
* monitor enter/exit
* arithmetic stubs (frem, drem, ...)
* create stack values for debug info
* some doc
author | Lukas Stadler <lukas.stadler@oracle.com> |
---|---|
date | Thu, 30 Sep 2010 17:19:48 -0700 |
parents | efba53f86c4f |
children | 9e5e83ca2259 |
comparison
equal
deleted
inserted
replaced
1433:efba53f86c4f | 1434:72cfb36c6bb2 |
---|---|
69 this.config = config; | 69 this.config = config; |
70 this.target = target; | 70 this.target = target; |
71 this.registerConfig = registerConfig; | 71 this.registerConfig = registerConfig; |
72 } | 72 } |
73 | 73 |
74 private SimpleTemplates prologueTemplates = new SimpleTemplates(STATIC_METHOD, SYNCHRONIZED) { | 74 private SimpleTemplates prologueTemplates = new SimpleTemplates(STATIC_METHOD) { |
75 | 75 |
76 @Override | 76 @Override |
77 protected XirTemplate create(CiXirAssembler asm, long flags) { | 77 protected XirTemplate create(CiXirAssembler asm, long flags) { |
78 asm.restart(CiKind.Void); | 78 asm.restart(CiKind.Void); |
79 XirOperand framePointer = asm.createRegister("frame pointer", CiKind.Word, AMD64.rbp); | 79 XirOperand framePointer = asm.createRegister("frame pointer", CiKind.Word, AMD64.rbp); |
94 asm.pload(CiKind.Word, temp, receiver, asm.i(config.hubOffset), false); | 94 asm.pload(CiKind.Word, temp, receiver, asm.i(config.hubOffset), false); |
95 asm.jneq(unverifiedStub, cache, temp); | 95 asm.jneq(unverifiedStub, cache, temp); |
96 } | 96 } |
97 asm.align(config.codeEntryAlignment); | 97 asm.align(config.codeEntryAlignment); |
98 asm.mark(MARK_VERIFIED_ENTRY); | 98 asm.mark(MARK_VERIFIED_ENTRY); |
99 asm.stackOverflowCheck(); | |
99 asm.push(framePointer); | 100 asm.push(framePointer); |
100 asm.mov(framePointer, stackPointer); | 101 asm.mov(framePointer, stackPointer); |
101 asm.pushFrame(); | 102 asm.pushFrame(); |
102 | |
103 if (is(SYNCHRONIZED, flags)) { | |
104 // TODO synchronized methods / monitors | |
105 } | |
106 | 103 |
107 // -- out of line ------------------------------------------------------- | 104 // -- out of line ------------------------------------------------------- |
108 XirOperand thread = asm.createRegister("thread", CiKind.Word, AMD64.r15); | 105 XirOperand thread = asm.createRegister("thread", CiKind.Word, AMD64.r15); |
109 XirOperand exceptionOop = asm.createTemp("exception oop", CiKind.Object); | 106 XirOperand exceptionOop = asm.createTemp("exception oop", CiKind.Object); |
110 XirLabel unwind = asm.createOutOfLineLabel("unwind"); | 107 XirLabel unwind = asm.createOutOfLineLabel("unwind"); |
137 @Override | 134 @Override |
138 protected XirTemplate create(CiXirAssembler asm, long flags) { | 135 protected XirTemplate create(CiXirAssembler asm, long flags) { |
139 asm.restart(CiKind.Void); | 136 asm.restart(CiKind.Void); |
140 XirOperand framePointer = asm.createRegister("frame pointer", CiKind.Word, AMD64.rbp); | 137 XirOperand framePointer = asm.createRegister("frame pointer", CiKind.Word, AMD64.rbp); |
141 | 138 |
142 if (is(SYNCHRONIZED, flags)) { | |
143 // TODO synchronized methods / monitors | |
144 } | |
145 | |
146 asm.popFrame(); | 139 asm.popFrame(); |
147 asm.pop(framePointer); | 140 asm.pop(framePointer); |
148 | 141 |
149 // TODO safepoint check | 142 // TODO safepoint check |
150 | 143 |
156 | 149 |
157 @Override | 150 @Override |
158 protected XirTemplate create(CiXirAssembler asm, long flags) { | 151 protected XirTemplate create(CiXirAssembler asm, long flags) { |
159 asm.restart(CiKind.Void); | 152 asm.restart(CiKind.Void); |
160 | 153 |
161 // TODO safepoint | 154 // XirOperand temp = asm.createRegister("temp", CiKind.Word, AMD64.rax); |
155 // asm.pload(CiKind.Word, temp, asm.w(config.safepointPollingAddress), true); | |
156 | |
162 return asm.finishTemplate("safepoint"); | 157 return asm.finishTemplate("safepoint"); |
163 } | 158 } |
164 }; | 159 }; |
165 | 160 |
166 private SimpleTemplates exceptionObjectTemplates = new SimpleTemplates() { | 161 private SimpleTemplates exceptionObjectTemplates = new SimpleTemplates() { |
295 | 290 |
296 @Override | 291 @Override |
297 protected XirTemplate create(CiXirAssembler asm, long flags) { | 292 protected XirTemplate create(CiXirAssembler asm, long flags) { |
298 asm.restart(CiKind.Void); | 293 asm.restart(CiKind.Void); |
299 XirParameter object = asm.createInputParameter("object", CiKind.Object); | 294 XirParameter object = asm.createInputParameter("object", CiKind.Object); |
300 XirOperand temp = asm.createRegister("temp", CiKind.Word, AMD64.rax); | 295 XirParameter lock = asm.createInputParameter("lock", CiKind.Word); |
301 | 296 |
302 if (is(NULL_CHECK, flags)) { | 297 if (is(NULL_CHECK, flags)) { |
303 asm.nop(1); | 298 asm.nop(1); |
304 asm.mark(MARK_IMPLICIT_NULL); | 299 asm.mark(MARK_IMPLICIT_NULL); |
305 asm.pload(CiKind.Word, temp, object, true); | 300 asm.pload(CiKind.Word, asm.createTemp("temp", CiKind.Word), object, true); |
306 } | 301 } |
307 | 302 /* |
303 useRegisters(asm, AMD64.rbx, AMD64.rsi, AMD64.rdx); | |
304 useRegisters(asm, AMD64.rax); | |
305 asm.callRuntime(config.monitorEnterStub, null, object, lock); | |
306 */ | |
308 return asm.finishTemplate("monitorEnter"); | 307 return asm.finishTemplate("monitorEnter"); |
309 } | 308 } |
310 }; | 309 }; |
311 | 310 |
312 private SimpleTemplates monitorExitTemplates = new SimpleTemplates(NULL_CHECK) { | 311 private SimpleTemplates monitorExitTemplates = new SimpleTemplates(NULL_CHECK) { |
313 | 312 |
314 @Override | 313 @Override |
315 protected XirTemplate create(CiXirAssembler asm, long flags) { | 314 protected XirTemplate create(CiXirAssembler asm, long flags) { |
316 asm.restart(CiKind.Void); | 315 asm.restart(CiKind.Void); |
317 XirParameter object = asm.createInputParameter("object", CiKind.Object); | 316 XirParameter object = asm.createInputParameter("object", CiKind.Object); |
318 XirOperand temp = asm.createRegister("temp", CiKind.Word, AMD64.rax); | 317 XirParameter lock = asm.createInputParameter("lock", CiKind.Word); |
319 | 318 /* |
320 if (is(NULL_CHECK, flags)) { | 319 useRegisters(asm, AMD64.rbx, AMD64.rsi, AMD64.rdx); |
321 asm.nop(1); | 320 useRegisters(asm, AMD64.rax); |
322 asm.mark(MARK_IMPLICIT_NULL); | 321 asm.callRuntime(config.monitorExitStub, null, object, lock); |
323 asm.pload(CiKind.Word, temp, object, true); | 322 */ |
324 } | |
325 | |
326 return asm.finishTemplate("monitorExit"); | 323 return asm.finishTemplate("monitorExit"); |
327 } | 324 } |
328 }; | 325 }; |
329 | 326 |
330 private KindTemplates getFieldTemplates = new KindTemplates(NULL_CHECK, UNRESOLVED) { | 327 private KindTemplates getFieldTemplates = new KindTemplates(NULL_CHECK, UNRESOLVED) { |
358 asm.restart(CiKind.Void); | 355 asm.restart(CiKind.Void); |
359 XirParameter object = asm.createInputParameter("object", CiKind.Object); | 356 XirParameter object = asm.createInputParameter("object", CiKind.Object); |
360 XirParameter value = asm.createInputParameter("value", kind); | 357 XirParameter value = asm.createInputParameter("value", kind); |
361 | 358 |
362 if (is(UNRESOLVED, flags)) { | 359 if (is(UNRESOLVED, flags)) { |
363 UnresolvedFieldPatching fieldPatching = new UnresolvedFieldPatching(asm, object, value, false, is(NULL_CHECK, flags), config); | 360 UnresolvedFieldPatching fieldPatching = new UnresolvedFieldPatching(asm, object, value, true, is(NULL_CHECK, flags), config); |
364 fieldPatching.emitInline(); | 361 fieldPatching.emitInline(); |
365 // -- out of line ------------------------------------------------------- | 362 // -- out of line ------------------------------------------------------- |
366 fieldPatching.emitOutOfLine(); | 363 fieldPatching.emitOutOfLine(); |
367 return asm.finishTemplate("putfield<" + kind + ">"); | 364 return asm.finishTemplate("putfield<" + kind + ">"); |
368 } | 365 } |
387 XirOperand type = asm.createInputParameter("type", CiKind.Object); | 384 XirOperand type = asm.createInputParameter("type", CiKind.Object); |
388 | 385 |
389 XirOperand thread = asm.createRegister("thread", CiKind.Word, AMD64.r15); | 386 XirOperand thread = asm.createRegister("thread", CiKind.Word, AMD64.r15); |
390 XirOperand temp1 = asm.createRegister("temp1", CiKind.Word, AMD64.rcx); | 387 XirOperand temp1 = asm.createRegister("temp1", CiKind.Word, AMD64.rcx); |
391 XirOperand temp2 = asm.createRegister("temp2", CiKind.Word, AMD64.rbx); | 388 XirOperand temp2 = asm.createRegister("temp2", CiKind.Word, AMD64.rbx); |
392 XirOperand temp2i = asm.createRegister("temp2i", CiKind.Word, AMD64.rbx); | 389 XirOperand temp2i = asm.createRegister("temp2i", CiKind.Int, AMD64.rbx); |
393 useRegisters(asm, AMD64.rsi); | 390 useRegisters(asm, AMD64.rsi); |
394 XirLabel tlabFull = asm.createOutOfLineLabel("tlab full"); | 391 XirLabel tlabFull = asm.createOutOfLineLabel("tlab full"); |
395 XirLabel resume = asm.createInlineLabel("resume"); | 392 XirLabel resume = asm.createInlineLabel("resume"); |
396 | 393 |
397 // check if the class is already initialized | 394 // check if the class is already initialized |
419 | 416 |
420 // -- out of line ------------------------------------------------------- | 417 // -- out of line ------------------------------------------------------- |
421 asm.bindOutOfLine(tlabFull); | 418 asm.bindOutOfLine(tlabFull); |
422 XirOperand arg = asm.createRegister("runtime call argument", CiKind.Object, AMD64.rdx); | 419 XirOperand arg = asm.createRegister("runtime call argument", CiKind.Object, AMD64.rdx); |
423 asm.mov(arg, type); | 420 asm.mov(arg, type); |
421 useRegisters(asm, AMD64.rax); | |
424 asm.callRuntime(config.newInstanceStub, result); | 422 asm.callRuntime(config.newInstanceStub, result); |
425 asm.jmp(resume); | 423 asm.jmp(resume); |
426 | 424 |
427 return asm.finishTemplate("new instance"); | 425 return asm.finishTemplate("new instance"); |
428 } | 426 } |
437 | 435 |
438 UnresolvedClassPatching patching = new UnresolvedClassPatching(asm, arg, config); | 436 UnresolvedClassPatching patching = new UnresolvedClassPatching(asm, arg, config); |
439 | 437 |
440 patching.emitInline(); | 438 patching.emitInline(); |
441 useRegisters(asm, AMD64.rbx, AMD64.rcx, AMD64.rsi); | 439 useRegisters(asm, AMD64.rbx, AMD64.rcx, AMD64.rsi); |
440 useRegisters(asm, AMD64.rax); | |
442 asm.callRuntime(config.unresolvedNewInstanceStub, result); | 441 asm.callRuntime(config.unresolvedNewInstanceStub, result); |
443 | 442 |
444 // -- out of line ------------------------------------------------------- | 443 // -- out of line ------------------------------------------------------- |
445 patching.emitOutOfLine(); | 444 patching.emitOutOfLine(); |
446 | 445 |
467 } else { | 466 } else { |
468 asm.mov(hub, asm.createConstantInputParameter("hub", CiKind.Object)); | 467 asm.mov(hub, asm.createConstantInputParameter("hub", CiKind.Object)); |
469 } | 468 } |
470 | 469 |
471 asm.mov(length, lengthParam); | 470 asm.mov(length, lengthParam); |
472 useRegisters(asm, AMD64.rax, AMD64.rsi, AMD64.rcx, AMD64.rdi); | 471 useRegisters(asm, AMD64.rsi, AMD64.rcx, AMD64.rdi); |
472 useRegisters(asm, AMD64.rax); | |
473 asm.callRuntime(config.newObjectArrayStub, result); | 473 asm.callRuntime(config.newObjectArrayStub, result); |
474 if (is(UNRESOLVED, flags)) { | 474 if (is(UNRESOLVED, flags)) { |
475 patching.emitOutOfLine(); | 475 patching.emitOutOfLine(); |
476 } | 476 } |
477 return asm.finishTemplate(is(UNRESOLVED, flags) ? "newObjectArray (unresolved)" : "newObjectArray"); | 477 return asm.finishTemplate(is(UNRESOLVED, flags) ? "newObjectArray (unresolved)" : "newObjectArray"); |
490 XirOperand length = asm.createRegister("length", CiKind.Int, AMD64.rbx); | 490 XirOperand length = asm.createRegister("length", CiKind.Int, AMD64.rbx); |
491 XirOperand hub = asm.createRegister("hub", CiKind.Object, AMD64.rdx); | 491 XirOperand hub = asm.createRegister("hub", CiKind.Object, AMD64.rdx); |
492 | 492 |
493 asm.mov(hub, hubParam); | 493 asm.mov(hub, hubParam); |
494 asm.mov(length, lengthParam); | 494 asm.mov(length, lengthParam); |
495 useRegisters(asm, AMD64.rax, AMD64.rsi, AMD64.rcx, AMD64.rdi); | 495 useRegisters(asm, AMD64.rsi, AMD64.rcx, AMD64.rdi); |
496 useRegisters(asm, AMD64.rax); | |
496 asm.callRuntime(config.newTypeArrayStub, result); | 497 asm.callRuntime(config.newTypeArrayStub, result); |
497 | 498 |
498 return asm.finishTemplate("newTypeArray"); | 499 return asm.finishTemplate("newTypeArray"); |
499 } | 500 } |
500 }; | 501 }; |
523 } else { | 524 } else { |
524 asm.mov(hub, asm.createConstantInputParameter("hub", CiKind.Object)); | 525 asm.mov(hub, asm.createConstantInputParameter("hub", CiKind.Object)); |
525 } | 526 } |
526 | 527 |
527 asm.mov(rank, asm.i(dimensions)); | 528 asm.mov(rank, asm.i(dimensions)); |
529 useRegisters(asm, AMD64.rax); | |
528 asm.callRuntime(config.newMultiArrayStub, result); | 530 asm.callRuntime(config.newMultiArrayStub, result); |
529 if (is(UNRESOLVED, flags)) { | 531 if (is(UNRESOLVED, flags)) { |
530 patching.emitOutOfLine(); | 532 patching.emitOutOfLine(); |
531 } | 533 } |
532 return asm.finishTemplate(is(UNRESOLVED, flags) ? "multiNewArray" + dimensions + " (unresolved)" : "multiNewArray" + dimensions); | 534 return asm.finishTemplate(is(UNRESOLVED, flags) ? "multiNewArray" + dimensions + " (unresolved)" : "multiNewArray" + dimensions); |
789 public XirSnippet genExceptionObject(XirSite site) { | 791 public XirSnippet genExceptionObject(XirSite site) { |
790 return new XirSnippet(exceptionObjectTemplates.get(site)); | 792 return new XirSnippet(exceptionObjectTemplates.get(site)); |
791 } | 793 } |
792 | 794 |
793 @Override | 795 @Override |
794 public XirSnippet genResolveClass(XirSite site, RiType type, Representation representation) { | 796 public XirSnippet genResolveClass(XirSite site, RiType type, Representation rep) { |
795 assert representation == Representation.ObjectHub : "unexpected representation: " + representation; | 797 assert rep == Representation.ObjectHub || rep == Representation.StaticFields : "unexpected representation: " + rep; |
796 if (type instanceof HotSpotTypeResolved) { | 798 if (type instanceof HotSpotTypeResolved) { |
797 return new XirSnippet(resolveClassTemplates.get(site), XirArgument.forObject(type)); | 799 return new XirSnippet(resolveClassTemplates.get(site), XirArgument.forObject(type)); |
798 } | 800 } |
799 return new XirSnippet(resolveClassTemplates.get(site, UNRESOLVED)); | 801 return new XirSnippet(resolveClassTemplates.get(site, UNRESOLVED)); |
800 } | 802 } |
823 public XirSnippet genInvokeStatic(XirSite site, RiMethod method) { | 825 public XirSnippet genInvokeStatic(XirSite site, RiMethod method) { |
824 return new XirSnippet(invokeStaticTemplates.get(site), XirArgument.forWord(0)); | 826 return new XirSnippet(invokeStaticTemplates.get(site), XirArgument.forWord(0)); |
825 } | 827 } |
826 | 828 |
827 @Override | 829 @Override |
828 public XirSnippet genMonitorEnter(XirSite site, XirArgument receiver) { | 830 public XirSnippet genMonitorEnter(XirSite site, XirArgument receiver, XirArgument lockAddress) { |
829 return new XirSnippet(monitorEnterTemplates.get(site), receiver); | 831 return new XirSnippet(monitorEnterTemplates.get(site), receiver, lockAddress); |
830 } | 832 } |
831 | 833 |
832 @Override | 834 @Override |
833 public XirSnippet genMonitorExit(XirSite site, XirArgument receiver) { | 835 public XirSnippet genMonitorExit(XirSite site, XirArgument receiver, XirArgument lockAddress) { |
834 return new XirSnippet(monitorExitTemplates.get(site), receiver); | 836 return new XirSnippet(monitorExitTemplates.get(site), receiver, lockAddress); |
835 } | 837 } |
836 | 838 |
837 @Override | 839 @Override |
838 public XirSnippet genGetField(XirSite site, XirArgument object, RiField field) { | 840 public XirSnippet genGetField(XirSite site, XirArgument object, RiField field) { |
839 if (field.isResolved()) { | 841 if (field.isResolved()) { |
1036 } | 1038 } |
1037 asm.bindInline(patchSite); | 1039 asm.bindInline(patchSite); |
1038 asm.mark(MARK_DUMMY_OOP_RELOCATION); | 1040 asm.mark(MARK_DUMMY_OOP_RELOCATION); |
1039 if (nullCheck) { | 1041 if (nullCheck) { |
1040 asm.mark(MARK_IMPLICIT_NULL); | 1042 asm.mark(MARK_IMPLICIT_NULL); |
1043 asm.safepoint(); | |
1041 } | 1044 } |
1042 asm.jmp(patchStub); | 1045 asm.jmp(patchStub); |
1043 | 1046 |
1044 // TODO: make this more generic & safe - this is needed to create space for patching | 1047 // TODO: make this more generic & safe - this is needed to create space for patching |
1045 asm.nop(5); | 1048 asm.nop(5); |