44 // - - NativeReturn
45 // - - NativeReturnX (return with argument)
46 // - - NativePushConst
47 // - - NativeTstRegMem
48
49 // The base class for different kinds of native instruction abstractions.
50 // Provides the primitive operations to manipulate code relative to this.
51
52 class NativeInstruction VALUE_OBJ_CLASS_SPEC {
53 friend class Relocation;
54 friend bool is_NativeCallTrampolineStub_at(address);
55 public:
56 enum {
57 instruction_size = 4
58 };
59
60 juint encoding() const {
61 return uint_at(0);
62 }
63
64 bool is_blr() const { return (encoding() & 0xfffffc1f) == 0xd63f0000; }
65 bool is_adr_aligned() const { return (encoding() & 0xff000000) == 0x10000000; } // adr Xn, <label>, where label is aligned to 4 bytes (address of instruction).
66
67 inline bool is_nop();
68 inline bool is_illegal();
69 inline bool is_return();
70 bool is_jump();
71 bool is_general_jump();
72 inline bool is_jump_or_nop();
73 inline bool is_cond_jump();
74 bool is_safepoint_poll();
75 bool is_movz();
76 bool is_movk();
77 bool is_sigill_zombie_not_entrant();
78
79 protected:
80 address addr_at(int offset) const { return address(this) + offset; }
81
82 s_char sbyte_at(int offset) const { return *(s_char*) addr_at(offset); }
83 u_char ubyte_at(int offset) const { return *(u_char*) addr_at(offset); }
84
126 return is_adrp_at(instr) || is_ldr_literal_at(instr);
127 }
128
129 bool is_Membar() {
130 unsigned int insn = uint_at(0);
131 return Instruction_aarch64::extract(insn, 31, 12) == 0b11010101000000110011 &&
132 Instruction_aarch64::extract(insn, 7, 0) == 0b10111111;
133 }
134 };
135
136 inline NativeInstruction* nativeInstruction_at(address address) {
137 return (NativeInstruction*)address;
138 }
139
140 // The natural type of an AArch64 instruction is uint32_t
141 inline NativeInstruction* nativeInstruction_at(uint32_t *address) {
142 return (NativeInstruction*)address;
143 }
144
145 inline NativeCall* nativeCall_at(address address);
146 // The NativeCall is an abstraction for accessing/manipulating native call imm32/rel32off
147 // instructions (used to manipulate inline caches, primitive & dll calls, etc.).
148
149 class NativeCall: public NativeInstruction {
150 public:
151 enum Aarch64_specific_constants {
152 instruction_size = 4,
153 instruction_offset = 0,
154 displacement_offset = 0,
155 return_address_offset = 4
156 };
157
158 enum { cache_line_size = BytesPerWord }; // conservative estimate!
159 address instruction_address() const { return addr_at(instruction_offset); }
160 address next_instruction_address() const { return addr_at(return_address_offset); }
161 int displacement() const { return (int_at(displacement_offset) << 6) >> 4; }
162 address displacement_address() const { return addr_at(displacement_offset); }
163 address return_address() const { return addr_at(return_address_offset); }
164 address destination() const;
165
166 void set_destination(address dest) {
167 int offset = dest - instruction_address();
168 unsigned int insn = 0b100101 << 26;
169 assert((offset & 3) == 0, "should be");
170 offset >>= 2;
171 offset &= (1 << 26) - 1; // mask off insn part
172 insn |= offset;
173 set_int_at(displacement_offset, insn);
174 }
175
176 void verify_alignment() { ; }
177 void verify();
178 void print();
189 static void insert(address code_pos, address entry);
190
191 static void replace_mt_safe(address instr_addr, address code_buffer);
192
193 // Similar to replace_mt_safe, but just changes the destination. The
194 // important thing is that free-running threads are able to execute
195 // this call instruction at all times. If the call is an immediate BL
196 // instruction we can simply rely on atomicity of 32-bit writes to
197 // make sure other threads will see no intermediate states.
198
199 // We cannot rely on locks here, since the free-running threads must run at
200 // full speed.
201 //
202 // Used in the runtime linkage of calls; see class CompiledIC.
203 // (Cf. 4506997 and 4479829, where threads witnessed garbage displacements.)
204
205 // The parameter assert_lock disables the assertion during code generation.
206 void set_destination_mt_safe(address dest, bool assert_lock = true);
207
208 address get_trampoline();
209 };
210
211 inline NativeCall* nativeCall_at(address address) {
212 NativeCall* call = (NativeCall*)(address - NativeCall::instruction_offset);
213 #ifdef ASSERT
214 call->verify();
215 #endif
216 return call;
217 }
218
219 inline NativeCall* nativeCall_before(address return_address) {
220 NativeCall* call = (NativeCall*)(return_address - NativeCall::return_address_offset);
221 #ifdef ASSERT
222 call->verify();
223 #endif
224 return call;
225 }
226
227 // An interface for accessing/manipulating native mov reg, imm instructions.
228 // (used to manipulate inlined 64-bit data calls, etc.)
|
44 // - - NativeReturn
45 // - - NativeReturnX (return with argument)
46 // - - NativePushConst
47 // - - NativeTstRegMem
48
49 // The base class for different kinds of native instruction abstractions.
50 // Provides the primitive operations to manipulate code relative to this.
51
52 class NativeInstruction VALUE_OBJ_CLASS_SPEC {
53 friend class Relocation;
54 friend bool is_NativeCallTrampolineStub_at(address);
55 public:
56 enum {
57 instruction_size = 4
58 };
59
60 juint encoding() const {
61 return uint_at(0);
62 }
63
64 bool is_blr() const { return (encoding() & 0xff9ffc1f) == 0xd61f0000; } // blr(register) or br(register)
65 bool is_adr_aligned() const { return (encoding() & 0xff000000) == 0x10000000; } // adr Xn, <label>, where label is aligned to 4 bytes (address of instruction).
66
67 inline bool is_nop();
68 inline bool is_illegal();
69 inline bool is_return();
70 bool is_jump();
71 bool is_general_jump();
72 inline bool is_jump_or_nop();
73 inline bool is_cond_jump();
74 bool is_safepoint_poll();
75 bool is_movz();
76 bool is_movk();
77 bool is_sigill_zombie_not_entrant();
78
79 protected:
80 address addr_at(int offset) const { return address(this) + offset; }
81
82 s_char sbyte_at(int offset) const { return *(s_char*) addr_at(offset); }
83 u_char ubyte_at(int offset) const { return *(u_char*) addr_at(offset); }
84
126 return is_adrp_at(instr) || is_ldr_literal_at(instr);
127 }
128
129 bool is_Membar() {
130 unsigned int insn = uint_at(0);
131 return Instruction_aarch64::extract(insn, 31, 12) == 0b11010101000000110011 &&
132 Instruction_aarch64::extract(insn, 7, 0) == 0b10111111;
133 }
134 };
135
136 inline NativeInstruction* nativeInstruction_at(address address) {
137 return (NativeInstruction*)address;
138 }
139
140 // The natural type of an AArch64 instruction is uint32_t
141 inline NativeInstruction* nativeInstruction_at(uint32_t *address) {
142 return (NativeInstruction*)address;
143 }
144
145 inline NativeCall* nativeCall_at(address address);
146 // The NativeCall is an abstraction for accessing/manipulating native
147 // call instructions (used to manipulate inline caches, primitive &
148 // DSO calls, etc.).
149
150 class NativeCall: public NativeInstruction {
151 public:
152 enum Aarch64_specific_constants {
153 instruction_size = 4,
154 instruction_offset = 0,
155 displacement_offset = 0,
156 return_address_offset = 4
157 };
158
159 address instruction_address() const { return addr_at(instruction_offset); }
160 address next_instruction_address() const { return addr_at(return_address_offset); }
161 int displacement() const { return (int_at(displacement_offset) << 6) >> 4; }
162 address displacement_address() const { return addr_at(displacement_offset); }
163 address return_address() const { return addr_at(return_address_offset); }
164 address destination() const;
165
166 void set_destination(address dest) {
167 int offset = dest - instruction_address();
168 unsigned int insn = 0b100101 << 26;
169 assert((offset & 3) == 0, "should be");
170 offset >>= 2;
171 offset &= (1 << 26) - 1; // mask off insn part
172 insn |= offset;
173 set_int_at(displacement_offset, insn);
174 }
175
176 void verify_alignment() { ; }
177 void verify();
178 void print();
189 static void insert(address code_pos, address entry);
190
191 static void replace_mt_safe(address instr_addr, address code_buffer);
192
193 // Similar to replace_mt_safe, but just changes the destination. The
194 // important thing is that free-running threads are able to execute
195 // this call instruction at all times. If the call is an immediate BL
196 // instruction we can simply rely on atomicity of 32-bit writes to
197 // make sure other threads will see no intermediate states.
198
199 // We cannot rely on locks here, since the free-running threads must run at
200 // full speed.
201 //
202 // Used in the runtime linkage of calls; see class CompiledIC.
203 // (Cf. 4506997 and 4479829, where threads witnessed garbage displacements.)
204
205 // The parameter assert_lock disables the assertion during code generation.
206 void set_destination_mt_safe(address dest, bool assert_lock = true);
207
208 address get_trampoline();
209 address trampoline_jump(CodeBuffer &cbuf, address dest);
210 };
211
212 inline NativeCall* nativeCall_at(address address) {
213 NativeCall* call = (NativeCall*)(address - NativeCall::instruction_offset);
214 #ifdef ASSERT
215 call->verify();
216 #endif
217 return call;
218 }
219
220 inline NativeCall* nativeCall_before(address return_address) {
221 NativeCall* call = (NativeCall*)(return_address - NativeCall::return_address_offset);
222 #ifdef ASSERT
223 call->verify();
224 #endif
225 return call;
226 }
227
228 // An interface for accessing/manipulating native mov reg, imm instructions.
229 // (used to manipulate inlined 64-bit data calls, etc.)
|