1 /*
2 * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
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 "precompiled.hpp"
26 #include "c1/c1_CodeStubs.hpp"
27 #include "c1/c1_FrameMap.hpp"
28 #include "c1/c1_LIRAssembler.hpp"
29 #include "c1/c1_MacroAssembler.hpp"
30 #include "c1/c1_Runtime1.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 float ConversionStub::float_zero = 0.0;
41 double ConversionStub::double_zero = 0.0;
42
43 void ConversionStub::emit_code(LIR_Assembler* ce) {
44 __ bind(_entry);
45 assert(bytecode() == Bytecodes::_f2i || bytecode() == Bytecodes::_d2i, "other conversions do not require stub");
46
47
48 if (input()->is_single_xmm()) {
49 __ comiss(input()->as_xmm_float_reg(),
50 ExternalAddress((address)&float_zero));
51 } else if (input()->is_double_xmm()) {
137 void PredicateFailedStub::emit_code(LIR_Assembler* ce) {
138 __ bind(_entry);
139 address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
140 __ call(RuntimeAddress(a));
141 ce->add_call_info_here(_info);
142 ce->verify_oop_map(_info);
143 debug_only(__ should_not_reach_here());
144 }
145
146 void DivByZeroStub::emit_code(LIR_Assembler* ce) {
147 if (_offset != -1) {
148 ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
149 }
150 __ bind(_entry);
151 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::throw_div0_exception_id)));
152 ce->add_call_info_here(_info);
153 debug_only(__ should_not_reach_here());
154 }
155
156
157 // Implementation of NewInstanceStub
158
159 NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id) {
160 _result = result;
161 _klass = klass;
162 _klass_reg = klass_reg;
163 _info = new CodeEmitInfo(info);
164 assert(stub_id == Runtime1::new_instance_id ||
165 stub_id == Runtime1::fast_new_instance_id ||
166 stub_id == Runtime1::fast_new_instance_init_check_id,
167 "need new_instance id");
168 _stub_id = stub_id;
169 }
170
171
172 void NewInstanceStub::emit_code(LIR_Assembler* ce) {
173 assert(__ rsp_offset() == 0, "frame size should be fixed");
174 __ bind(_entry);
175 __ movptr(rdx, _klass_reg->as_register());
176 __ call(RuntimeAddress(Runtime1::entry_for(_stub_id)));
189 _result = result;
190 _info = new CodeEmitInfo(info);
191 }
192
193
194 void NewTypeArrayStub::emit_code(LIR_Assembler* ce) {
195 assert(__ rsp_offset() == 0, "frame size should be fixed");
196 __ bind(_entry);
197 assert(_length->as_register() == rbx, "length must in rbx,");
198 assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
199 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::new_type_array_id)));
200 ce->add_call_info_here(_info);
201 ce->verify_oop_map(_info);
202 assert(_result->as_register() == rax, "result must in rax,");
203 __ jmp(_continuation);
204 }
205
206
207 // Implementation of NewObjectArrayStub
208
209 NewObjectArrayStub::NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) {
210 _klass_reg = klass_reg;
211 _result = result;
212 _length = length;
213 _info = new CodeEmitInfo(info);
214 }
215
216
217 void NewObjectArrayStub::emit_code(LIR_Assembler* ce) {
218 assert(__ rsp_offset() == 0, "frame size should be fixed");
219 __ bind(_entry);
220 assert(_length->as_register() == rbx, "length must in rbx,");
221 assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
222 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::new_object_array_id)));
223 ce->add_call_info_here(_info);
224 ce->verify_oop_map(_info);
225 assert(_result->as_register() == rax, "result must in rax,");
226 __ jmp(_continuation);
227 }
228
229
230 // Implementation of MonitorAccessStubs
231
232 MonitorEnterStub::MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info)
233 : MonitorAccessStub(obj_reg, lock_reg)
234 {
235 _info = new CodeEmitInfo(info);
236 }
237
238
239 void MonitorEnterStub::emit_code(LIR_Assembler* ce) {
240 assert(__ rsp_offset() == 0, "frame size should be fixed");
241 __ bind(_entry);
242 ce->store_parameter(_obj_reg->as_register(), 1);
243 ce->store_parameter(_lock_reg->as_register(), 0);
244 Runtime1::StubID enter_id;
245 if (ce->compilation()->has_fpu_code()) {
246 enter_id = Runtime1::monitorenter_id;
247 } else {
248 enter_id = Runtime1::monitorenter_nofpu_id;
249 }
250 __ call(RuntimeAddress(Runtime1::entry_for(enter_id)));
251 ce->add_call_info_here(_info);
252 ce->verify_oop_map(_info);
253 __ jmp(_continuation);
254 }
255
256
257 void MonitorExitStub::emit_code(LIR_Assembler* ce) {
258 __ bind(_entry);
259 if (_compute_lock) {
260 // lock_reg was destroyed by fast unlocking attempt => recompute it
261 ce->monitor_address(_monitor_ix, _lock_reg);
|
1 /*
2 * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
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 "precompiled.hpp"
26 #include "c1/c1_CodeStubs.hpp"
27 #include "c1/c1_FrameMap.hpp"
28 #include "c1/c1_LIRAssembler.hpp"
29 #include "c1/c1_MacroAssembler.hpp"
30 #include "c1/c1_Runtime1.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 float ConversionStub::float_zero = 0.0;
42 double ConversionStub::double_zero = 0.0;
43
44 void ConversionStub::emit_code(LIR_Assembler* ce) {
45 __ bind(_entry);
46 assert(bytecode() == Bytecodes::_f2i || bytecode() == Bytecodes::_d2i, "other conversions do not require stub");
47
48
49 if (input()->is_single_xmm()) {
50 __ comiss(input()->as_xmm_float_reg(),
51 ExternalAddress((address)&float_zero));
52 } else if (input()->is_double_xmm()) {
138 void PredicateFailedStub::emit_code(LIR_Assembler* ce) {
139 __ bind(_entry);
140 address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
141 __ call(RuntimeAddress(a));
142 ce->add_call_info_here(_info);
143 ce->verify_oop_map(_info);
144 debug_only(__ should_not_reach_here());
145 }
146
147 void DivByZeroStub::emit_code(LIR_Assembler* ce) {
148 if (_offset != -1) {
149 ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
150 }
151 __ bind(_entry);
152 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::throw_div0_exception_id)));
153 ce->add_call_info_here(_info);
154 debug_only(__ should_not_reach_here());
155 }
156
157
158 // Implementation of LoadFlattenedArrayStub
159
160 LoadFlattenedArrayStub::LoadFlattenedArrayStub(LIR_Opr array, LIR_Opr index, LIR_Opr result, CodeEmitInfo* info) {
161 _array = array;
162 _index = index;
163 _result = result;
164 // Tell the register allocator that the runtime call will scratch rax.
165 _scratch_reg = FrameMap::rax_oop_opr;
166 _info = new CodeEmitInfo(info);
167 }
168
169 void LoadFlattenedArrayStub::emit_code(LIR_Assembler* ce) {
170 assert(__ rsp_offset() == 0, "frame size should be fixed");
171 __ bind(_entry);
172 ce->store_parameter(_array->as_register(), 1);
173 ce->store_parameter(_index->as_register(), 0);
174 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::load_flattened_array_id)));
175 ce->add_call_info_here(_info);
176 ce->verify_oop_map(_info);
177 if (_result->as_register() != rax) {
178 __ movptr(_result->as_register(), rax);
179 }
180 __ jmp(_continuation);
181 }
182
183
184 // Implementation of StoreFlattenedArrayStub
185
186 StoreFlattenedArrayStub::StoreFlattenedArrayStub(LIR_Opr array, LIR_Opr index, LIR_Opr value, CodeEmitInfo* info) {
187 _array = array;
188 _index = index;
189 _value = value;
190 // Tell the register allocator that the runtime call will scratch rax.
191 _scratch_reg = FrameMap::rax_oop_opr;
192 _info = new CodeEmitInfo(info);
193 }
194
195
196 void StoreFlattenedArrayStub::emit_code(LIR_Assembler* ce) {
197 assert(__ rsp_offset() == 0, "frame size should be fixed");
198 __ bind(_entry);
199 ce->store_parameter(_array->as_register(), 2);
200 ce->store_parameter(_index->as_register(), 1);
201 ce->store_parameter(_value->as_register(), 0);
202 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::store_flattened_array_id)));
203 ce->add_call_info_here(_info);
204 ce->verify_oop_map(_info);
205 __ jmp(_continuation);
206 }
207
208
209 // Implementation of NewInstanceStub
210
211 NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id) {
212 _result = result;
213 _klass = klass;
214 _klass_reg = klass_reg;
215 _info = new CodeEmitInfo(info);
216 assert(stub_id == Runtime1::new_instance_id ||
217 stub_id == Runtime1::fast_new_instance_id ||
218 stub_id == Runtime1::fast_new_instance_init_check_id,
219 "need new_instance id");
220 _stub_id = stub_id;
221 }
222
223
224 void NewInstanceStub::emit_code(LIR_Assembler* ce) {
225 assert(__ rsp_offset() == 0, "frame size should be fixed");
226 __ bind(_entry);
227 __ movptr(rdx, _klass_reg->as_register());
228 __ call(RuntimeAddress(Runtime1::entry_for(_stub_id)));
241 _result = result;
242 _info = new CodeEmitInfo(info);
243 }
244
245
246 void NewTypeArrayStub::emit_code(LIR_Assembler* ce) {
247 assert(__ rsp_offset() == 0, "frame size should be fixed");
248 __ bind(_entry);
249 assert(_length->as_register() == rbx, "length must in rbx,");
250 assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
251 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::new_type_array_id)));
252 ce->add_call_info_here(_info);
253 ce->verify_oop_map(_info);
254 assert(_result->as_register() == rax, "result must in rax,");
255 __ jmp(_continuation);
256 }
257
258
259 // Implementation of NewObjectArrayStub
260
261 NewObjectArrayStub::NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result,
262 CodeEmitInfo* info, bool is_value_type) {
263 _klass_reg = klass_reg;
264 _result = result;
265 _length = length;
266 _info = new CodeEmitInfo(info);
267 _is_value_type = is_value_type;
268 }
269
270
271 void NewObjectArrayStub::emit_code(LIR_Assembler* ce) {
272 assert(__ rsp_offset() == 0, "frame size should be fixed");
273 __ bind(_entry);
274 assert(_length->as_register() == rbx, "length must in rbx,");
275 assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
276 if (_is_value_type) {
277 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::new_value_array_id)));
278 } else {
279 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::new_object_array_id)));
280 }
281 ce->add_call_info_here(_info);
282 ce->verify_oop_map(_info);
283 assert(_result->as_register() == rax, "result must in rax,");
284 __ jmp(_continuation);
285 }
286
287
288 // Implementation of MonitorAccessStubs
289
290 MonitorEnterStub::MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info, CodeStub* throw_imse_stub, LIR_Opr scratch_reg)
291 : MonitorAccessStub(obj_reg, lock_reg)
292 {
293 _info = new CodeEmitInfo(info);
294 _throw_imse_stub = throw_imse_stub;
295 _scratch_reg = scratch_reg;
296 if (_throw_imse_stub != NULL) {
297 assert(_scratch_reg != LIR_OprFact::illegalOpr, "must be");
298 }
299 }
300
301
302 void MonitorEnterStub::emit_code(LIR_Assembler* ce) {
303 assert(__ rsp_offset() == 0, "frame size should be fixed");
304 __ bind(_entry);
305 if (_throw_imse_stub != NULL) {
306 // When we come here, _obj_reg has already been checked to be non-null.
307 Register mark = _scratch_reg->as_register();
308 __ movptr(mark, Address(_obj_reg->as_register(), oopDesc::mark_offset_in_bytes()));
309 __ testl(mark, markOopDesc::always_locked_pattern);
310 __ jcc(Assembler::notZero, *_throw_imse_stub->entry());
311 }
312 ce->store_parameter(_obj_reg->as_register(), 1);
313 ce->store_parameter(_lock_reg->as_register(), 0);
314 Runtime1::StubID enter_id;
315 if (ce->compilation()->has_fpu_code()) {
316 enter_id = Runtime1::monitorenter_id;
317 } else {
318 enter_id = Runtime1::monitorenter_nofpu_id;
319 }
320 __ call(RuntimeAddress(Runtime1::entry_for(enter_id)));
321 ce->add_call_info_here(_info);
322 ce->verify_oop_map(_info);
323 __ jmp(_continuation);
324 }
325
326
327 void MonitorExitStub::emit_code(LIR_Assembler* ce) {
328 __ bind(_entry);
329 if (_compute_lock) {
330 // lock_reg was destroyed by fast unlocking attempt => recompute it
331 ce->monitor_address(_monitor_ix, _lock_reg);
|