12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "c1/c1_CodeStubs.hpp"
26 #include "c1/c1_FrameMap.hpp"
27 #include "c1/c1_LIRAssembler.hpp"
28 #include "c1/c1_MacroAssembler.hpp"
29 #include "c1/c1_Runtime1.hpp"
30 #include "classfile/javaClasses.hpp"
31 #include "nativeInst_x86.hpp"
32 #include "runtime/sharedRuntime.hpp"
33 #include "utilities/align.hpp"
34 #include "utilities/macros.hpp"
35 #include "vmreg_x86.inline.hpp"
36
37
38 #define __ ce->masm()->
39
40 void C1SafepointPollStub::emit_code(LIR_Assembler* ce) {
41 __ bind(_entry);
42 InternalAddress safepoint_pc(ce->masm()->pc() - ce->masm()->offset() + safepoint_offset());
43 __ lea(rscratch1, safepoint_pc);
44 __ movptr(Address(r15_thread, JavaThread::saved_exception_pc_offset()), rscratch1);
45
46 assert(SharedRuntime::polling_page_return_handler_blob() != nullptr,
47 "polling page return stub not created yet");
48
49 address stub = SharedRuntime::polling_page_return_handler_blob()->entry_point();
50 __ jump(RuntimeAddress(stub));
51 }
98 void PredicateFailedStub::emit_code(LIR_Assembler* ce) {
99 __ bind(_entry);
100 address a = Runtime1::entry_for(C1StubId::predicate_failed_trap_id);
101 __ call(RuntimeAddress(a));
102 ce->add_call_info_here(_info);
103 ce->verify_oop_map(_info);
104 debug_only(__ should_not_reach_here());
105 }
106
107 void DivByZeroStub::emit_code(LIR_Assembler* ce) {
108 if (_offset != -1) {
109 ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
110 }
111 __ bind(_entry);
112 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::throw_div0_exception_id)));
113 ce->add_call_info_here(_info);
114 debug_only(__ should_not_reach_here());
115 }
116
117
118 // Implementation of NewInstanceStub
119
120 NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, C1StubId stub_id) {
121 _result = result;
122 _klass = klass;
123 _klass_reg = klass_reg;
124 _info = new CodeEmitInfo(info);
125 assert(stub_id == C1StubId::new_instance_id ||
126 stub_id == C1StubId::fast_new_instance_id ||
127 stub_id == C1StubId::fast_new_instance_init_check_id,
128 "need new_instance id");
129 _stub_id = stub_id;
130 }
131
132
133 void NewInstanceStub::emit_code(LIR_Assembler* ce) {
134 assert(__ rsp_offset() == 0, "frame size should be fixed");
135 __ bind(_entry);
136 __ movptr(rdx, _klass_reg->as_register());
137 __ call(RuntimeAddress(Runtime1::entry_for(_stub_id)));
150 _result = result;
151 _info = new CodeEmitInfo(info);
152 }
153
154
155 void NewTypeArrayStub::emit_code(LIR_Assembler* ce) {
156 assert(__ rsp_offset() == 0, "frame size should be fixed");
157 __ bind(_entry);
158 assert(_length->as_register() == rbx, "length must in rbx,");
159 assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
160 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::new_type_array_id)));
161 ce->add_call_info_here(_info);
162 ce->verify_oop_map(_info);
163 assert(_result->as_register() == rax, "result must in rax,");
164 __ jmp(_continuation);
165 }
166
167
168 // Implementation of NewObjectArrayStub
169
170 NewObjectArrayStub::NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) {
171 _klass_reg = klass_reg;
172 _result = result;
173 _length = length;
174 _info = new CodeEmitInfo(info);
175 }
176
177
178 void NewObjectArrayStub::emit_code(LIR_Assembler* ce) {
179 assert(__ rsp_offset() == 0, "frame size should be fixed");
180 __ bind(_entry);
181 assert(_length->as_register() == rbx, "length must in rbx,");
182 assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
183 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::new_object_array_id)));
184 ce->add_call_info_here(_info);
185 ce->verify_oop_map(_info);
186 assert(_result->as_register() == rax, "result must in rax,");
187 __ jmp(_continuation);
188 }
189
190 void MonitorEnterStub::emit_code(LIR_Assembler* ce) {
191 assert(__ rsp_offset() == 0, "frame size should be fixed");
192 __ bind(_entry);
193 ce->store_parameter(_obj_reg->as_register(), 1);
194 ce->store_parameter(_lock_reg->as_register(), 0);
195 C1StubId enter_id;
196 if (ce->compilation()->has_fpu_code()) {
197 enter_id = C1StubId::monitorenter_id;
198 } else {
199 enter_id = C1StubId::monitorenter_nofpu_id;
200 }
201 __ call(RuntimeAddress(Runtime1::entry_for(enter_id)));
202 ce->add_call_info_here(_info);
203 ce->verify_oop_map(_info);
204 __ jmp(_continuation);
205 }
206
207
208 void MonitorExitStub::emit_code(LIR_Assembler* ce) {
209 __ bind(_entry);
210 if (_compute_lock) {
211 // lock_reg was destroyed by fast unlocking attempt => recompute it
212 ce->monitor_address(_monitor_ix, _lock_reg);
|
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "c1/c1_CodeStubs.hpp"
26 #include "c1/c1_FrameMap.hpp"
27 #include "c1/c1_LIRAssembler.hpp"
28 #include "c1/c1_MacroAssembler.hpp"
29 #include "c1/c1_Runtime1.hpp"
30 #include "classfile/javaClasses.hpp"
31 #include "nativeInst_x86.hpp"
32 #include "oops/objArrayKlass.hpp"
33 #include "runtime/sharedRuntime.hpp"
34 #include "utilities/align.hpp"
35 #include "utilities/macros.hpp"
36 #include "vmreg_x86.inline.hpp"
37
38
39 #define __ ce->masm()->
40
41 void C1SafepointPollStub::emit_code(LIR_Assembler* ce) {
42 __ bind(_entry);
43 InternalAddress safepoint_pc(ce->masm()->pc() - ce->masm()->offset() + safepoint_offset());
44 __ lea(rscratch1, safepoint_pc);
45 __ movptr(Address(r15_thread, JavaThread::saved_exception_pc_offset()), rscratch1);
46
47 assert(SharedRuntime::polling_page_return_handler_blob() != nullptr,
48 "polling page return stub not created yet");
49
50 address stub = SharedRuntime::polling_page_return_handler_blob()->entry_point();
51 __ jump(RuntimeAddress(stub));
52 }
99 void PredicateFailedStub::emit_code(LIR_Assembler* ce) {
100 __ bind(_entry);
101 address a = Runtime1::entry_for(C1StubId::predicate_failed_trap_id);
102 __ call(RuntimeAddress(a));
103 ce->add_call_info_here(_info);
104 ce->verify_oop_map(_info);
105 debug_only(__ should_not_reach_here());
106 }
107
108 void DivByZeroStub::emit_code(LIR_Assembler* ce) {
109 if (_offset != -1) {
110 ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
111 }
112 __ bind(_entry);
113 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::throw_div0_exception_id)));
114 ce->add_call_info_here(_info);
115 debug_only(__ should_not_reach_here());
116 }
117
118
119 // Implementation of LoadFlattenedArrayStub
120
121 LoadFlattenedArrayStub::LoadFlattenedArrayStub(LIR_Opr array, LIR_Opr index, LIR_Opr result, CodeEmitInfo* info) {
122 _array = array;
123 _index = index;
124 _result = result;
125 // Tell the register allocator that the runtime call will scratch rax.
126 _scratch_reg = FrameMap::rax_oop_opr;
127 _info = new CodeEmitInfo(info);
128 }
129
130 void LoadFlattenedArrayStub::emit_code(LIR_Assembler* ce) {
131 assert(__ rsp_offset() == 0, "frame size should be fixed");
132 __ bind(_entry);
133 ce->store_parameter(_array->as_register(), 1);
134 ce->store_parameter(_index->as_register(), 0);
135 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::load_flat_array_id)));
136 ce->add_call_info_here(_info);
137 ce->verify_oop_map(_info);
138 if (_result->as_register() != rax) {
139 __ movptr(_result->as_register(), rax);
140 }
141 __ jmp(_continuation);
142 }
143
144
145 // Implementation of StoreFlattenedArrayStub
146
147 StoreFlattenedArrayStub::StoreFlattenedArrayStub(LIR_Opr array, LIR_Opr index, LIR_Opr value, CodeEmitInfo* info) {
148 _array = array;
149 _index = index;
150 _value = value;
151 // Tell the register allocator that the runtime call will scratch rax.
152 _scratch_reg = FrameMap::rax_oop_opr;
153 _info = new CodeEmitInfo(info);
154 }
155
156
157 void StoreFlattenedArrayStub::emit_code(LIR_Assembler* ce) {
158 assert(__ rsp_offset() == 0, "frame size should be fixed");
159 __ bind(_entry);
160 ce->store_parameter(_array->as_register(), 2);
161 ce->store_parameter(_index->as_register(), 1);
162 ce->store_parameter(_value->as_register(), 0);
163 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::store_flat_array_id)));
164 ce->add_call_info_here(_info);
165 ce->verify_oop_map(_info);
166 __ jmp(_continuation);
167 }
168
169
170 // Implementation of SubstitutabilityCheckStub
171
172 SubstitutabilityCheckStub::SubstitutabilityCheckStub(LIR_Opr left, LIR_Opr right, CodeEmitInfo* info) {
173 _left = left;
174 _right = right;
175 // Tell the register allocator that the runtime call will scratch rax.
176 _scratch_reg = FrameMap::rax_oop_opr;
177 _info = new CodeEmitInfo(info);
178 }
179
180 void SubstitutabilityCheckStub::emit_code(LIR_Assembler* ce) {
181 assert(__ rsp_offset() == 0, "frame size should be fixed");
182 __ bind(_entry);
183 ce->store_parameter(_left->as_register(), 1);
184 ce->store_parameter(_right->as_register(), 0);
185 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::substitutability_check_id)));
186 ce->add_call_info_here(_info);
187 ce->verify_oop_map(_info);
188 __ jmp(_continuation);
189 }
190
191
192 // Implementation of NewInstanceStub
193
194 NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, C1StubId stub_id) {
195 _result = result;
196 _klass = klass;
197 _klass_reg = klass_reg;
198 _info = new CodeEmitInfo(info);
199 assert(stub_id == C1StubId::new_instance_id ||
200 stub_id == C1StubId::fast_new_instance_id ||
201 stub_id == C1StubId::fast_new_instance_init_check_id,
202 "need new_instance id");
203 _stub_id = stub_id;
204 }
205
206
207 void NewInstanceStub::emit_code(LIR_Assembler* ce) {
208 assert(__ rsp_offset() == 0, "frame size should be fixed");
209 __ bind(_entry);
210 __ movptr(rdx, _klass_reg->as_register());
211 __ call(RuntimeAddress(Runtime1::entry_for(_stub_id)));
224 _result = result;
225 _info = new CodeEmitInfo(info);
226 }
227
228
229 void NewTypeArrayStub::emit_code(LIR_Assembler* ce) {
230 assert(__ rsp_offset() == 0, "frame size should be fixed");
231 __ bind(_entry);
232 assert(_length->as_register() == rbx, "length must in rbx,");
233 assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
234 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::new_type_array_id)));
235 ce->add_call_info_here(_info);
236 ce->verify_oop_map(_info);
237 assert(_result->as_register() == rax, "result must in rax,");
238 __ jmp(_continuation);
239 }
240
241
242 // Implementation of NewObjectArrayStub
243
244 NewObjectArrayStub::NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result,
245 CodeEmitInfo* info, bool is_null_free) {
246 _klass_reg = klass_reg;
247 _result = result;
248 _length = length;
249 _info = new CodeEmitInfo(info);
250 _is_null_free = is_null_free;
251 }
252
253
254 void NewObjectArrayStub::emit_code(LIR_Assembler* ce) {
255 assert(__ rsp_offset() == 0, "frame size should be fixed");
256 __ bind(_entry);
257 assert(_length->as_register() == rbx, "length must in rbx,");
258 assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
259 if (_is_null_free) {
260 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::new_null_free_array_id)));
261 } else {
262 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::new_object_array_id)));
263 }
264 ce->add_call_info_here(_info);
265 ce->verify_oop_map(_info);
266 assert(_result->as_register() == rax, "result must in rax,");
267 __ jmp(_continuation);
268 }
269
270 void MonitorEnterStub::emit_code(LIR_Assembler* ce) {
271 assert(__ rsp_offset() == 0, "frame size should be fixed");
272 __ bind(_entry);
273 if (_throw_ie_stub != nullptr) {
274 // When we come here, _obj_reg has already been checked to be non-null.
275 const int is_value_mask = markWord::inline_type_pattern;
276 Register mark = _scratch_reg->as_register();
277 __ movptr(mark, Address(_obj_reg->as_register(), oopDesc::mark_offset_in_bytes()));
278 __ andptr(mark, is_value_mask);
279 __ cmpl(mark, is_value_mask);
280 __ jcc(Assembler::equal, *_throw_ie_stub->entry());
281 }
282 ce->store_parameter(_obj_reg->as_register(), 1);
283 ce->store_parameter(_lock_reg->as_register(), 0);
284 C1StubId enter_id;
285 if (ce->compilation()->has_fpu_code()) {
286 enter_id = C1StubId::monitorenter_id;
287 } else {
288 enter_id = C1StubId::monitorenter_nofpu_id;
289 }
290 __ call(RuntimeAddress(Runtime1::entry_for(enter_id)));
291 ce->add_call_info_here(_info);
292 ce->verify_oop_map(_info);
293 __ jmp(_continuation);
294 }
295
296
297 void MonitorExitStub::emit_code(LIR_Assembler* ce) {
298 __ bind(_entry);
299 if (_compute_lock) {
300 // lock_reg was destroyed by fast unlocking attempt => recompute it
301 ce->monitor_address(_monitor_ix, _lock_reg);
|