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 #ifndef _LP64
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));
152 void PredicateFailedStub::emit_code(LIR_Assembler* ce) {
153 __ bind(_entry);
154 address a = Runtime1::entry_for(C1StubId::predicate_failed_trap_id);
155 __ call(RuntimeAddress(a));
156 ce->add_call_info_here(_info);
157 ce->verify_oop_map(_info);
158 debug_only(__ should_not_reach_here());
159 }
160
161 void DivByZeroStub::emit_code(LIR_Assembler* ce) {
162 if (_offset != -1) {
163 ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
164 }
165 __ bind(_entry);
166 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::throw_div0_exception_id)));
167 ce->add_call_info_here(_info);
168 debug_only(__ should_not_reach_here());
169 }
170
171
172 // Implementation of NewInstanceStub
173
174 NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, C1StubId stub_id) {
175 _result = result;
176 _klass = klass;
177 _klass_reg = klass_reg;
178 _info = new CodeEmitInfo(info);
179 assert(stub_id == C1StubId::new_instance_id ||
180 stub_id == C1StubId::fast_new_instance_id ||
181 stub_id == C1StubId::fast_new_instance_init_check_id,
182 "need new_instance id");
183 _stub_id = stub_id;
184 }
185
186
187 void NewInstanceStub::emit_code(LIR_Assembler* ce) {
188 assert(__ rsp_offset() == 0, "frame size should be fixed");
189 __ bind(_entry);
190 __ movptr(rdx, _klass_reg->as_register());
191 __ call(RuntimeAddress(Runtime1::entry_for(_stub_id)));
204 _result = result;
205 _info = new CodeEmitInfo(info);
206 }
207
208
209 void NewTypeArrayStub::emit_code(LIR_Assembler* ce) {
210 assert(__ rsp_offset() == 0, "frame size should be fixed");
211 __ bind(_entry);
212 assert(_length->as_register() == rbx, "length must in rbx,");
213 assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
214 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::new_type_array_id)));
215 ce->add_call_info_here(_info);
216 ce->verify_oop_map(_info);
217 assert(_result->as_register() == rax, "result must in rax,");
218 __ jmp(_continuation);
219 }
220
221
222 // Implementation of NewObjectArrayStub
223
224 NewObjectArrayStub::NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) {
225 _klass_reg = klass_reg;
226 _result = result;
227 _length = length;
228 _info = new CodeEmitInfo(info);
229 }
230
231
232 void NewObjectArrayStub::emit_code(LIR_Assembler* ce) {
233 assert(__ rsp_offset() == 0, "frame size should be fixed");
234 __ bind(_entry);
235 assert(_length->as_register() == rbx, "length must in rbx,");
236 assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
237 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::new_object_array_id)));
238 ce->add_call_info_here(_info);
239 ce->verify_oop_map(_info);
240 assert(_result->as_register() == rax, "result must in rax,");
241 __ jmp(_continuation);
242 }
243
244 void MonitorEnterStub::emit_code(LIR_Assembler* ce) {
245 assert(__ rsp_offset() == 0, "frame size should be fixed");
246 __ bind(_entry);
247 ce->store_parameter(_obj_reg->as_register(), 1);
248 ce->store_parameter(_lock_reg->as_register(), 0);
249 C1StubId enter_id;
250 if (ce->compilation()->has_fpu_code()) {
251 enter_id = C1StubId::monitorenter_id;
252 } else {
253 enter_id = C1StubId::monitorenter_nofpu_id;
254 }
255 __ call(RuntimeAddress(Runtime1::entry_for(enter_id)));
256 ce->add_call_info_here(_info);
257 ce->verify_oop_map(_info);
258 __ jmp(_continuation);
259 }
260
261
262 void MonitorExitStub::emit_code(LIR_Assembler* ce) {
263 __ bind(_entry);
264 if (_compute_lock) {
265 // lock_reg was destroyed by fast unlocking attempt => recompute it
266 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 #ifndef _LP64
42 float ConversionStub::float_zero = 0.0;
43 double ConversionStub::double_zero = 0.0;
44
45 void ConversionStub::emit_code(LIR_Assembler* ce) {
46 __ bind(_entry);
47 assert(bytecode() == Bytecodes::_f2i || bytecode() == Bytecodes::_d2i, "other conversions do not require stub");
48
49
50 if (input()->is_single_xmm()) {
51 __ comiss(input()->as_xmm_float_reg(),
52 ExternalAddress((address)&float_zero));
153 void PredicateFailedStub::emit_code(LIR_Assembler* ce) {
154 __ bind(_entry);
155 address a = Runtime1::entry_for(C1StubId::predicate_failed_trap_id);
156 __ call(RuntimeAddress(a));
157 ce->add_call_info_here(_info);
158 ce->verify_oop_map(_info);
159 debug_only(__ should_not_reach_here());
160 }
161
162 void DivByZeroStub::emit_code(LIR_Assembler* ce) {
163 if (_offset != -1) {
164 ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
165 }
166 __ bind(_entry);
167 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::throw_div0_exception_id)));
168 ce->add_call_info_here(_info);
169 debug_only(__ should_not_reach_here());
170 }
171
172
173 // Implementation of LoadFlattenedArrayStub
174
175 LoadFlattenedArrayStub::LoadFlattenedArrayStub(LIR_Opr array, LIR_Opr index, LIR_Opr result, CodeEmitInfo* info) {
176 _array = array;
177 _index = index;
178 _result = result;
179 // Tell the register allocator that the runtime call will scratch rax.
180 _scratch_reg = FrameMap::rax_oop_opr;
181 _info = new CodeEmitInfo(info);
182 }
183
184 void LoadFlattenedArrayStub::emit_code(LIR_Assembler* ce) {
185 assert(__ rsp_offset() == 0, "frame size should be fixed");
186 __ bind(_entry);
187 ce->store_parameter(_array->as_register(), 1);
188 ce->store_parameter(_index->as_register(), 0);
189 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::load_flat_array_id)));
190 ce->add_call_info_here(_info);
191 ce->verify_oop_map(_info);
192 if (_result->as_register() != rax) {
193 __ movptr(_result->as_register(), rax);
194 }
195 __ jmp(_continuation);
196 }
197
198
199 // Implementation of StoreFlattenedArrayStub
200
201 StoreFlattenedArrayStub::StoreFlattenedArrayStub(LIR_Opr array, LIR_Opr index, LIR_Opr value, CodeEmitInfo* info) {
202 _array = array;
203 _index = index;
204 _value = value;
205 // Tell the register allocator that the runtime call will scratch rax.
206 _scratch_reg = FrameMap::rax_oop_opr;
207 _info = new CodeEmitInfo(info);
208 }
209
210
211 void StoreFlattenedArrayStub::emit_code(LIR_Assembler* ce) {
212 assert(__ rsp_offset() == 0, "frame size should be fixed");
213 __ bind(_entry);
214 ce->store_parameter(_array->as_register(), 2);
215 ce->store_parameter(_index->as_register(), 1);
216 ce->store_parameter(_value->as_register(), 0);
217 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::store_flat_array_id)));
218 ce->add_call_info_here(_info);
219 ce->verify_oop_map(_info);
220 __ jmp(_continuation);
221 }
222
223
224 // Implementation of SubstitutabilityCheckStub
225
226 SubstitutabilityCheckStub::SubstitutabilityCheckStub(LIR_Opr left, LIR_Opr right, CodeEmitInfo* info) {
227 _left = left;
228 _right = right;
229 // Tell the register allocator that the runtime call will scratch rax.
230 _scratch_reg = FrameMap::rax_oop_opr;
231 _info = new CodeEmitInfo(info);
232 }
233
234 void SubstitutabilityCheckStub::emit_code(LIR_Assembler* ce) {
235 assert(__ rsp_offset() == 0, "frame size should be fixed");
236 __ bind(_entry);
237 ce->store_parameter(_left->as_register(), 1);
238 ce->store_parameter(_right->as_register(), 0);
239 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::substitutability_check_id)));
240 ce->add_call_info_here(_info);
241 ce->verify_oop_map(_info);
242 __ jmp(_continuation);
243 }
244
245
246 // Implementation of NewInstanceStub
247
248 NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, C1StubId stub_id) {
249 _result = result;
250 _klass = klass;
251 _klass_reg = klass_reg;
252 _info = new CodeEmitInfo(info);
253 assert(stub_id == C1StubId::new_instance_id ||
254 stub_id == C1StubId::fast_new_instance_id ||
255 stub_id == C1StubId::fast_new_instance_init_check_id,
256 "need new_instance id");
257 _stub_id = stub_id;
258 }
259
260
261 void NewInstanceStub::emit_code(LIR_Assembler* ce) {
262 assert(__ rsp_offset() == 0, "frame size should be fixed");
263 __ bind(_entry);
264 __ movptr(rdx, _klass_reg->as_register());
265 __ call(RuntimeAddress(Runtime1::entry_for(_stub_id)));
278 _result = result;
279 _info = new CodeEmitInfo(info);
280 }
281
282
283 void NewTypeArrayStub::emit_code(LIR_Assembler* ce) {
284 assert(__ rsp_offset() == 0, "frame size should be fixed");
285 __ bind(_entry);
286 assert(_length->as_register() == rbx, "length must in rbx,");
287 assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
288 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::new_type_array_id)));
289 ce->add_call_info_here(_info);
290 ce->verify_oop_map(_info);
291 assert(_result->as_register() == rax, "result must in rax,");
292 __ jmp(_continuation);
293 }
294
295
296 // Implementation of NewObjectArrayStub
297
298 NewObjectArrayStub::NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result,
299 CodeEmitInfo* info, bool is_null_free) {
300 _klass_reg = klass_reg;
301 _result = result;
302 _length = length;
303 _info = new CodeEmitInfo(info);
304 _is_null_free = is_null_free;
305 }
306
307
308 void NewObjectArrayStub::emit_code(LIR_Assembler* ce) {
309 assert(__ rsp_offset() == 0, "frame size should be fixed");
310 __ bind(_entry);
311 assert(_length->as_register() == rbx, "length must in rbx,");
312 assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx");
313 if (_is_null_free) {
314 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::new_null_free_array_id)));
315 } else {
316 __ call(RuntimeAddress(Runtime1::entry_for(C1StubId::new_object_array_id)));
317 }
318 ce->add_call_info_here(_info);
319 ce->verify_oop_map(_info);
320 assert(_result->as_register() == rax, "result must in rax,");
321 __ jmp(_continuation);
322 }
323
324 void MonitorEnterStub::emit_code(LIR_Assembler* ce) {
325 assert(__ rsp_offset() == 0, "frame size should be fixed");
326 __ bind(_entry);
327 if (_throw_ie_stub != nullptr) {
328 // When we come here, _obj_reg has already been checked to be non-null.
329 const int is_value_mask = markWord::inline_type_pattern;
330 Register mark = _scratch_reg->as_register();
331 __ movptr(mark, Address(_obj_reg->as_register(), oopDesc::mark_offset_in_bytes()));
332 __ andptr(mark, is_value_mask);
333 __ cmpl(mark, is_value_mask);
334 __ jcc(Assembler::equal, *_throw_ie_stub->entry());
335 }
336 ce->store_parameter(_obj_reg->as_register(), 1);
337 ce->store_parameter(_lock_reg->as_register(), 0);
338 C1StubId enter_id;
339 if (ce->compilation()->has_fpu_code()) {
340 enter_id = C1StubId::monitorenter_id;
341 } else {
342 enter_id = C1StubId::monitorenter_nofpu_id;
343 }
344 __ call(RuntimeAddress(Runtime1::entry_for(enter_id)));
345 ce->add_call_info_here(_info);
346 ce->verify_oop_map(_info);
347 __ jmp(_continuation);
348 }
349
350
351 void MonitorExitStub::emit_code(LIR_Assembler* ce) {
352 __ bind(_entry);
353 if (_compute_lock) {
354 // lock_reg was destroyed by fast unlocking attempt => recompute it
355 ce->monitor_address(_monitor_ix, _lock_reg);
|