comparison c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java @ 1449:8cfe3537a0d3

Pointer verification stub. Two loose oop fixes in C1X C++ part. Logging which methods have been compiled.
author Thomas Wuerthinger <wuerthinger@ssw.jku.at>
date Thu, 11 Nov 2010 14:09:37 +0100
parents c0e244017dad
children 565f45cebac2
comparison
equal deleted inserted replaced
1445:a7b84a5e16c6 1449:8cfe3537a0d3
35 import com.sun.cri.xir.*; 35 import com.sun.cri.xir.*;
36 import com.sun.cri.xir.CiXirAssembler.XirLabel; 36 import com.sun.cri.xir.CiXirAssembler.XirLabel;
37 import com.sun.cri.xir.CiXirAssembler.XirMark; 37 import com.sun.cri.xir.CiXirAssembler.XirMark;
38 import com.sun.cri.xir.CiXirAssembler.XirOperand; 38 import com.sun.cri.xir.CiXirAssembler.XirOperand;
39 import com.sun.cri.xir.CiXirAssembler.XirParameter; 39 import com.sun.cri.xir.CiXirAssembler.XirParameter;
40 import com.sun.cri.xir.CiXirAssembler.XirRegister;
40 41
41 /** 42 /**
42 * 43 *
43 * @author Thomas Wuerthinger, Lukas Stadler 44 * @author Thomas Wuerthinger, Lukas Stadler
44 */ 45 */
82 private SimpleTemplates prologueTemplates = new SimpleTemplates(STATIC_METHOD) { 83 private SimpleTemplates prologueTemplates = new SimpleTemplates(STATIC_METHOD) {
83 84
84 @Override 85 @Override
85 protected XirTemplate create(CiXirAssembler asm, long flags) { 86 protected XirTemplate create(CiXirAssembler asm, long flags) {
86 asm.restart(CiKind.Void); 87 asm.restart(CiKind.Void);
87 XirOperand framePointer = asm.createRegister("frame pointer", CiKind.Word, AMD64.rbp); 88 XirOperand framePointer = asm.createRegisterTemp("frame pointer", CiKind.Word, AMD64.rbp);
88 XirOperand stackPointer = asm.createRegister("stack pointer", CiKind.Word, AMD64.rsp); 89 XirOperand stackPointer = asm.createRegisterTemp("stack pointer", CiKind.Word, AMD64.rsp);
89 XirLabel unverifiedStub = null; 90 XirLabel unverifiedStub = null;
90 91
91 asm.mark(MARK_OSR_ENTRY); 92 asm.mark(MARK_OSR_ENTRY);
92 asm.mark(MARK_UNVERIFIED_ENTRY); 93 asm.mark(MARK_UNVERIFIED_ENTRY);
93 if (!is(STATIC_METHOD, flags)) { 94 if (!is(STATIC_METHOD, flags)) {
94 unverifiedStub = asm.createOutOfLineLabel("unverified"); 95 unverifiedStub = asm.createOutOfLineLabel("unverified");
95 96
96 XirOperand temp = asm.createRegister("temp (r10)", CiKind.Word, AMD64.r10); 97 XirOperand temp = asm.createRegisterTemp("temp (r10)", CiKind.Word, AMD64.r10);
97 XirOperand cache = asm.createRegister("cache (rax)", CiKind.Word, AMD64.rax); 98 XirOperand cache = asm.createRegisterTemp("cache (rax)", CiKind.Word, AMD64.rax);
98 99
99 CiCallingConvention conventions = registerConfig.getCallingConvention(Java, new CiKind[] {CiKind.Object}, false, target); 100 CiCallingConvention conventions = registerConfig.getCallingConvention(Java, new CiKind[] {CiKind.Object}, false, target);
100 XirOperand receiver = asm.createRegister("cache (rax)", CiKind.Word, conventions.locations[0].asRegister()); 101 XirOperand receiver = asm.createRegisterTemp("receiver", CiKind.Word, conventions.locations[0].asRegister());
101 102
102 asm.pload(CiKind.Word, temp, receiver, asm.i(config.hubOffset), false); 103 asm.pload(CiKind.Word, temp, receiver, asm.i(config.hubOffset), false);
103 asm.jneq(unverifiedStub, cache, temp); 104 asm.jneq(unverifiedStub, cache, temp);
104 } 105 }
105 asm.align(config.codeEntryAlignment); 106 asm.align(config.codeEntryAlignment);
108 asm.push(framePointer); 109 asm.push(framePointer);
109 asm.mov(framePointer, stackPointer); 110 asm.mov(framePointer, stackPointer);
110 asm.pushFrame(); 111 asm.pushFrame();
111 112
112 // -- out of line ------------------------------------------------------- 113 // -- out of line -------------------------------------------------------
113 XirOperand thread = asm.createRegister("thread", CiKind.Word, AMD64.r15); 114 XirOperand thread = asm.createRegisterTemp("thread", CiKind.Word, AMD64.r15);
114 XirOperand exceptionOop = asm.createTemp("exception oop", CiKind.Object); 115 XirOperand exceptionOop = asm.createTemp("exception oop", CiKind.Object);
115 XirLabel unwind = asm.createOutOfLineLabel("unwind"); 116 XirLabel unwind = asm.createOutOfLineLabel("unwind");
116 asm.bindOutOfLine(unwind); 117 asm.bindOutOfLine(unwind);
117 118
118 asm.mark(MARK_UNWIND_ENTRY); 119 asm.mark(MARK_UNWIND_ENTRY);
140 private SimpleTemplates epilogueTemplates = new SimpleTemplates(STATIC_METHOD, SYNCHRONIZED) { 141 private SimpleTemplates epilogueTemplates = new SimpleTemplates(STATIC_METHOD, SYNCHRONIZED) {
141 142
142 @Override 143 @Override
143 protected XirTemplate create(CiXirAssembler asm, long flags) { 144 protected XirTemplate create(CiXirAssembler asm, long flags) {
144 asm.restart(CiKind.Void); 145 asm.restart(CiKind.Void);
145 XirOperand framePointer = asm.createRegister("frame pointer", CiKind.Word, AMD64.rbp); 146 XirOperand framePointer = asm.createRegisterTemp("frame pointer", CiKind.Word, AMD64.rbp);
146 147
147 asm.popFrame(); 148 asm.popFrame();
148 asm.pop(framePointer); 149 asm.pop(framePointer);
149 150
150 // TODO safepoint check 151 // TODO safepoint check
169 private SimpleTemplates exceptionObjectTemplates = new SimpleTemplates() { 170 private SimpleTemplates exceptionObjectTemplates = new SimpleTemplates() {
170 171
171 @Override 172 @Override
172 protected XirTemplate create(CiXirAssembler asm, long flags) { 173 protected XirTemplate create(CiXirAssembler asm, long flags) {
173 XirOperand result = asm.restart(CiKind.Object); 174 XirOperand result = asm.restart(CiKind.Object);
174 XirOperand thread = asm.createRegister("thread", CiKind.Word, AMD64.r15); 175 XirOperand thread = asm.createRegisterTemp("thread", CiKind.Word, AMD64.r15);
175 176
176 asm.pload(CiKind.Object, result, thread, asm.i(config.threadExceptionOopOffset), false); 177 asm.pload(CiKind.Object, result, thread, asm.i(config.threadExceptionOopOffset), false);
177 asm.pstore(CiKind.Object, thread, asm.i(config.threadExceptionOopOffset), asm.o(null), false); 178 asm.pstore(CiKind.Object, thread, asm.i(config.threadExceptionOopOffset), asm.o(null), false);
178 asm.pstore(CiKind.Long, thread, asm.i(config.threadExceptionPcOffset), asm.l(0), false); 179 asm.pstore(CiKind.Long, thread, asm.i(config.threadExceptionPcOffset), asm.l(0), false);
179 180
204 @Override 205 @Override
205 protected XirTemplate create(CiXirAssembler asm, long flags) { 206 protected XirTemplate create(CiXirAssembler asm, long flags) {
206 asm.restart(); 207 asm.restart();
207 XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object); 208 XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object);
208 XirParameter addr = asm.createConstantInputParameter("addr", CiKind.Word); 209 XirParameter addr = asm.createConstantInputParameter("addr", CiKind.Word);
209 XirOperand temp = asm.createRegister("temp", CiKind.Word, AMD64.rax); 210 XirOperand temp = asm.createRegisterTemp("temp", CiKind.Word, AMD64.rax);
210 211
211 if (is(NULL_CHECK, flags)) { 212 if (is(NULL_CHECK, flags)) {
212 asm.nop(1); 213 asm.nop(1);
213 asm.mark(MARK_IMPLICIT_NULL); 214 asm.mark(MARK_IMPLICIT_NULL);
214 asm.pload(CiKind.Word, temp, receiver, true); 215 asm.pload(CiKind.Word, temp, receiver, true);
225 @Override 226 @Override
226 protected XirTemplate create(CiXirAssembler asm, long flags) { 227 protected XirTemplate create(CiXirAssembler asm, long flags) {
227 asm.restart(); 228 asm.restart();
228 XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object); 229 XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object);
229 XirParameter addr = asm.createConstantInputParameter("addr", CiKind.Word); 230 XirParameter addr = asm.createConstantInputParameter("addr", CiKind.Word);
230 XirOperand temp = asm.createRegister("temp", CiKind.Word, AMD64.rax); 231 XirOperand temp = asm.createRegisterTemp("temp", CiKind.Word, AMD64.rax);
231 232
232 if (is(NULL_CHECK, flags)) { 233 if (is(NULL_CHECK, flags)) {
233 asm.nop(1); 234 asm.nop(1);
234 asm.mark(MARK_IMPLICIT_NULL); 235 asm.mark(MARK_IMPLICIT_NULL);
235 asm.pload(CiKind.Word, temp, receiver, true); 236 asm.pload(CiKind.Word, temp, receiver, true);
246 @Override 247 @Override
247 protected XirTemplate create(CiXirAssembler asm, long flags) { 248 protected XirTemplate create(CiXirAssembler asm, long flags) {
248 asm.restart(); 249 asm.restart();
249 XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object); 250 XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object);
250 XirParameter addr = asm.createConstantInputParameter("addr", CiKind.Word); 251 XirParameter addr = asm.createConstantInputParameter("addr", CiKind.Word);
251 XirOperand temp = asm.createRegister("temp", CiKind.Word, AMD64.rax); 252 XirOperand temp = asm.createRegisterTemp("temp", CiKind.Word, AMD64.rax);
252 XirLabel stub = asm.createOutOfLineLabel("call stub"); 253 XirLabel stub = asm.createOutOfLineLabel("call stub");
253 254
254 if (is(NULL_CHECK, flags)) { 255 if (is(NULL_CHECK, flags)) {
255 asm.nop(1); 256 asm.nop(1);
256 asm.mark(MARK_IMPLICIT_NULL); 257 asm.mark(MARK_IMPLICIT_NULL);
258 } 259 }
259 asm.mark(MARK_INVOKESPECIAL); 260 asm.mark(MARK_INVOKESPECIAL);
260 261
261 // -- out of line ------------------------------------------------------- 262 // -- out of line -------------------------------------------------------
262 asm.bindOutOfLine(stub); 263 asm.bindOutOfLine(stub);
263 XirOperand method = asm.createRegister("method", CiKind.Object, AMD64.rbx); 264 XirOperand method = asm.createRegisterTemp("method", CiKind.Object, AMD64.rbx);
264 asm.mark(MARK_STATIC_CALL_STUB, XirMark.CALLSITE); 265 asm.mark(MARK_STATIC_CALL_STUB, XirMark.CALLSITE);
265 asm.mov(method, asm.w(0L)); 266 asm.mov(method, asm.w(0L));
266 XirLabel dummy = asm.createOutOfLineLabel("dummy"); 267 XirLabel dummy = asm.createOutOfLineLabel("dummy");
267 asm.jmp(dummy); 268 asm.jmp(dummy);
268 asm.bindOutOfLine(dummy); 269 asm.bindOutOfLine(dummy);
281 XirLabel stub = asm.createOutOfLineLabel("call stub"); 282 XirLabel stub = asm.createOutOfLineLabel("call stub");
282 asm.mark(MARK_INVOKESTATIC); 283 asm.mark(MARK_INVOKESTATIC);
283 284
284 // -- out of line ------------------------------------------------------- 285 // -- out of line -------------------------------------------------------
285 asm.bindOutOfLine(stub); 286 asm.bindOutOfLine(stub);
286 XirOperand method = asm.createRegister("method", CiKind.Object, AMD64.rbx); 287 XirOperand method = asm.createRegisterTemp("method", CiKind.Object, AMD64.rbx);
287 asm.mark(MARK_STATIC_CALL_STUB, XirMark.CALLSITE); 288 asm.mark(MARK_STATIC_CALL_STUB, XirMark.CALLSITE);
288 asm.mov(method, asm.w(0L)); 289 asm.mov(method, asm.w(0L));
289 XirLabel dummy = asm.createOutOfLineLabel("dummy"); 290 XirLabel dummy = asm.createOutOfLineLabel("dummy");
290 asm.jmp(dummy); 291 asm.jmp(dummy);
291 asm.bindOutOfLine(dummy); 292 asm.bindOutOfLine(dummy);
374 XirParameter fieldOffset = asm.createConstantInputParameter("fieldOffset", CiKind.Int); 375 XirParameter fieldOffset = asm.createConstantInputParameter("fieldOffset", CiKind.Int);
375 if (is(NULL_CHECK, flags)) { 376 if (is(NULL_CHECK, flags)) {
376 asm.nop(1); 377 asm.nop(1);
377 asm.mark(MARK_IMPLICIT_NULL); 378 asm.mark(MARK_IMPLICIT_NULL);
378 } 379 }
380 if (kind == CiKind.Object) {
381 verifyPointer(asm, value);
382 }
379 asm.pstore(kind, object, fieldOffset, value, is(NULL_CHECK, flags)); 383 asm.pstore(kind, object, fieldOffset, value, is(NULL_CHECK, flags));
380 if (is(WRITE_BARRIER, flags)) { 384 if (is(WRITE_BARRIER, flags)) {
381 writeBarrier(asm, object); 385 XirOperand temp = asm.createTemp("temp", CiKind.Word);
386 asm.mov(temp, object);
387 writeBarrier(asm, temp);
382 } 388 }
383 return asm.finishTemplate("putfield<" + kind + ">"); 389 return asm.finishTemplate("putfield<" + kind + ">");
384 } 390 }
385 }; 391 };
386 392
389 @Override 395 @Override
390 protected XirTemplate create(CiXirAssembler asm, long flags, int size) { 396 protected XirTemplate create(CiXirAssembler asm, long flags, int size) {
391 XirOperand result = asm.restart(CiKind.Word); 397 XirOperand result = asm.restart(CiKind.Word);
392 XirOperand type = asm.createInputParameter("type", CiKind.Object); 398 XirOperand type = asm.createInputParameter("type", CiKind.Object);
393 399
394 XirOperand thread = asm.createRegister("thread", CiKind.Word, AMD64.r15); 400 XirOperand thread = asm.createRegisterTemp("thread", CiKind.Word, AMD64.r15);
395 XirOperand temp1 = asm.createRegister("temp1", CiKind.Word, AMD64.rcx); 401 XirOperand temp1 = asm.createRegisterTemp("temp1", CiKind.Word, AMD64.rcx);
396 XirOperand temp2 = asm.createRegister("temp2", CiKind.Word, AMD64.rbx); 402 XirOperand temp2 = asm.createRegisterTemp("temp2", CiKind.Word, AMD64.rbx);
397 XirOperand temp2i = asm.createRegister("temp2i", CiKind.Int, AMD64.rbx); 403 XirOperand temp2i = asm.createRegisterTemp("temp2i", CiKind.Int, AMD64.rbx);
398 useRegisters(asm, AMD64.rsi); 404 useRegisters(asm, AMD64.rsi);
399 XirLabel tlabFull = asm.createOutOfLineLabel("tlab full"); 405 XirLabel tlabFull = asm.createOutOfLineLabel("tlab full");
400 XirLabel resume = asm.createInlineLabel("resume"); 406 XirLabel resume = asm.createInlineLabel("resume");
401 407
402 // check if the class is already initialized 408 // check if the class is already initialized
422 } 428 }
423 } 429 }
424 430
425 // -- out of line ------------------------------------------------------- 431 // -- out of line -------------------------------------------------------
426 asm.bindOutOfLine(tlabFull); 432 asm.bindOutOfLine(tlabFull);
427 XirOperand arg = asm.createRegister("runtime call argument", CiKind.Object, AMD64.rdx); 433 XirOperand arg = asm.createRegisterTemp("runtime call argument", CiKind.Object, AMD64.rdx);
428 asm.mov(arg, type); 434 asm.mov(arg, type);
429 useRegisters(asm, AMD64.rax); 435 useRegisters(asm, AMD64.rax);
430 asm.callRuntime(config.newInstanceStub, result); 436 asm.callRuntime(config.newInstanceStub, result);
431 asm.jmp(resume); 437 asm.jmp(resume);
432 438
437 private SimpleTemplates newInstanceUnresolvedTemplates = new SimpleTemplates() { 443 private SimpleTemplates newInstanceUnresolvedTemplates = new SimpleTemplates() {
438 444
439 @Override 445 @Override
440 protected XirTemplate create(CiXirAssembler asm, long flags) { 446 protected XirTemplate create(CiXirAssembler asm, long flags) {
441 XirOperand result = asm.restart(CiKind.Word); 447 XirOperand result = asm.restart(CiKind.Word);
442 XirOperand arg = asm.createRegister("runtime call argument", CiKind.Object, AMD64.rdx); 448 XirOperand arg = asm.createRegisterTemp("runtime call argument", CiKind.Object, AMD64.rdx);
443 449
444 UnresolvedClassPatching patching = new UnresolvedClassPatching(asm, arg, config); 450 UnresolvedClassPatching patching = new UnresolvedClassPatching(asm, arg, config);
445 451
446 patching.emitInline(); 452 patching.emitInline();
447 useRegisters(asm, AMD64.rbx, AMD64.rcx, AMD64.rsi, AMD64.rax); 453 useRegisters(asm, AMD64.rbx, AMD64.rcx, AMD64.rsi, AMD64.rax);
460 protected XirTemplate create(CiXirAssembler asm, long flags) { 466 protected XirTemplate create(CiXirAssembler asm, long flags) {
461 XirOperand result = asm.restart(CiKind.Object); 467 XirOperand result = asm.restart(CiKind.Object);
462 468
463 XirParameter lengthParam = asm.createInputParameter("length", CiKind.Int); 469 XirParameter lengthParam = asm.createInputParameter("length", CiKind.Int);
464 470
465 XirOperand length = asm.createRegister("length", CiKind.Int, AMD64.rbx); 471 XirOperand length = asm.createRegisterTemp("length", CiKind.Int, AMD64.rbx);
466 XirOperand hub = asm.createRegister("hub", CiKind.Object, AMD64.rdx); 472 XirOperand hub = asm.createRegisterTemp("hub", CiKind.Object, AMD64.rdx);
467 473
468 UnresolvedClassPatching patching = null; 474 UnresolvedClassPatching patching = null;
469 if (is(UNRESOLVED, flags)) { 475 if (is(UNRESOLVED, flags)) {
470 // insert the patching code for class resolving - the hub will end up in "hub" 476 // insert the patching code for class resolving - the hub will end up in "hub"
471 patching = new UnresolvedClassPatching(asm, hub, config); 477 patching = new UnresolvedClassPatching(asm, hub, config);
491 XirOperand result = asm.restart(CiKind.Object); 497 XirOperand result = asm.restart(CiKind.Object);
492 498
493 XirParameter lengthParam = asm.createInputParameter("length", CiKind.Int); 499 XirParameter lengthParam = asm.createInputParameter("length", CiKind.Int);
494 XirParameter hubParam = asm.createConstantInputParameter("hub", CiKind.Object); 500 XirParameter hubParam = asm.createConstantInputParameter("hub", CiKind.Object);
495 501
496 XirOperand length = asm.createRegister("length", CiKind.Int, AMD64.rbx); 502 XirOperand length = asm.createRegisterTemp("length", CiKind.Int, AMD64.rbx);
497 XirOperand hub = asm.createRegister("hub", CiKind.Object, AMD64.rdx); 503 XirOperand hub = asm.createRegisterTemp("hub", CiKind.Object, AMD64.rdx);
498 504
499 asm.mov(hub, hubParam); 505 asm.mov(hub, hubParam);
500 asm.mov(length, lengthParam); 506 asm.mov(length, lengthParam);
501 useRegisters(asm, AMD64.rsi, AMD64.rcx, AMD64.rdi, AMD64.rax); 507 useRegisters(asm, AMD64.rsi, AMD64.rcx, AMD64.rdi, AMD64.rax);
502 asm.callRuntime(config.newTypeArrayStub, result); 508 asm.callRuntime(config.newTypeArrayStub, result);
509 515
510 @Override 516 @Override
511 protected XirTemplate create(CiXirAssembler asm, long flags, int dimensions) { 517 protected XirTemplate create(CiXirAssembler asm, long flags, int dimensions) {
512 XirOperand result = asm.restart(CiKind.Object); 518 XirOperand result = asm.restart(CiKind.Object);
513 519
514 XirOperand hub = asm.createRegister("hub", CiKind.Object, AMD64.rax); 520 XirOperand hub = asm.createRegisterTemp("hub", CiKind.Object, AMD64.rax);
515 XirOperand rank = asm.createRegister("rank", CiKind.Int, AMD64.rbx); 521 XirOperand rank = asm.createRegisterTemp("rank", CiKind.Int, AMD64.rbx);
516 XirOperand sizes = asm.createRegister("sizes", CiKind.Long, AMD64.rcx); 522 XirOperand sizes = asm.createRegisterTemp("sizes", CiKind.Long, AMD64.rcx);
517 XirOperand thread = asm.createRegister("thread", CiKind.Long, AMD64.r15); 523 XirOperand thread = asm.createRegisterTemp("thread", CiKind.Long, AMD64.r15);
518 asm.add(sizes, thread, asm.l(config.threadMultiNewArrayStorage)); 524 asm.add(sizes, thread, asm.l(config.threadMultiNewArrayStorage));
519 for (int i = 0; i < dimensions; i++) { 525 for (int i = 0; i < dimensions; i++) {
520 XirParameter length = asm.createInputParameter("length" + i, CiKind.Int); 526 XirParameter length = asm.createInputParameter("length" + i, CiKind.Int);
521 asm.pstore(CiKind.Int, sizes, asm.i(i * target.sizeInBytes(CiKind.Int)), length, false); 527 asm.pstore(CiKind.Int, sizes, asm.i(i * target.sizeInBytes(CiKind.Int)), length, false);
522 } 528 }
575 581
576 // -- out of line ------------------------------------------------------- 582 // -- out of line -------------------------------------------------------
577 asm.bindOutOfLine(slowPath); 583 asm.bindOutOfLine(slowPath);
578 checkSubtype(asm, objHub, objHub, hub); 584 checkSubtype(asm, objHub, objHub, hub);
579 asm.jneq(end, objHub, asm.o(null)); 585 asm.jneq(end, objHub, asm.o(null));
580 XirOperand scratch = asm.createRegister("scratch", CiKind.Object, AMD64.r10); 586 XirOperand scratch = asm.createRegisterTemp("scratch", CiKind.Object, AMD64.r10);
581 asm.mov(scratch, object); 587 asm.mov(scratch, object);
582 asm.callRuntime(config.throwClassCastException, null); 588 asm.callRuntime(config.throwClassCastException, null);
583 asm.shouldNotReachHere(); 589 asm.shouldNotReachHere();
584 590
585 if (is(UNRESOLVED, flags)) { 591 if (is(UNRESOLVED, flags)) {
736 int elemSize = target.sizeInBytes(kind); 742 int elemSize = target.sizeInBytes(kind);
737 743
738 if (implicitNullException) { 744 if (implicitNullException) {
739 asm.mark(MARK_IMPLICIT_NULL); 745 asm.mark(MARK_IMPLICIT_NULL);
740 } 746 }
741 asm.pstore(kind, array, index, value, config.getArrayOffset(kind), Scale.fromInt(elemSize), implicitNullException); 747 int disp = config.getArrayOffset(kind);
748 Scale scale = Scale.fromInt(elemSize);
749 if (kind == CiKind.Object) {
750 verifyPointer(asm, value);
751 }
742 if (is(WRITE_BARRIER, flags)) { 752 if (is(WRITE_BARRIER, flags)) {
743 writeBarrier(asm, array); 753 asm.lea(temp, array, index, disp, scale);
754 asm.pstore(kind, temp, value, implicitNullException);
755 writeBarrier(asm, temp);
756 } else {
757 asm.pstore(kind, array, index, value, disp, scale, implicitNullException);
744 } 758 }
745 759
746 // -- out of line ------------------------------------------------------- 760 // -- out of line -------------------------------------------------------
747 if (is(BOUNDS_CHECK, flags)) { 761 if (is(BOUNDS_CHECK, flags)) {
748 asm.bindOutOfLine(failBoundsCheck); 762 asm.bindOutOfLine(failBoundsCheck);
769 XirParameter object = asm.createInputParameter("object", CiKind.Object); 783 XirParameter object = asm.createInputParameter("object", CiKind.Object);
770 if (is(NULL_CHECK, flags)) { 784 if (is(NULL_CHECK, flags)) {
771 asm.nop(1); 785 asm.nop(1);
772 asm.mark(MARK_IMPLICIT_NULL); 786 asm.mark(MARK_IMPLICIT_NULL);
773 } 787 }
788 verifyPointer(asm, object);
774 asm.pload(CiKind.Int, result, object, asm.i(config.arrayLengthOffset), true); 789 asm.pload(CiKind.Int, result, object, asm.i(config.arrayLengthOffset), true);
775 return asm.finishTemplate("arrayLength"); 790 return asm.finishTemplate("arrayLength");
776 } 791 }
777 }; 792 };
778 793
1075 1090
1076 state = State.Finished; 1091 state = State.Finished;
1077 } 1092 }
1078 } 1093 }
1079 1094
1095 private void verifyPointer(CiXirAssembler asm, XirOperand pointer) {
1096 if (config.verifyPointers) {
1097 // The verify pointer stub wants the argument in a fixed register.
1098 XirOperand fixed = asm.createRegisterTemp("fixed", CiKind.Object, AMD64.r13);
1099 asm.push(fixed);
1100 asm.mov(fixed, pointer);
1101 asm.callRuntime(config.verifyPointerStub, null);
1102 asm.pop(fixed);
1103 }
1104 }
1105
1080 private void checkSubtype(CiXirAssembler asm, XirOperand result, XirOperand objHub, XirOperand hub) { 1106 private void checkSubtype(CiXirAssembler asm, XirOperand result, XirOperand objHub, XirOperand hub) {
1081 asm.push(objHub); 1107 asm.push(objHub);
1082 asm.push(hub); 1108 asm.push(hub);
1083 asm.callRuntime(config.instanceofStub, null); 1109 asm.callRuntime(config.instanceofStub, null);
1084 asm.pop(result); 1110 asm.pop(result);
1086 } 1112 }
1087 1113
1088 private void useRegisters(CiXirAssembler asm, CiRegister... registers) { 1114 private void useRegisters(CiXirAssembler asm, CiRegister... registers) {
1089 if (registers != null) { 1115 if (registers != null) {
1090 for (CiRegister register : registers) { 1116 for (CiRegister register : registers) {
1091 asm.createRegister("reg", CiKind.Illegal, register); 1117 asm.createRegisterTemp("reg", CiKind.Illegal, register);
1092 } 1118 }
1093 } 1119 }
1094 } 1120 }
1095 1121
1096 private void writeBarrier(CiXirAssembler asm, XirOperand base) { 1122 private void writeBarrier(CiXirAssembler asm, XirOperand base) {