18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #include <sys/types.h>
27
28 #include "precompiled.hpp"
29 #include "jvm.h"
30 #include "asm/assembler.hpp"
31 #include "asm/assembler.inline.hpp"
32 #include "gc/shared/cardTable.hpp"
33 #include "gc/shared/cardTableModRefBS.hpp"
34 #include "interpreter/interpreter.hpp"
35 #include "compiler/disassembler.hpp"
36 #include "memory/resourceArea.hpp"
37 #include "nativeInst_aarch64.hpp"
38 #include "oops/klass.inline.hpp"
39 #include "oops/oop.inline.hpp"
40 #include "opto/compile.hpp"
41 #include "opto/intrinsicnode.hpp"
42 #include "opto/node.hpp"
43 #include "runtime/biasedLocking.hpp"
44 #include "runtime/icache.hpp"
45 #include "runtime/interfaceSupport.inline.hpp"
46 #include "runtime/jniHandles.inline.hpp"
47 #include "runtime/sharedRuntime.hpp"
48 #include "runtime/thread.hpp"
49
50 #if INCLUDE_ALL_GCS
51 #include "gc/g1/g1BarrierSet.hpp"
52 #include "gc/g1/g1CardTable.hpp"
53 #include "gc/g1/g1CollectedHeap.inline.hpp"
54 #include "gc/g1/heapRegion.hpp"
55 #endif
56
57 #ifdef PRODUCT
58 #define BLOCK_COMMENT(str) /* nothing */
59 #define STOP(error) stop(error)
60 #else
61 #define BLOCK_COMMENT(str) block_comment(str)
62 #define STOP(error) block_comment(error); stop(error)
63 #endif
64
65 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
66
67 // Patch any kind of instruction; there may be several instructions.
68 // Return the total length (in bytes) of the instructions.
69 int MacroAssembler::pd_patch_instruction_size(address branch, address target) {
156 } else if (Instruction_aarch64::extract(insn, 31, 22) == 0b1011100101 &&
157 Instruction_aarch64::extract(insn, 4, 0) == 0b11111) {
158 // nothing to do
159 assert(target == 0, "did not expect to relocate target for polling page load");
160 } else {
161 ShouldNotReachHere();
162 }
163 return instructions * NativeInstruction::instruction_size;
164 }
165
166 int MacroAssembler::patch_oop(address insn_addr, address o) {
167 int instructions;
168 unsigned insn = *(unsigned*)insn_addr;
169 assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
170
171 // OOPs are either narrow (32 bits) or wide (48 bits). We encode
172 // narrow OOPs by setting the upper 16 bits in the first
173 // instruction.
174 if (Instruction_aarch64::extract(insn, 31, 21) == 0b11010010101) {
175 // Move narrow OOP
176 narrowOop n = oopDesc::encode_heap_oop((oop)o);
177 Instruction_aarch64::patch(insn_addr, 20, 5, n >> 16);
178 Instruction_aarch64::patch(insn_addr+4, 20, 5, n & 0xffff);
179 instructions = 2;
180 } else {
181 // Move wide OOP
182 assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
183 uintptr_t dest = (uintptr_t)o;
184 Instruction_aarch64::patch(insn_addr, 20, 5, dest & 0xffff);
185 Instruction_aarch64::patch(insn_addr+4, 20, 5, (dest >>= 16) & 0xffff);
186 Instruction_aarch64::patch(insn_addr+8, 20, 5, (dest >>= 16) & 0xffff);
187 instructions = 3;
188 }
189 return instructions * NativeInstruction::instruction_size;
190 }
191
192 int MacroAssembler::patch_narrow_klass(address insn_addr, narrowKlass n) {
193 // Metatdata pointers are either narrow (32 bits) or wide (48 bits).
194 // We encode narrow ones by setting the upper 16 bits in the first
195 // instruction.
196 NativeInstruction *insn = nativeInstruction_at(insn_addr);
3695 }
3696
3697 void MacroAssembler::store_klass(Register dst, Register src) {
3698 // FIXME: Should this be a store release? concurrent gcs assumes
3699 // klass length is valid if klass field is not null.
3700 if (UseCompressedClassPointers) {
3701 encode_klass_not_null(src);
3702 strw(src, Address(dst, oopDesc::klass_offset_in_bytes()));
3703 } else {
3704 str(src, Address(dst, oopDesc::klass_offset_in_bytes()));
3705 }
3706 }
3707
3708 void MacroAssembler::store_klass_gap(Register dst, Register src) {
3709 if (UseCompressedClassPointers) {
3710 // Store to klass gap in destination
3711 strw(src, Address(dst, oopDesc::klass_gap_offset_in_bytes()));
3712 }
3713 }
3714
3715 // Algorithm must match oop.inline.hpp encode_heap_oop.
3716 void MacroAssembler::encode_heap_oop(Register d, Register s) {
3717 #ifdef ASSERT
3718 verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?");
3719 #endif
3720 verify_oop(s, "broken oop in encode_heap_oop");
3721 if (Universe::narrow_oop_base() == NULL) {
3722 if (Universe::narrow_oop_shift() != 0) {
3723 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
3724 lsr(d, s, LogMinObjAlignmentInBytes);
3725 } else {
3726 mov(d, s);
3727 }
3728 } else {
3729 subs(d, s, rheapbase);
3730 csel(d, d, zr, Assembler::HS);
3731 lsr(d, d, LogMinObjAlignmentInBytes);
3732
3733 /* Old algorithm: is this any worse?
3734 Label nonnull;
3735 cbnz(r, nonnull);
|
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #include <sys/types.h>
27
28 #include "precompiled.hpp"
29 #include "jvm.h"
30 #include "asm/assembler.hpp"
31 #include "asm/assembler.inline.hpp"
32 #include "gc/shared/cardTable.hpp"
33 #include "gc/shared/cardTableModRefBS.hpp"
34 #include "interpreter/interpreter.hpp"
35 #include "compiler/disassembler.hpp"
36 #include "memory/resourceArea.hpp"
37 #include "nativeInst_aarch64.hpp"
38 #include "oops/compressedOops.inline.hpp"
39 #include "oops/klass.inline.hpp"
40 #include "oops/oop.hpp"
41 #include "opto/compile.hpp"
42 #include "opto/intrinsicnode.hpp"
43 #include "opto/node.hpp"
44 #include "runtime/biasedLocking.hpp"
45 #include "runtime/icache.hpp"
46 #include "runtime/interfaceSupport.inline.hpp"
47 #include "runtime/jniHandles.inline.hpp"
48 #include "runtime/sharedRuntime.hpp"
49 #include "runtime/thread.hpp"
50 #if INCLUDE_ALL_GCS
51 #include "gc/g1/g1BarrierSet.hpp"
52 #include "gc/g1/g1CardTable.hpp"
53 #include "gc/g1/g1CollectedHeap.inline.hpp"
54 #include "gc/g1/heapRegion.hpp"
55 #endif
56
57 #ifdef PRODUCT
58 #define BLOCK_COMMENT(str) /* nothing */
59 #define STOP(error) stop(error)
60 #else
61 #define BLOCK_COMMENT(str) block_comment(str)
62 #define STOP(error) block_comment(error); stop(error)
63 #endif
64
65 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
66
67 // Patch any kind of instruction; there may be several instructions.
68 // Return the total length (in bytes) of the instructions.
69 int MacroAssembler::pd_patch_instruction_size(address branch, address target) {
156 } else if (Instruction_aarch64::extract(insn, 31, 22) == 0b1011100101 &&
157 Instruction_aarch64::extract(insn, 4, 0) == 0b11111) {
158 // nothing to do
159 assert(target == 0, "did not expect to relocate target for polling page load");
160 } else {
161 ShouldNotReachHere();
162 }
163 return instructions * NativeInstruction::instruction_size;
164 }
165
166 int MacroAssembler::patch_oop(address insn_addr, address o) {
167 int instructions;
168 unsigned insn = *(unsigned*)insn_addr;
169 assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
170
171 // OOPs are either narrow (32 bits) or wide (48 bits). We encode
172 // narrow OOPs by setting the upper 16 bits in the first
173 // instruction.
174 if (Instruction_aarch64::extract(insn, 31, 21) == 0b11010010101) {
175 // Move narrow OOP
176 narrowOop n = CompressedOops::encode((oop)o);
177 Instruction_aarch64::patch(insn_addr, 20, 5, n >> 16);
178 Instruction_aarch64::patch(insn_addr+4, 20, 5, n & 0xffff);
179 instructions = 2;
180 } else {
181 // Move wide OOP
182 assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
183 uintptr_t dest = (uintptr_t)o;
184 Instruction_aarch64::patch(insn_addr, 20, 5, dest & 0xffff);
185 Instruction_aarch64::patch(insn_addr+4, 20, 5, (dest >>= 16) & 0xffff);
186 Instruction_aarch64::patch(insn_addr+8, 20, 5, (dest >>= 16) & 0xffff);
187 instructions = 3;
188 }
189 return instructions * NativeInstruction::instruction_size;
190 }
191
192 int MacroAssembler::patch_narrow_klass(address insn_addr, narrowKlass n) {
193 // Metatdata pointers are either narrow (32 bits) or wide (48 bits).
194 // We encode narrow ones by setting the upper 16 bits in the first
195 // instruction.
196 NativeInstruction *insn = nativeInstruction_at(insn_addr);
3695 }
3696
3697 void MacroAssembler::store_klass(Register dst, Register src) {
3698 // FIXME: Should this be a store release? concurrent gcs assumes
3699 // klass length is valid if klass field is not null.
3700 if (UseCompressedClassPointers) {
3701 encode_klass_not_null(src);
3702 strw(src, Address(dst, oopDesc::klass_offset_in_bytes()));
3703 } else {
3704 str(src, Address(dst, oopDesc::klass_offset_in_bytes()));
3705 }
3706 }
3707
3708 void MacroAssembler::store_klass_gap(Register dst, Register src) {
3709 if (UseCompressedClassPointers) {
3710 // Store to klass gap in destination
3711 strw(src, Address(dst, oopDesc::klass_gap_offset_in_bytes()));
3712 }
3713 }
3714
3715 // Algorithm must match CompressedOops::encode.
3716 void MacroAssembler::encode_heap_oop(Register d, Register s) {
3717 #ifdef ASSERT
3718 verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?");
3719 #endif
3720 verify_oop(s, "broken oop in encode_heap_oop");
3721 if (Universe::narrow_oop_base() == NULL) {
3722 if (Universe::narrow_oop_shift() != 0) {
3723 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
3724 lsr(d, s, LogMinObjAlignmentInBytes);
3725 } else {
3726 mov(d, s);
3727 }
3728 } else {
3729 subs(d, s, rheapbase);
3730 csel(d, d, zr, Assembler::HS);
3731 lsr(d, d, LogMinObjAlignmentInBytes);
3732
3733 /* Old algorithm: is this any worse?
3734 Label nonnull;
3735 cbnz(r, nonnull);
|