216 bind(done);
217 }
218
219 void MacroAssembler::pop_cont_fastpath(Register java_thread) {
220 if (!Continuations::enabled()) return;
221 Label done;
222 ld(t0, Address(java_thread, JavaThread::cont_fastpath_offset()));
223 bltu(sp, t0, done);
224 sd(zr, Address(java_thread, JavaThread::cont_fastpath_offset()));
225 bind(done);
226 }
227
228 int MacroAssembler::align(int modulus, int extra_offset) {
229 CompressibleScope scope(this);
230 intptr_t before = offset();
231 while ((offset() + extra_offset) % modulus != 0) { nop(); }
232 return (int)(offset() - before);
233 }
234
235 void MacroAssembler::call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions) {
236 call_VM_base(oop_result, noreg, noreg, entry_point, number_of_arguments, check_exceptions);
237 }
238
239 // Implementation of call_VM versions
240
241 void MacroAssembler::call_VM(Register oop_result,
242 address entry_point,
243 bool check_exceptions) {
244 call_VM_helper(oop_result, entry_point, 0, check_exceptions);
245 }
246
247 void MacroAssembler::call_VM(Register oop_result,
248 address entry_point,
249 Register arg_1,
250 bool check_exceptions) {
251 pass_arg1(this, arg_1);
252 call_VM_helper(oop_result, entry_point, 1, check_exceptions);
253 }
254
255 void MacroAssembler::call_VM(Register oop_result,
256 address entry_point,
267 address entry_point,
268 Register arg_1,
269 Register arg_2,
270 Register arg_3,
271 bool check_exceptions) {
272 assert_different_registers(arg_1, c_rarg2, c_rarg3);
273 assert_different_registers(arg_2, c_rarg3);
274 pass_arg3(this, arg_3);
275
276 pass_arg2(this, arg_2);
277
278 pass_arg1(this, arg_1);
279 call_VM_helper(oop_result, entry_point, 3, check_exceptions);
280 }
281
282 void MacroAssembler::call_VM(Register oop_result,
283 Register last_java_sp,
284 address entry_point,
285 int number_of_arguments,
286 bool check_exceptions) {
287 call_VM_base(oop_result, xthread, last_java_sp, entry_point, number_of_arguments, check_exceptions);
288 }
289
290 void MacroAssembler::call_VM(Register oop_result,
291 Register last_java_sp,
292 address entry_point,
293 Register arg_1,
294 bool check_exceptions) {
295 pass_arg1(this, arg_1);
296 call_VM(oop_result, last_java_sp, entry_point, 1, check_exceptions);
297 }
298
299 void MacroAssembler::call_VM(Register oop_result,
300 Register last_java_sp,
301 address entry_point,
302 Register arg_1,
303 Register arg_2,
304 bool check_exceptions) {
305
306 assert_different_registers(arg_1, c_rarg2);
307 pass_arg2(this, arg_2);
392 L.add_patch_at(code(), locator());
393 IncompressibleScope scope(this); // the label address will be patched back.
394 set_last_Java_frame(last_java_sp, last_java_fp, pc() /* Patched later */, tmp);
395 }
396 }
397
398 void MacroAssembler::reset_last_Java_frame(bool clear_fp) {
399 // we must set sp to zero to clear frame
400 sd(zr, Address(xthread, JavaThread::last_Java_sp_offset()));
401
402 // must clear fp, so that compiled frames are not confused; it is
403 // possible that we need it only for debugging
404 if (clear_fp) {
405 sd(zr, Address(xthread, JavaThread::last_Java_fp_offset()));
406 }
407
408 // Always clear the pc because it could have been set by make_walkable()
409 sd(zr, Address(xthread, JavaThread::last_Java_pc_offset()));
410 }
411
412 static bool is_preemptable(address entry_point) {
413 return entry_point == CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter);
414 }
415
416 void MacroAssembler::call_VM_base(Register oop_result,
417 Register java_thread,
418 Register last_java_sp,
419 address entry_point,
420 int number_of_arguments,
421 bool check_exceptions) {
422 // determine java_thread register
423 if (!java_thread->is_valid()) {
424 java_thread = xthread;
425 }
426 // determine last_java_sp register
427 if (!last_java_sp->is_valid()) {
428 last_java_sp = esp;
429 }
430
431 // debugging support
432 assert(number_of_arguments >= 0 , "cannot have negative number of arguments");
433 assert(java_thread == xthread, "unexpected register");
434
435 assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result");
436 assert(java_thread != last_java_sp, "cannot use the same register for java_thread & last_java_sp");
437
438 // push java thread (becomes first argument of C function)
439 mv(c_rarg0, java_thread);
440
441 // set last Java frame before call
442 assert(last_java_sp != fp, "can't use fp");
443
444 Label l;
445 if (is_preemptable(entry_point)) {
446 // skip setting last_pc since we already set it to desired value.
447 set_last_Java_frame(last_java_sp, fp, noreg);
448 } else {
449 set_last_Java_frame(last_java_sp, fp, l, t0);
450 }
451
452 // do the call, remove parameters
453 MacroAssembler::call_VM_leaf_base(entry_point, number_of_arguments, &l);
454
455 // reset last Java frame
456 // Only interpreter should have to clear fp
457 reset_last_Java_frame(true);
458
459 // C++ interp handles this in the interpreter
460 check_and_handle_popframe(java_thread);
461 check_and_handle_earlyret(java_thread);
462
463 if (check_exceptions) {
464 // check for pending exceptions (java_thread is set upon return)
465 ld(t0, Address(java_thread, in_bytes(Thread::pending_exception_offset())));
466 Label ok;
467 beqz(t0, ok);
468 j(RuntimeAddress(StubRoutines::forward_exception_entry()));
469 bind(ok);
470 }
|
216 bind(done);
217 }
218
219 void MacroAssembler::pop_cont_fastpath(Register java_thread) {
220 if (!Continuations::enabled()) return;
221 Label done;
222 ld(t0, Address(java_thread, JavaThread::cont_fastpath_offset()));
223 bltu(sp, t0, done);
224 sd(zr, Address(java_thread, JavaThread::cont_fastpath_offset()));
225 bind(done);
226 }
227
228 int MacroAssembler::align(int modulus, int extra_offset) {
229 CompressibleScope scope(this);
230 intptr_t before = offset();
231 while ((offset() + extra_offset) % modulus != 0) { nop(); }
232 return (int)(offset() - before);
233 }
234
235 void MacroAssembler::call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions) {
236 call_VM_base(oop_result, noreg, noreg, nullptr, entry_point, number_of_arguments, check_exceptions);
237 }
238
239 // Implementation of call_VM versions
240
241 void MacroAssembler::call_VM(Register oop_result,
242 address entry_point,
243 bool check_exceptions) {
244 call_VM_helper(oop_result, entry_point, 0, check_exceptions);
245 }
246
247 void MacroAssembler::call_VM(Register oop_result,
248 address entry_point,
249 Register arg_1,
250 bool check_exceptions) {
251 pass_arg1(this, arg_1);
252 call_VM_helper(oop_result, entry_point, 1, check_exceptions);
253 }
254
255 void MacroAssembler::call_VM(Register oop_result,
256 address entry_point,
267 address entry_point,
268 Register arg_1,
269 Register arg_2,
270 Register arg_3,
271 bool check_exceptions) {
272 assert_different_registers(arg_1, c_rarg2, c_rarg3);
273 assert_different_registers(arg_2, c_rarg3);
274 pass_arg3(this, arg_3);
275
276 pass_arg2(this, arg_2);
277
278 pass_arg1(this, arg_1);
279 call_VM_helper(oop_result, entry_point, 3, check_exceptions);
280 }
281
282 void MacroAssembler::call_VM(Register oop_result,
283 Register last_java_sp,
284 address entry_point,
285 int number_of_arguments,
286 bool check_exceptions) {
287 call_VM_base(oop_result, xthread, last_java_sp, nullptr, entry_point, number_of_arguments, check_exceptions);
288 }
289
290 void MacroAssembler::call_VM(Register oop_result,
291 Register last_java_sp,
292 address entry_point,
293 Register arg_1,
294 bool check_exceptions) {
295 pass_arg1(this, arg_1);
296 call_VM(oop_result, last_java_sp, entry_point, 1, check_exceptions);
297 }
298
299 void MacroAssembler::call_VM(Register oop_result,
300 Register last_java_sp,
301 address entry_point,
302 Register arg_1,
303 Register arg_2,
304 bool check_exceptions) {
305
306 assert_different_registers(arg_1, c_rarg2);
307 pass_arg2(this, arg_2);
392 L.add_patch_at(code(), locator());
393 IncompressibleScope scope(this); // the label address will be patched back.
394 set_last_Java_frame(last_java_sp, last_java_fp, pc() /* Patched later */, tmp);
395 }
396 }
397
398 void MacroAssembler::reset_last_Java_frame(bool clear_fp) {
399 // we must set sp to zero to clear frame
400 sd(zr, Address(xthread, JavaThread::last_Java_sp_offset()));
401
402 // must clear fp, so that compiled frames are not confused; it is
403 // possible that we need it only for debugging
404 if (clear_fp) {
405 sd(zr, Address(xthread, JavaThread::last_Java_fp_offset()));
406 }
407
408 // Always clear the pc because it could have been set by make_walkable()
409 sd(zr, Address(xthread, JavaThread::last_Java_pc_offset()));
410 }
411
412 void MacroAssembler::call_VM_base(Register oop_result,
413 Register java_thread,
414 Register last_java_sp,
415 Label* return_pc,
416 address entry_point,
417 int number_of_arguments,
418 bool check_exceptions) {
419 // determine java_thread register
420 if (!java_thread->is_valid()) {
421 java_thread = xthread;
422 }
423
424 // determine last_java_sp register
425 if (!last_java_sp->is_valid()) {
426 last_java_sp = esp;
427 }
428
429 // debugging support
430 assert(number_of_arguments >= 0 , "cannot have negative number of arguments");
431 assert(java_thread == xthread, "unexpected register");
432
433 assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result");
434 assert(java_thread != last_java_sp, "cannot use the same register for java_thread & last_java_sp");
435
436 // push java thread (becomes first argument of C function)
437 mv(c_rarg0, java_thread);
438
439 // set last Java frame before call
440 assert(last_java_sp != fp, "can't use fp");
441
442 Label l;
443 set_last_Java_frame(last_java_sp, fp, return_pc != nullptr ? *return_pc : l, t0);
444
445 // do the call, remove parameters
446 MacroAssembler::call_VM_leaf_base(entry_point, number_of_arguments, &l);
447
448 // reset last Java frame
449 // Only interpreter should have to clear fp
450 reset_last_Java_frame(true);
451
452 // C++ interp handles this in the interpreter
453 check_and_handle_popframe(java_thread);
454 check_and_handle_earlyret(java_thread);
455
456 if (check_exceptions) {
457 // check for pending exceptions (java_thread is set upon return)
458 ld(t0, Address(java_thread, in_bytes(Thread::pending_exception_offset())));
459 Label ok;
460 beqz(t0, ok);
461 j(RuntimeAddress(StubRoutines::forward_exception_entry()));
462 bind(ok);
463 }
|