1371 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1372 emit_rm(cbuf, 0x2, reg & 7, 0x04);
1373 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1374 emit_d32(cbuf, offset);
1375 } else {
1376 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1377 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1378 emit_rm(cbuf, 0x1, reg & 7, 0x04);
1379 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1380 emit_d8(cbuf, offset);
1381 }
1382 }
1383
1384 uint BoxLockNode::size(PhaseRegAlloc *ra_) const
1385 {
1386 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1387 return (offset < 0x80) ? 5 : 8; // REX
1388 }
1389
1390 //=============================================================================
1391
1392 // emit call stub, compiled java to interpreter
1393 void emit_java_to_interp(CodeBuffer& cbuf)
1394 {
1395 // Stub is fixed up when the corresponding call is converted from
1396 // calling compiled code to calling interpreted code.
1397 // movq rbx, 0
1398 // jmp -5 # to self
1399
1400 address mark = cbuf.insts_mark(); // get mark within main instrs section
1401
1402 // Note that the code buffer's insts_mark is always relative to insts.
1403 // That's why we must use the macroassembler to generate a stub.
1404 MacroAssembler _masm(&cbuf);
1405
1406 address base =
1407 __ start_a_stub(Compile::MAX_stubs_size);
1408 if (base == NULL) return; // CodeBuffer::expand failed
1409 // static stub relocation stores the instruction address of the call
1410 __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM64);
1411 // static stub relocation also tags the Method* in the code-stream.
1412 __ mov_metadata(rbx, (Metadata*) NULL); // method is zapped till fixup time
1413 // This is recognized as unresolved by relocs/nativeinst/ic code
1414 __ jump(RuntimeAddress(__ pc()));
1415
1416 // Update current stubs pointer and restore insts_end.
1417 __ end_a_stub();
1418 }
1419
1420 // size of call stub, compiled java to interpretor
1421 uint size_java_to_interp()
1422 {
1423 return 15; // movq (1+1+8); jmp (1+4)
1424 }
1425
1426 // relocation entries for call stub, compiled java to interpretor
1427 uint reloc_java_to_interp()
1428 {
1429 return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call
1430 }
1431
1432 //=============================================================================
1433 #ifndef PRODUCT
1434 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1435 {
1436 if (UseCompressedKlassPointers) {
1437 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1438 if (Universe::narrow_klass_shift() != 0) {
1439 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
1440 }
1441 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check");
1442 } else {
1443 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t"
1444 "# Inline cache check");
1445 }
1446 st->print_cr("\tjne SharedRuntime::_ic_miss_stub");
1447 st->print_cr("\tnop\t# nops to align entry point");
1448 }
1449 #endif
1450
1451 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1452 {
2072 cbuf.set_insts_mark();
2073 $$$emit8$primary;
2074
2075 if (!_method) {
2076 emit_d32_reloc(cbuf,
2077 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2078 runtime_call_Relocation::spec(),
2079 RELOC_DISP32);
2080 } else if (_optimized_virtual) {
2081 emit_d32_reloc(cbuf,
2082 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2083 opt_virtual_call_Relocation::spec(),
2084 RELOC_DISP32);
2085 } else {
2086 emit_d32_reloc(cbuf,
2087 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2088 static_call_Relocation::spec(),
2089 RELOC_DISP32);
2090 }
2091 if (_method) {
2092 // Emit stub for static call
2093 emit_java_to_interp(cbuf);
2094 }
2095 %}
2096
2097 enc_class Java_Dynamic_Call(method meth) %{
2098 MacroAssembler _masm(&cbuf);
2099 __ ic_call((address)$meth$$method);
2100 %}
2101
2102 enc_class Java_Compiled_Call(method meth)
2103 %{
2104 // JAVA COMPILED CALL
2105 int disp = in_bytes(Method:: from_compiled_offset());
2106
2107 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!!
2108 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small");
2109
2110 // callq *disp(%rax)
2111 cbuf.set_insts_mark();
2112 $$$emit8$primary;
2113 if (disp < 0x80) {
|
1371 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1372 emit_rm(cbuf, 0x2, reg & 7, 0x04);
1373 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1374 emit_d32(cbuf, offset);
1375 } else {
1376 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1377 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1378 emit_rm(cbuf, 0x1, reg & 7, 0x04);
1379 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1380 emit_d8(cbuf, offset);
1381 }
1382 }
1383
1384 uint BoxLockNode::size(PhaseRegAlloc *ra_) const
1385 {
1386 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1387 return (offset < 0x80) ? 5 : 8; // REX
1388 }
1389
1390 //=============================================================================
1391 #ifndef PRODUCT
1392 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1393 {
1394 if (UseCompressedKlassPointers) {
1395 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1396 if (Universe::narrow_klass_shift() != 0) {
1397 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
1398 }
1399 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check");
1400 } else {
1401 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t"
1402 "# Inline cache check");
1403 }
1404 st->print_cr("\tjne SharedRuntime::_ic_miss_stub");
1405 st->print_cr("\tnop\t# nops to align entry point");
1406 }
1407 #endif
1408
1409 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1410 {
2030 cbuf.set_insts_mark();
2031 $$$emit8$primary;
2032
2033 if (!_method) {
2034 emit_d32_reloc(cbuf,
2035 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2036 runtime_call_Relocation::spec(),
2037 RELOC_DISP32);
2038 } else if (_optimized_virtual) {
2039 emit_d32_reloc(cbuf,
2040 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2041 opt_virtual_call_Relocation::spec(),
2042 RELOC_DISP32);
2043 } else {
2044 emit_d32_reloc(cbuf,
2045 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2046 static_call_Relocation::spec(),
2047 RELOC_DISP32);
2048 }
2049 if (_method) {
2050 // Emit stub for static call.
2051 CompiledStaticCall::emit_to_interp_stub(cbuf);
2052 }
2053 %}
2054
2055 enc_class Java_Dynamic_Call(method meth) %{
2056 MacroAssembler _masm(&cbuf);
2057 __ ic_call((address)$meth$$method);
2058 %}
2059
2060 enc_class Java_Compiled_Call(method meth)
2061 %{
2062 // JAVA COMPILED CALL
2063 int disp = in_bytes(Method:: from_compiled_offset());
2064
2065 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!!
2066 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small");
2067
2068 // callq *disp(%rax)
2069 cbuf.set_insts_mark();
2070 $$$emit8$primary;
2071 if (disp < 0x80) {
|