470 |
470 |
471 if (PrintBiasedLockingStatistics && counters == NULL) |
471 if (PrintBiasedLockingStatistics && counters == NULL) |
472 counters = BiasedLocking::counters(); |
472 counters = BiasedLocking::counters(); |
473 |
473 |
474 assert_different_registers(lock_reg, obj_reg, swap_reg, tmp_reg, rscratch1, rscratch2, noreg); |
474 assert_different_registers(lock_reg, obj_reg, swap_reg, tmp_reg, rscratch1, rscratch2, noreg); |
475 assert(markOopDesc::age_shift == markOopDesc::lock_bits + markOopDesc::biased_lock_bits, "biased locking makes assumptions about bit layout"); |
475 assert(markWord::age_shift == markWord::lock_bits + markWord::biased_lock_bits, "biased locking makes assumptions about bit layout"); |
476 Address mark_addr (obj_reg, oopDesc::mark_offset_in_bytes()); |
476 Address mark_addr (obj_reg, oopDesc::mark_offset_in_bytes()); |
477 Address klass_addr (obj_reg, oopDesc::klass_offset_in_bytes()); |
477 Address klass_addr (obj_reg, oopDesc::klass_offset_in_bytes()); |
478 Address saved_mark_addr(lock_reg, 0); |
478 Address saved_mark_addr(lock_reg, 0); |
479 |
479 |
480 // Biased locking |
480 // Biased locking |
487 int null_check_offset = -1; |
487 int null_check_offset = -1; |
488 if (!swap_reg_contains_mark) { |
488 if (!swap_reg_contains_mark) { |
489 null_check_offset = offset(); |
489 null_check_offset = offset(); |
490 ldr(swap_reg, mark_addr); |
490 ldr(swap_reg, mark_addr); |
491 } |
491 } |
492 andr(tmp_reg, swap_reg, markOopDesc::biased_lock_mask_in_place); |
492 andr(tmp_reg, swap_reg, markWord::biased_lock_mask_in_place); |
493 cmp(tmp_reg, (u1)markOopDesc::biased_lock_pattern); |
493 cmp(tmp_reg, (u1)markWord::biased_lock_pattern); |
494 br(Assembler::NE, cas_label); |
494 br(Assembler::NE, cas_label); |
495 // The bias pattern is present in the object's header. Need to check |
495 // The bias pattern is present in the object's header. Need to check |
496 // whether the bias owner and the epoch are both still current. |
496 // whether the bias owner and the epoch are both still current. |
497 load_prototype_header(tmp_reg, obj_reg); |
497 load_prototype_header(tmp_reg, obj_reg); |
498 orr(tmp_reg, tmp_reg, rthread); |
498 orr(tmp_reg, tmp_reg, rthread); |
499 eor(tmp_reg, swap_reg, tmp_reg); |
499 eor(tmp_reg, swap_reg, tmp_reg); |
500 andr(tmp_reg, tmp_reg, ~((int) markOopDesc::age_mask_in_place)); |
500 andr(tmp_reg, tmp_reg, ~((int) markWord::age_mask_in_place)); |
501 if (counters != NULL) { |
501 if (counters != NULL) { |
502 Label around; |
502 Label around; |
503 cbnz(tmp_reg, around); |
503 cbnz(tmp_reg, around); |
504 atomic_incw(Address((address)counters->biased_lock_entry_count_addr()), tmp_reg, rscratch1, rscratch2); |
504 atomic_incw(Address((address)counters->biased_lock_entry_count_addr()), tmp_reg, rscratch1, rscratch2); |
505 b(done); |
505 b(done); |
518 // header. |
518 // header. |
519 |
519 |
520 // If the low three bits in the xor result aren't clear, that means |
520 // If the low three bits in the xor result aren't clear, that means |
521 // the prototype header is no longer biased and we have to revoke |
521 // the prototype header is no longer biased and we have to revoke |
522 // the bias on this object. |
522 // the bias on this object. |
523 andr(rscratch1, tmp_reg, markOopDesc::biased_lock_mask_in_place); |
523 andr(rscratch1, tmp_reg, markWord::biased_lock_mask_in_place); |
524 cbnz(rscratch1, try_revoke_bias); |
524 cbnz(rscratch1, try_revoke_bias); |
525 |
525 |
526 // Biasing is still enabled for this data type. See whether the |
526 // Biasing is still enabled for this data type. See whether the |
527 // epoch of the current bias is still valid, meaning that the epoch |
527 // epoch of the current bias is still valid, meaning that the epoch |
528 // bits of the mark word are equal to the epoch bits of the |
528 // bits of the mark word are equal to the epoch bits of the |
530 // only change at a safepoint.) If not, attempt to rebias the object |
530 // only change at a safepoint.) If not, attempt to rebias the object |
531 // toward the current thread. Note that we must be absolutely sure |
531 // toward the current thread. Note that we must be absolutely sure |
532 // that the current epoch is invalid in order to do this because |
532 // that the current epoch is invalid in order to do this because |
533 // otherwise the manipulations it performs on the mark word are |
533 // otherwise the manipulations it performs on the mark word are |
534 // illegal. |
534 // illegal. |
535 andr(rscratch1, tmp_reg, markOopDesc::epoch_mask_in_place); |
535 andr(rscratch1, tmp_reg, markWord::epoch_mask_in_place); |
536 cbnz(rscratch1, try_rebias); |
536 cbnz(rscratch1, try_rebias); |
537 |
537 |
538 // The epoch of the current bias is still valid but we know nothing |
538 // The epoch of the current bias is still valid but we know nothing |
539 // about the owner; it might be set or it might be clear. Try to |
539 // about the owner; it might be set or it might be clear. Try to |
540 // acquire the bias of the object using an atomic operation. If this |
540 // acquire the bias of the object using an atomic operation. If this |
541 // fails we will go in to the runtime to revoke the object's bias. |
541 // fails we will go in to the runtime to revoke the object's bias. |
542 // Note that we first construct the presumed unbiased header so we |
542 // Note that we first construct the presumed unbiased header so we |
543 // don't accidentally blow away another thread's valid bias. |
543 // don't accidentally blow away another thread's valid bias. |
544 { |
544 { |
545 Label here; |
545 Label here; |
546 mov(rscratch1, markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place); |
546 mov(rscratch1, markWord::biased_lock_mask_in_place | markWord::age_mask_in_place | markWord::epoch_mask_in_place); |
547 andr(swap_reg, swap_reg, rscratch1); |
547 andr(swap_reg, swap_reg, rscratch1); |
548 orr(tmp_reg, swap_reg, rthread); |
548 orr(tmp_reg, swap_reg, rthread); |
549 cmpxchg_obj_header(swap_reg, tmp_reg, obj_reg, rscratch1, here, slow_case); |
549 cmpxchg_obj_header(swap_reg, tmp_reg, obj_reg, rscratch1, here, slow_case); |
550 // If the biasing toward our thread failed, this means that |
550 // If the biasing toward our thread failed, this means that |
551 // another thread succeeded in biasing it toward itself and we |
551 // another thread succeeded in biasing it toward itself and we |
626 // First, the interpreter checks for IllegalMonitorStateException at |
626 // First, the interpreter checks for IllegalMonitorStateException at |
627 // a higher level. Second, if the bias was revoked while we held the |
627 // a higher level. Second, if the bias was revoked while we held the |
628 // lock, the object could not be rebiased toward another thread, so |
628 // lock, the object could not be rebiased toward another thread, so |
629 // the bias bit would be clear. |
629 // the bias bit would be clear. |
630 ldr(temp_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); |
630 ldr(temp_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes())); |
631 andr(temp_reg, temp_reg, markOopDesc::biased_lock_mask_in_place); |
631 andr(temp_reg, temp_reg, markWord::biased_lock_mask_in_place); |
632 cmp(temp_reg, (u1)markOopDesc::biased_lock_pattern); |
632 cmp(temp_reg, (u1)markWord::biased_lock_pattern); |
633 br(Assembler::EQ, done); |
633 br(Assembler::EQ, done); |
634 } |
634 } |
635 |
635 |
636 static void pass_arg0(MacroAssembler* masm, Register arg) { |
636 static void pass_arg0(MacroAssembler* masm, Register arg) { |
637 if (c_rarg0 != arg ) { |
637 if (c_rarg0 != arg ) { |
968 |
968 |
969 if (offset != 0) |
969 if (offset != 0) |
970 add(tmp, tmp, offset); |
970 add(tmp, tmp, offset); |
971 |
971 |
972 return RegisterOrConstant(tmp); |
972 return RegisterOrConstant(tmp); |
973 } |
|
974 |
|
975 |
|
976 void MacroAssembler:: notify(int type) { |
|
977 if (type == bytecode_start) { |
|
978 // set_last_Java_frame(esp, rfp, (address)NULL); |
|
979 Assembler:: notify(type); |
|
980 // reset_last_Java_frame(true); |
|
981 } |
|
982 else |
|
983 Assembler:: notify(type); |
|
984 } |
973 } |
985 |
974 |
986 // Look up the method for a megamorphic invokeinterface call. |
975 // Look up the method for a megamorphic invokeinterface call. |
987 // The target method is determined by <intf_klass, itable_index>. |
976 // The target method is determined by <intf_klass, itable_index>. |
988 // The receiver klass is in recv_klass. |
977 // The receiver klass is in recv_klass. |
1305 #undef IS_A_TEMP |
1294 #undef IS_A_TEMP |
1306 |
1295 |
1307 bind(L_fallthrough); |
1296 bind(L_fallthrough); |
1308 } |
1297 } |
1309 |
1298 |
|
1299 void MacroAssembler::clinit_barrier(Register klass, Register scratch, Label* L_fast_path, Label* L_slow_path) { |
|
1300 assert(L_fast_path != NULL || L_slow_path != NULL, "at least one is required"); |
|
1301 assert_different_registers(klass, rthread, scratch); |
|
1302 |
|
1303 Label L_fallthrough, L_tmp; |
|
1304 if (L_fast_path == NULL) { |
|
1305 L_fast_path = &L_fallthrough; |
|
1306 } else if (L_slow_path == NULL) { |
|
1307 L_slow_path = &L_fallthrough; |
|
1308 } |
|
1309 // Fast path check: class is fully initialized |
|
1310 ldrb(scratch, Address(klass, InstanceKlass::init_state_offset())); |
|
1311 subs(zr, scratch, InstanceKlass::fully_initialized); |
|
1312 br(Assembler::EQ, *L_fast_path); |
|
1313 |
|
1314 // Fast path check: current thread is initializer thread |
|
1315 ldr(scratch, Address(klass, InstanceKlass::init_thread_offset())); |
|
1316 cmp(rthread, scratch); |
|
1317 |
|
1318 if (L_slow_path == &L_fallthrough) { |
|
1319 br(Assembler::EQ, *L_fast_path); |
|
1320 bind(*L_slow_path); |
|
1321 } else if (L_fast_path == &L_fallthrough) { |
|
1322 br(Assembler::NE, *L_slow_path); |
|
1323 bind(*L_fast_path); |
|
1324 } else { |
|
1325 Unimplemented(); |
|
1326 } |
|
1327 } |
1310 |
1328 |
1311 void MacroAssembler::verify_oop(Register reg, const char* s) { |
1329 void MacroAssembler::verify_oop(Register reg, const char* s) { |
1312 if (!VerifyOops) return; |
1330 if (!VerifyOops) return; |
1313 |
1331 |
1314 // Pass register number to verify_oop_subroutine |
1332 // Pass register number to verify_oop_subroutine |
1394 } |
1412 } |
1395 |
1413 |
1396 void MacroAssembler::call_VM_leaf_base(address entry_point, |
1414 void MacroAssembler::call_VM_leaf_base(address entry_point, |
1397 int number_of_arguments, |
1415 int number_of_arguments, |
1398 Label *retaddr) { |
1416 Label *retaddr) { |
1399 call_VM_leaf_base1(entry_point, number_of_arguments, 0, ret_type_integral, retaddr); |
|
1400 } |
|
1401 |
|
1402 void MacroAssembler::call_VM_leaf_base1(address entry_point, |
|
1403 int number_of_gp_arguments, |
|
1404 int number_of_fp_arguments, |
|
1405 ret_type type, |
|
1406 Label *retaddr) { |
|
1407 Label E, L; |
1417 Label E, L; |
1408 |
1418 |
1409 stp(rscratch1, rmethod, Address(pre(sp, -2 * wordSize))); |
1419 stp(rscratch1, rmethod, Address(pre(sp, -2 * wordSize))); |
1410 |
1420 |
1411 // We add 1 to number_of_arguments because the thread in arg0 is |
|
1412 // not counted |
|
1413 mov(rscratch1, entry_point); |
1421 mov(rscratch1, entry_point); |
1414 blrt(rscratch1, number_of_gp_arguments + 1, number_of_fp_arguments, type); |
1422 blr(rscratch1); |
1415 if (retaddr) |
1423 if (retaddr) |
1416 bind(*retaddr); |
1424 bind(*retaddr); |
1417 |
1425 |
1418 ldp(rscratch1, rmethod, Address(post(sp, 2 * wordSize))); |
1426 ldp(rscratch1, rmethod, Address(post(sp, 2 * wordSize))); |
1419 maybe_isb(); |
1427 maybe_isb(); |
2122 |
2130 |
2123 assert(words_pushed == count, "oops, pushed != count"); |
2131 assert(words_pushed == count, "oops, pushed != count"); |
2124 |
2132 |
2125 return count; |
2133 return count; |
2126 } |
2134 } |
|
2135 |
|
2136 // Push lots of registers in the bit set supplied. Don't push sp. |
|
2137 // Return the number of words pushed |
|
2138 int MacroAssembler::push_fp(unsigned int bitset, Register stack) { |
|
2139 int words_pushed = 0; |
|
2140 |
|
2141 // Scan bitset to accumulate register pairs |
|
2142 unsigned char regs[32]; |
|
2143 int count = 0; |
|
2144 for (int reg = 0; reg <= 31; reg++) { |
|
2145 if (1 & bitset) |
|
2146 regs[count++] = reg; |
|
2147 bitset >>= 1; |
|
2148 } |
|
2149 regs[count++] = zr->encoding_nocheck(); |
|
2150 count &= ~1; // Only push an even number of regs |
|
2151 |
|
2152 // Always pushing full 128 bit registers. |
|
2153 if (count) { |
|
2154 stpq(as_FloatRegister(regs[0]), as_FloatRegister(regs[1]), Address(pre(stack, -count * wordSize * 2))); |
|
2155 words_pushed += 2; |
|
2156 } |
|
2157 for (int i = 2; i < count; i += 2) { |
|
2158 stpq(as_FloatRegister(regs[i]), as_FloatRegister(regs[i+1]), Address(stack, i * wordSize * 2)); |
|
2159 words_pushed += 2; |
|
2160 } |
|
2161 |
|
2162 assert(words_pushed == count, "oops, pushed != count"); |
|
2163 return count; |
|
2164 } |
|
2165 |
|
2166 int MacroAssembler::pop_fp(unsigned int bitset, Register stack) { |
|
2167 int words_pushed = 0; |
|
2168 |
|
2169 // Scan bitset to accumulate register pairs |
|
2170 unsigned char regs[32]; |
|
2171 int count = 0; |
|
2172 for (int reg = 0; reg <= 31; reg++) { |
|
2173 if (1 & bitset) |
|
2174 regs[count++] = reg; |
|
2175 bitset >>= 1; |
|
2176 } |
|
2177 regs[count++] = zr->encoding_nocheck(); |
|
2178 count &= ~1; |
|
2179 |
|
2180 for (int i = 2; i < count; i += 2) { |
|
2181 ldpq(as_FloatRegister(regs[i]), as_FloatRegister(regs[i+1]), Address(stack, i * wordSize * 2)); |
|
2182 words_pushed += 2; |
|
2183 } |
|
2184 if (count) { |
|
2185 ldpq(as_FloatRegister(regs[0]), as_FloatRegister(regs[1]), Address(post(stack, count * wordSize * 2))); |
|
2186 words_pushed += 2; |
|
2187 } |
|
2188 |
|
2189 assert(words_pushed == count, "oops, pushed != count"); |
|
2190 |
|
2191 return count; |
|
2192 } |
|
2193 |
2127 #ifdef ASSERT |
2194 #ifdef ASSERT |
2128 void MacroAssembler::verify_heapbase(const char* msg) { |
2195 void MacroAssembler::verify_heapbase(const char* msg) { |
2129 #if 0 |
2196 #if 0 |
2130 assert (UseCompressedOops || UseCompressedClassPointers, "should be compressed"); |
2197 assert (UseCompressedOops || UseCompressedClassPointers, "should be compressed"); |
2131 assert (Universe::heap() != NULL, "java heap should be initialized"); |
2198 assert (Universe::heap() != NULL, "java heap should be initialized"); |
2167 pusha(); |
2234 pusha(); |
2168 mov(c_rarg0, (address)msg); |
2235 mov(c_rarg0, (address)msg); |
2169 mov(c_rarg1, (address)ip); |
2236 mov(c_rarg1, (address)ip); |
2170 mov(c_rarg2, sp); |
2237 mov(c_rarg2, sp); |
2171 mov(c_rarg3, CAST_FROM_FN_PTR(address, MacroAssembler::debug64)); |
2238 mov(c_rarg3, CAST_FROM_FN_PTR(address, MacroAssembler::debug64)); |
2172 // call(c_rarg3); |
2239 blr(c_rarg3); |
2173 blrt(c_rarg3, 3, 0, 1); |
|
2174 hlt(0); |
2240 hlt(0); |
2175 } |
2241 } |
2176 |
2242 |
2177 void MacroAssembler::warn(const char* msg) { |
2243 void MacroAssembler::warn(const char* msg) { |
2178 pusha(); |
2244 pusha(); |
2179 mov(c_rarg0, (address)msg); |
2245 mov(c_rarg0, (address)msg); |
2180 mov(lr, CAST_FROM_FN_PTR(address, warning)); |
2246 mov(lr, CAST_FROM_FN_PTR(address, warning)); |
2181 blrt(lr, 1, 0, MacroAssembler::ret_type_void); |
2247 blr(lr); |
2182 popa(); |
2248 popa(); |
2183 } |
2249 } |
2184 |
2250 |
2185 void MacroAssembler::unimplemented(const char* what) { |
2251 void MacroAssembler::unimplemented(const char* what) { |
2186 const char* buf = NULL; |
2252 const char* buf = NULL; |
2548 tty->print_cr("r28 = 0x%016lx", regs[28]); |
2614 tty->print_cr("r28 = 0x%016lx", regs[28]); |
2549 tty->print_cr("r30 = 0x%016lx", regs[30]); |
2615 tty->print_cr("r30 = 0x%016lx", regs[30]); |
2550 tty->print_cr("r31 = 0x%016lx", regs[31]); |
2616 tty->print_cr("r31 = 0x%016lx", regs[31]); |
2551 BREAKPOINT; |
2617 BREAKPOINT; |
2552 } |
2618 } |
2553 ThreadStateTransition::transition(thread, _thread_in_vm, saved_state); |
2619 } |
2554 } else { |
2620 fatal("DEBUG MESSAGE: %s", msg); |
2555 ttyLocker ttyl; |
2621 } |
2556 ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", |
|
2557 msg); |
|
2558 assert(false, "DEBUG MESSAGE: %s", msg); |
|
2559 } |
|
2560 } |
|
2561 |
|
2562 #ifdef BUILTIN_SIM |
|
2563 // routine to generate an x86 prolog for a stub function which |
|
2564 // bootstraps into the generated ARM code which directly follows the |
|
2565 // stub |
|
2566 // |
|
2567 // the argument encodes the number of general and fp registers |
|
2568 // passed by the caller and the callng convention (currently just |
|
2569 // the number of general registers and assumes C argument passing) |
|
2570 |
|
2571 extern "C" { |
|
2572 int aarch64_stub_prolog_size(); |
|
2573 void aarch64_stub_prolog(); |
|
2574 void aarch64_prolog(); |
|
2575 } |
|
2576 |
|
2577 void MacroAssembler::c_stub_prolog(int gp_arg_count, int fp_arg_count, int ret_type, |
|
2578 address *prolog_ptr) |
|
2579 { |
|
2580 int calltype = (((ret_type & 0x3) << 8) | |
|
2581 ((fp_arg_count & 0xf) << 4) | |
|
2582 (gp_arg_count & 0xf)); |
|
2583 |
|
2584 // the addresses for the x86 to ARM entry code we need to use |
|
2585 address start = pc(); |
|
2586 // printf("start = %lx\n", start); |
|
2587 int byteCount = aarch64_stub_prolog_size(); |
|
2588 // printf("byteCount = %x\n", byteCount); |
|
2589 int instructionCount = (byteCount + 3)/ 4; |
|
2590 // printf("instructionCount = %x\n", instructionCount); |
|
2591 for (int i = 0; i < instructionCount; i++) { |
|
2592 nop(); |
|
2593 } |
|
2594 |
|
2595 memcpy(start, (void*)aarch64_stub_prolog, byteCount); |
|
2596 |
|
2597 // write the address of the setup routine and the call format at the |
|
2598 // end of into the copied code |
|
2599 u_int64_t *patch_end = (u_int64_t *)(start + byteCount); |
|
2600 if (prolog_ptr) |
|
2601 patch_end[-2] = (u_int64_t)prolog_ptr; |
|
2602 patch_end[-1] = calltype; |
|
2603 } |
|
2604 #endif |
|
2605 |
2622 |
2606 void MacroAssembler::push_call_clobbered_registers() { |
2623 void MacroAssembler::push_call_clobbered_registers() { |
2607 int step = 4 * wordSize; |
2624 int step = 4 * wordSize; |
2608 push(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2), sp); |
2625 push(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2), sp); |
2609 sub(sp, sp, step); |
2626 sub(sp, sp, step); |
2679 // Aligned - 12 bits unsigned offset shifted |
2696 // Aligned - 12 bits unsigned offset shifted |
2680 Register base = sp; |
2697 Register base = sp; |
2681 if ((offset & (size-1)) && offset >= (1<<8)) { |
2698 if ((offset & (size-1)) && offset >= (1<<8)) { |
2682 add(tmp, base, offset & ((1<<12)-1)); |
2699 add(tmp, base, offset & ((1<<12)-1)); |
2683 base = tmp; |
2700 base = tmp; |
2684 offset &= -1<<12; |
2701 offset &= -1u<<12; |
2685 } |
2702 } |
2686 |
2703 |
2687 if (offset >= (1<<12) * size) { |
2704 if (offset >= (1<<12) * size) { |
2688 add(tmp, base, offset & (((1<<12)-1)<<12)); |
2705 add(tmp, base, offset & (((1<<12)-1)<<12)); |
2689 base = tmp; |
2706 base = tmp; |
3681 void MacroAssembler::cmpoop(Register obj1, Register obj2) { |
3698 void MacroAssembler::cmpoop(Register obj1, Register obj2) { |
3682 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); |
3699 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); |
3683 bs->obj_equals(this, obj1, obj2); |
3700 bs->obj_equals(this, obj1, obj2); |
3684 } |
3701 } |
3685 |
3702 |
|
3703 void MacroAssembler::load_method_holder(Register holder, Register method) { |
|
3704 ldr(holder, Address(method, Method::const_offset())); // ConstMethod* |
|
3705 ldr(holder, Address(holder, ConstMethod::constants_offset())); // ConstantPool* |
|
3706 ldr(holder, Address(holder, ConstantPool::pool_holder_offset_in_bytes())); // InstanceKlass* |
|
3707 } |
|
3708 |
3686 void MacroAssembler::load_klass(Register dst, Register src) { |
3709 void MacroAssembler::load_klass(Register dst, Register src) { |
3687 if (UseCompressedClassPointers) { |
3710 if (UseCompressedClassPointers) { |
3688 ldrw(dst, Address(src, oopDesc::klass_offset_in_bytes())); |
3711 ldrw(dst, Address(src, oopDesc::klass_offset_in_bytes())); |
3689 decode_klass_not_null(dst); |
3712 decode_klass_not_null(dst); |
3690 } else { |
3713 } else { |
3982 { |
4005 { |
3983 ThreadInVMfromUnknown tiv; |
4006 ThreadInVMfromUnknown tiv; |
3984 assert (UseCompressedOops, "should only be used for compressed oops"); |
4007 assert (UseCompressedOops, "should only be used for compressed oops"); |
3985 assert (Universe::heap() != NULL, "java heap should be initialized"); |
4008 assert (Universe::heap() != NULL, "java heap should be initialized"); |
3986 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); |
4009 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); |
3987 assert(Universe::heap()->is_in_reserved(JNIHandles::resolve(obj)), "should be real oop"); |
4010 assert(Universe::heap()->is_in(JNIHandles::resolve(obj)), "should be real oop"); |
3988 } |
4011 } |
3989 #endif |
4012 #endif |
3990 int oop_index = oop_recorder()->find_index(obj); |
4013 int oop_index = oop_recorder()->find_index(obj); |
3991 InstructionMark im(this); |
4014 InstructionMark im(this); |
3992 RelocationHolder rspec = oop_Relocation::spec(oop_index); |
4015 RelocationHolder rspec = oop_Relocation::spec(oop_index); |
3997 |
4020 |
3998 void MacroAssembler::set_narrow_klass(Register dst, Klass* k) { |
4021 void MacroAssembler::set_narrow_klass(Register dst, Klass* k) { |
3999 assert (UseCompressedClassPointers, "should only be used for compressed headers"); |
4022 assert (UseCompressedClassPointers, "should only be used for compressed headers"); |
4000 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); |
4023 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); |
4001 int index = oop_recorder()->find_index(k); |
4024 int index = oop_recorder()->find_index(k); |
4002 assert(! Universe::heap()->is_in_reserved(k), "should not be an oop"); |
4025 assert(! Universe::heap()->is_in(k), "should not be an oop"); |
4003 |
4026 |
4004 InstructionMark im(this); |
4027 InstructionMark im(this); |
4005 RelocationHolder rspec = metadata_Relocation::spec(index); |
4028 RelocationHolder rspec = metadata_Relocation::spec(index); |
4006 code_section()->relocate(inst_mark(), rspec); |
4029 code_section()->relocate(inst_mark(), rspec); |
4007 narrowKlass nk = CompressedKlassPointers::encode(k); |
4030 narrowKlass nk = CompressedKlassPointers::encode(k); |
4081 oop_index = oop_recorder()->allocate_oop_index(obj); |
4104 oop_index = oop_recorder()->allocate_oop_index(obj); |
4082 } else { |
4105 } else { |
4083 #ifdef ASSERT |
4106 #ifdef ASSERT |
4084 { |
4107 { |
4085 ThreadInVMfromUnknown tiv; |
4108 ThreadInVMfromUnknown tiv; |
4086 assert(Universe::heap()->is_in_reserved(JNIHandles::resolve(obj)), "should be real oop"); |
4109 assert(Universe::heap()->is_in(JNIHandles::resolve(obj)), "should be real oop"); |
4087 } |
4110 } |
4088 #endif |
4111 #endif |
4089 oop_index = oop_recorder()->find_index(obj); |
4112 oop_index = oop_recorder()->find_index(obj); |
4090 } |
4113 } |
4091 RelocationHolder rspec = oop_Relocation::spec(oop_index); |
4114 RelocationHolder rspec = oop_Relocation::spec(oop_index); |
4111 Address MacroAssembler::constant_oop_address(jobject obj) { |
4134 Address MacroAssembler::constant_oop_address(jobject obj) { |
4112 #ifdef ASSERT |
4135 #ifdef ASSERT |
4113 { |
4136 { |
4114 ThreadInVMfromUnknown tiv; |
4137 ThreadInVMfromUnknown tiv; |
4115 assert(oop_recorder() != NULL, "this assembler needs an OopRecorder"); |
4138 assert(oop_recorder() != NULL, "this assembler needs an OopRecorder"); |
4116 assert(Universe::heap()->is_in_reserved(JNIHandles::resolve(obj)), "not an oop"); |
4139 assert(Universe::heap()->is_in(JNIHandles::resolve(obj)), "not an oop"); |
4117 } |
4140 } |
4118 #endif |
4141 #endif |
4119 int oop_index = oop_recorder()->find_index(obj); |
4142 int oop_index = oop_recorder()->find_index(obj); |
4120 return Address((address)obj, oop_Relocation::spec(oop_index)); |
4143 return Address((address)obj, oop_Relocation::spec(oop_index)); |
4121 } |
4144 } |
5641 NEXT_32_START, NEXT_32_PRFM_START; |
5664 NEXT_32_START, NEXT_32_PRFM_START; |
5642 Register tmp1 = rscratch1, tmp2 = rscratch2; |
5665 Register tmp1 = rscratch1, tmp2 = rscratch2; |
5643 |
5666 |
5644 mov(result, len); // Save initial len |
5667 mov(result, len); // Save initial len |
5645 |
5668 |
5646 #ifndef BUILTIN_SIM |
|
5647 cmp(len, (u1)8); // handle shortest strings first |
5669 cmp(len, (u1)8); // handle shortest strings first |
5648 br(LT, LOOP_1); |
5670 br(LT, LOOP_1); |
5649 cmp(len, (u1)32); |
5671 cmp(len, (u1)32); |
5650 br(LT, NEXT_8); |
5672 br(LT, NEXT_8); |
5651 // The following code uses the SIMD 'uzp1' and 'uzp2' instructions |
5673 // The following code uses the SIMD 'uzp1' and 'uzp2' instructions |
5856 void MacroAssembler::get_thread(Register dst) { |
5878 void MacroAssembler::get_thread(Register dst) { |
5857 RegSet saved_regs = RegSet::range(r0, r1) + lr - dst; |
5879 RegSet saved_regs = RegSet::range(r0, r1) + lr - dst; |
5858 push(saved_regs, sp); |
5880 push(saved_regs, sp); |
5859 |
5881 |
5860 mov(lr, CAST_FROM_FN_PTR(address, JavaThread::aarch64_get_thread_helper)); |
5882 mov(lr, CAST_FROM_FN_PTR(address, JavaThread::aarch64_get_thread_helper)); |
5861 blrt(lr, 1, 0, 1); |
5883 blr(lr); |
5862 if (dst != c_rarg0) { |
5884 if (dst != c_rarg0) { |
5863 mov(dst, c_rarg0); |
5885 mov(dst, c_rarg0); |
5864 } |
5886 } |
5865 |
5887 |
5866 pop(saved_regs, sp); |
5888 pop(saved_regs, sp); |
5867 } |
5889 } |
|
5890 |
|
5891 void MacroAssembler::cache_wb(Address line) { |
|
5892 assert(line.getMode() == Address::base_plus_offset, "mode should be base_plus_offset"); |
|
5893 assert(line.index() == noreg, "index should be noreg"); |
|
5894 assert(line.offset() == 0, "offset should be 0"); |
|
5895 // would like to assert this |
|
5896 // assert(line._ext.shift == 0, "shift should be zero"); |
|
5897 if (VM_Version::supports_dcpop()) { |
|
5898 // writeback using clear virtual address to point of persistence |
|
5899 dc(Assembler::CVAP, line.base()); |
|
5900 } else { |
|
5901 // no need to generate anything as Unsafe.writebackMemory should |
|
5902 // never invoke this stub |
|
5903 } |
|
5904 } |
|
5905 |
|
5906 void MacroAssembler::cache_wbsync(bool is_pre) { |
|
5907 // we only need a barrier post sync |
|
5908 if (!is_pre) { |
|
5909 membar(Assembler::AnyAny); |
|
5910 } |
|
5911 } |