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);