Mercurial > hg > truffle
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) { |