1290 }
1291
1292
1293 void MacroAssembler::verify_oop(Register reg, const char* s) {
1294 if (!VerifyOops) return;
1295
1296 // Pass register number to verify_oop_subroutine
1297 const char* b = NULL;
1298 {
1299 ResourceMark rm;
1300 stringStream ss;
1301 ss.print("verify_oop: %s: %s", reg->name(), s);
1302 b = code_string(ss.as_string());
1303 }
1304 BLOCK_COMMENT("verify_oop {");
1305
1306 stp(r0, rscratch1, Address(pre(sp, -2 * wordSize)));
1307 stp(rscratch2, lr, Address(pre(sp, -2 * wordSize)));
1308
1309 mov(r0, reg);
1310 mov(rscratch1, (address)b);
1311
1312 // call indirectly to solve generation ordering problem
1313 lea(rscratch2, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));
1314 ldr(rscratch2, Address(rscratch2));
1315 blr(rscratch2);
1316
1317 ldp(rscratch2, lr, Address(post(sp, 2 * wordSize)));
1318 ldp(r0, rscratch1, Address(post(sp, 2 * wordSize)));
1319
1320 BLOCK_COMMENT("} verify_oop");
1321 }
1322
1323 void MacroAssembler::verify_oop_addr(Address addr, const char* s) {
1324 if (!VerifyOops) return;
1325
1326 const char* b = NULL;
1327 {
1328 ResourceMark rm;
1329 stringStream ss;
1330 ss.print("verify_oop_addr: %s", s);
1331 b = code_string(ss.as_string());
1332 }
1333 BLOCK_COMMENT("verify_oop_addr {");
1334
1335 stp(r0, rscratch1, Address(pre(sp, -2 * wordSize)));
1336 stp(rscratch2, lr, Address(pre(sp, -2 * wordSize)));
1337
1338 // addr may contain sp so we will have to adjust it based on the
1339 // pushes that we just did.
1340 if (addr.uses(sp)) {
1341 lea(r0, addr);
1342 ldr(r0, Address(r0, 4 * wordSize));
1343 } else {
1344 ldr(r0, addr);
1345 }
1346 mov(rscratch1, (address)b);
1347
1348 // call indirectly to solve generation ordering problem
1349 lea(rscratch2, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));
1350 ldr(rscratch2, Address(rscratch2));
1351 blr(rscratch2);
1352
1353 ldp(rscratch2, lr, Address(post(sp, 2 * wordSize)));
1354 ldp(r0, rscratch1, Address(post(sp, 2 * wordSize)));
1355
1356 BLOCK_COMMENT("} verify_oop_addr");
1357 }
1358
1359 Address MacroAssembler::argument_address(RegisterOrConstant arg_slot,
1360 int extra_slot_offset) {
1361 // cf. TemplateTable::prepare_invoke(), if (load_receiver).
1362 int stackElementSize = Interpreter::stackElementSize;
1363 int offset = Interpreter::expr_offset_in_bytes(extra_slot_offset+0);
1364 #ifdef ASSERT
1365 int offset1 = Interpreter::expr_offset_in_bytes(extra_slot_offset+1);
1366 assert(offset1 - offset == stackElementSize, "correct arithmetic");
2120
2121 STATIC_ASSERT(JNIHandles::weak_tag_mask == 1u);
2122 tbz(r0, 0, not_weak); // Test for jweak tag.
2123
2124 // Resolve jweak.
2125 access_load_at(T_OBJECT, IN_NATIVE | ON_PHANTOM_OOP_REF, value,
2126 Address(value, -JNIHandles::weak_tag_value), tmp, thread);
2127 verify_oop(value);
2128 b(done);
2129
2130 bind(not_weak);
2131 // Resolve (untagged) jobject.
2132 access_load_at(T_OBJECT, IN_NATIVE, value, Address(value, 0), tmp, thread);
2133 verify_oop(value);
2134 bind(done);
2135 }
2136
2137 void MacroAssembler::stop(const char* msg) {
2138 address ip = pc();
2139 pusha();
2140 mov(c_rarg0, (address)msg);
2141 mov(c_rarg1, (address)ip);
2142 mov(c_rarg2, sp);
2143 mov(c_rarg3, CAST_FROM_FN_PTR(address, MacroAssembler::debug64));
2144 blr(c_rarg3);
2145 hlt(0);
2146 }
2147
2148 void MacroAssembler::warn(const char* msg) {
2149 pusha();
2150 mov(c_rarg0, (address)msg);
2151 mov(lr, CAST_FROM_FN_PTR(address, warning));
2152 blr(lr);
2153 popa();
2154 }
2155
2156 void MacroAssembler::unimplemented(const char* what) {
2157 const char* buf = NULL;
2158 {
2159 ResourceMark rm;
2160 stringStream ss;
2161 ss.print("unimplemented: %s", what);
|
1290 }
1291
1292
1293 void MacroAssembler::verify_oop(Register reg, const char* s) {
1294 if (!VerifyOops) return;
1295
1296 // Pass register number to verify_oop_subroutine
1297 const char* b = NULL;
1298 {
1299 ResourceMark rm;
1300 stringStream ss;
1301 ss.print("verify_oop: %s: %s", reg->name(), s);
1302 b = code_string(ss.as_string());
1303 }
1304 BLOCK_COMMENT("verify_oop {");
1305
1306 stp(r0, rscratch1, Address(pre(sp, -2 * wordSize)));
1307 stp(rscratch2, lr, Address(pre(sp, -2 * wordSize)));
1308
1309 mov(r0, reg);
1310 movptr(rscratch1, (uintptr_t)(address)b);
1311
1312 // call indirectly to solve generation ordering problem
1313 lea(rscratch2, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));
1314 ldr(rscratch2, Address(rscratch2));
1315 blr(rscratch2);
1316
1317 ldp(rscratch2, lr, Address(post(sp, 2 * wordSize)));
1318 ldp(r0, rscratch1, Address(post(sp, 2 * wordSize)));
1319
1320 BLOCK_COMMENT("} verify_oop");
1321 }
1322
1323 void MacroAssembler::verify_oop_addr(Address addr, const char* s) {
1324 if (!VerifyOops) return;
1325
1326 const char* b = NULL;
1327 {
1328 ResourceMark rm;
1329 stringStream ss;
1330 ss.print("verify_oop_addr: %s", s);
1331 b = code_string(ss.as_string());
1332 }
1333 BLOCK_COMMENT("verify_oop_addr {");
1334
1335 stp(r0, rscratch1, Address(pre(sp, -2 * wordSize)));
1336 stp(rscratch2, lr, Address(pre(sp, -2 * wordSize)));
1337
1338 // addr may contain sp so we will have to adjust it based on the
1339 // pushes that we just did.
1340 if (addr.uses(sp)) {
1341 lea(r0, addr);
1342 ldr(r0, Address(r0, 4 * wordSize));
1343 } else {
1344 ldr(r0, addr);
1345 }
1346 movptr(rscratch1, (uintptr_t)(address)b);
1347
1348 // call indirectly to solve generation ordering problem
1349 lea(rscratch2, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));
1350 ldr(rscratch2, Address(rscratch2));
1351 blr(rscratch2);
1352
1353 ldp(rscratch2, lr, Address(post(sp, 2 * wordSize)));
1354 ldp(r0, rscratch1, Address(post(sp, 2 * wordSize)));
1355
1356 BLOCK_COMMENT("} verify_oop_addr");
1357 }
1358
1359 Address MacroAssembler::argument_address(RegisterOrConstant arg_slot,
1360 int extra_slot_offset) {
1361 // cf. TemplateTable::prepare_invoke(), if (load_receiver).
1362 int stackElementSize = Interpreter::stackElementSize;
1363 int offset = Interpreter::expr_offset_in_bytes(extra_slot_offset+0);
1364 #ifdef ASSERT
1365 int offset1 = Interpreter::expr_offset_in_bytes(extra_slot_offset+1);
1366 assert(offset1 - offset == stackElementSize, "correct arithmetic");
2120
2121 STATIC_ASSERT(JNIHandles::weak_tag_mask == 1u);
2122 tbz(r0, 0, not_weak); // Test for jweak tag.
2123
2124 // Resolve jweak.
2125 access_load_at(T_OBJECT, IN_NATIVE | ON_PHANTOM_OOP_REF, value,
2126 Address(value, -JNIHandles::weak_tag_value), tmp, thread);
2127 verify_oop(value);
2128 b(done);
2129
2130 bind(not_weak);
2131 // Resolve (untagged) jobject.
2132 access_load_at(T_OBJECT, IN_NATIVE, value, Address(value, 0), tmp, thread);
2133 verify_oop(value);
2134 bind(done);
2135 }
2136
2137 void MacroAssembler::stop(const char* msg) {
2138 address ip = pc();
2139 pusha();
2140 movptr(c_rarg0, (uintptr_t)(address)msg);
2141 movptr(c_rarg1, (uintptr_t)(address)ip);
2142 mov(c_rarg2, sp);
2143 mov(c_rarg3, CAST_FROM_FN_PTR(address, MacroAssembler::debug64));
2144 blr(c_rarg3);
2145 hlt(0);
2146 }
2147
2148 void MacroAssembler::warn(const char* msg) {
2149 pusha();
2150 mov(c_rarg0, (address)msg);
2151 mov(lr, CAST_FROM_FN_PTR(address, warning));
2152 blr(lr);
2153 popa();
2154 }
2155
2156 void MacroAssembler::unimplemented(const char* what) {
2157 const char* buf = NULL;
2158 {
2159 ResourceMark rm;
2160 stringStream ss;
2161 ss.print("unimplemented: %s", what);
|