45 // - - NativeReturn
46 // - - NativeReturnX (return with argument)
47 // - - NativePushConst
48 // - - NativeTstRegMem
49
50 // The base class for different kinds of native instruction abstractions.
51 // Provides the primitive operations to manipulate code relative to this.
52
53 class NativeInstruction VALUE_OBJ_CLASS_SPEC {
54 friend class Relocation;
55 friend bool is_NativeCallTrampolineStub_at(address);
56 public:
57 enum { instruction_size = 4 };
58 inline bool is_nop();
59 inline bool is_illegal();
60 inline bool is_return();
61 bool is_jump();
62 inline bool is_jump_or_nop();
63 inline bool is_cond_jump();
64 bool is_safepoint_poll();
65 inline bool is_mov_literal64();
66 bool is_movz();
67 bool is_movk();
68 bool is_sigill_zombie_not_entrant();
69
70 protected:
71 address addr_at(int offset) const { return address(this) + offset; }
72
73 s_char sbyte_at(int offset) const { return *(s_char*) addr_at(offset); }
74 u_char ubyte_at(int offset) const { return *(u_char*) addr_at(offset); }
75
76 jint int_at(int offset) const { return *(jint*) addr_at(offset); }
77 juint uint_at(int offset) const { return *(juint*) addr_at(offset); }
78
79 address ptr_at(int offset) const { return *(address*) addr_at(offset); }
80
81 oop oop_at (int offset) const { return *(oop*) addr_at(offset); }
82
83
84 void set_char_at(int offset, char c) { *addr_at(offset) = (u_char)c; }
85 void set_int_at(int offset, jint i) { *(jint*)addr_at(offset) = i; }
86 void set_uint_at(int offset, jint i) { *(juint*)addr_at(offset) = i; }
87 void set_ptr_at (int offset, address ptr) { *(address*) addr_at(offset) = ptr; }
88 void set_oop_at (int offset, oop o) { *(oop*) addr_at(offset) = o; }
89
90 public:
91
92 // unit test stuff
93 static void test() {} // override for testing
94
95 inline friend NativeInstruction* nativeInstruction_at(address address);
96
97 static bool is_adrp_at(address instr);
98 static bool is_ldr_literal_at(address instr);
99 static bool is_ldrw_to_zr(address instr);
100
101 static bool maybe_cpool_ref(address instr) {
102 return is_adrp_at(instr) || is_ldr_literal_at(instr);
103 }
104
105 bool is_Membar() {
106 unsigned int insn = uint_at(0);
107 return Instruction_aarch64::extract(insn, 31, 12) == 0b11010101000000110011 &&
108 Instruction_aarch64::extract(insn, 7, 0) == 0b10111111;
109 }
110 };
111
112 inline NativeInstruction* nativeInstruction_at(address address) {
113 return (NativeInstruction*)address;
114 }
115
116 // The natural type of an AArch64 instruction is uint32_t
117 inline NativeInstruction* nativeInstruction_at(uint32_t *address) {
118 return (NativeInstruction*)address;
119 }
120
139 address return_address() const { return addr_at(return_address_offset); }
140 address destination() const;
141
142 void set_destination(address dest) {
143 int offset = dest - instruction_address();
144 unsigned int insn = 0b100101 << 26;
145 assert((offset & 3) == 0, "should be");
146 offset >>= 2;
147 offset &= (1 << 26) - 1; // mask off insn part
148 insn |= offset;
149 set_int_at(displacement_offset, insn);
150 }
151
152 void verify_alignment() { ; }
153 void verify();
154 void print();
155
156 // Creation
157 inline friend NativeCall* nativeCall_at(address address);
158 inline friend NativeCall* nativeCall_before(address return_address);
159
160 static bool is_call_at(address instr) {
161 const uint32_t insn = (*(uint32_t*)instr);
162 return (insn >> 26) == 0b100101;
163 }
164
165 static bool is_call_before(address return_address) {
166 return is_call_at(return_address - NativeCall::return_address_offset);
167 }
168
169 // MT-safe patching of a call instruction.
170 static void insert(address code_pos, address entry);
171
172 static void replace_mt_safe(address instr_addr, address code_buffer);
173
174 // Similar to replace_mt_safe, but just changes the destination. The
175 // important thing is that free-running threads are able to execute
176 // this call instruction at all times. If the call is an immediate BL
177 // instruction we can simply rely on atomicity of 32-bit writes to
178 // make sure other threads will see no intermediate states.
179
180 // We cannot rely on locks here, since the free-running threads must run at
181 // full speed.
182 //
183 // Used in the runtime linkage of calls; see class CompiledIC.
|
45 // - - NativeReturn
46 // - - NativeReturnX (return with argument)
47 // - - NativePushConst
48 // - - NativeTstRegMem
49
50 // The base class for different kinds of native instruction abstractions.
51 // Provides the primitive operations to manipulate code relative to this.
52
53 class NativeInstruction VALUE_OBJ_CLASS_SPEC {
54 friend class Relocation;
55 friend bool is_NativeCallTrampolineStub_at(address);
56 public:
57 enum { instruction_size = 4 };
58 inline bool is_nop();
59 inline bool is_illegal();
60 inline bool is_return();
61 bool is_jump();
62 inline bool is_jump_or_nop();
63 inline bool is_cond_jump();
64 bool is_safepoint_poll();
65 bool is_movz();
66 bool is_movk();
67 bool is_sigill_zombie_not_entrant();
68
69 protected:
70 address addr_at(int offset) const { return address(this) + offset; }
71
72 s_char sbyte_at(int offset) const { return *(s_char*) addr_at(offset); }
73 u_char ubyte_at(int offset) const { return *(u_char*) addr_at(offset); }
74
75 jint int_at(int offset) const { return *(jint*) addr_at(offset); }
76 juint uint_at(int offset) const { return *(juint*) addr_at(offset); }
77
78 address ptr_at(int offset) const { return *(address*) addr_at(offset); }
79
80 oop oop_at (int offset) const { return *(oop*) addr_at(offset); }
81
82
83 void set_char_at(int offset, char c) { *addr_at(offset) = (u_char)c; }
84 void set_int_at(int offset, jint i) { *(jint*)addr_at(offset) = i; }
85 void set_uint_at(int offset, jint i) { *(juint*)addr_at(offset) = i; }
86 void set_ptr_at (int offset, address ptr) { *(address*) addr_at(offset) = ptr; }
87 void set_oop_at (int offset, oop o) { *(oop*) addr_at(offset) = o; }
88
89 public:
90
91 // unit test stuff
92 static void test() {} // override for testing
93
94 inline friend NativeInstruction* nativeInstruction_at(address address);
95
96 static bool is_adrp_at(address instr);
97 static bool is_ldr_literal_at(address instr);
98 static bool is_ldrw_to_zr(address instr);
99
100 static bool is_call_at(address instr) {
101 const uint32_t insn = (*(uint32_t*)instr);
102 return (insn >> 26) == 0b100101;
103 }
104 bool is_call() {
105 return is_call_at(addr_at(0));
106 }
107
108 static bool maybe_cpool_ref(address instr) {
109 return is_adrp_at(instr) || is_ldr_literal_at(instr);
110 }
111
112 bool is_Membar() {
113 unsigned int insn = uint_at(0);
114 return Instruction_aarch64::extract(insn, 31, 12) == 0b11010101000000110011 &&
115 Instruction_aarch64::extract(insn, 7, 0) == 0b10111111;
116 }
117 };
118
119 inline NativeInstruction* nativeInstruction_at(address address) {
120 return (NativeInstruction*)address;
121 }
122
123 // The natural type of an AArch64 instruction is uint32_t
124 inline NativeInstruction* nativeInstruction_at(uint32_t *address) {
125 return (NativeInstruction*)address;
126 }
127
146 address return_address() const { return addr_at(return_address_offset); }
147 address destination() const;
148
149 void set_destination(address dest) {
150 int offset = dest - instruction_address();
151 unsigned int insn = 0b100101 << 26;
152 assert((offset & 3) == 0, "should be");
153 offset >>= 2;
154 offset &= (1 << 26) - 1; // mask off insn part
155 insn |= offset;
156 set_int_at(displacement_offset, insn);
157 }
158
159 void verify_alignment() { ; }
160 void verify();
161 void print();
162
163 // Creation
164 inline friend NativeCall* nativeCall_at(address address);
165 inline friend NativeCall* nativeCall_before(address return_address);
166
167 static bool is_call_before(address return_address) {
168 return is_call_at(return_address - NativeCall::return_address_offset);
169 }
170
171 // MT-safe patching of a call instruction.
172 static void insert(address code_pos, address entry);
173
174 static void replace_mt_safe(address instr_addr, address code_buffer);
175
176 // Similar to replace_mt_safe, but just changes the destination. The
177 // important thing is that free-running threads are able to execute
178 // this call instruction at all times. If the call is an immediate BL
179 // instruction we can simply rely on atomicity of 32-bit writes to
180 // make sure other threads will see no intermediate states.
181
182 // We cannot rely on locks here, since the free-running threads must run at
183 // full speed.
184 //
185 // Used in the runtime linkage of calls; see class CompiledIC.
|