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