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 "asm/macroAssembler.hpp"
26 #include "classfile/javaClasses.hpp"
27 #include "classfile/vmIntrinsics.hpp"
28 #include "compiler/oopMap.hpp"
29 #include "gc/shared/barrierSet.hpp"
30 #include "gc/shared/barrierSetAssembler.hpp"
31 #include "gc/shared/barrierSetNMethod.hpp"
32 #include "gc/shared/gc_globals.hpp"
33 #include "memory/universe.hpp"
34 #include "prims/jvmtiExport.hpp"
35 #include "prims/upcallLinker.hpp"
36 #include "runtime/arguments.hpp"
37 #include "runtime/continuationEntry.hpp"
38 #include "runtime/javaThread.hpp"
39 #include "runtime/sharedRuntime.hpp"
40 #include "runtime/stubRoutines.hpp"
41 #include "stubGenerator_x86_64.hpp"
42 #ifdef COMPILER2
43 #include "opto/runtime.hpp"
44 #include "opto/c2_globals.hpp"
45 #endif
46
47 // For a more detailed description of the stub routine structure
48 // see the comment in stubRoutines.hpp
49
50 #define __ _masm->
51 #define TIMES_OOP (UseCompressedOops ? Address::times_4 : Address::times_8)
52
53 #ifdef PRODUCT
54 #define BLOCK_COMMENT(str) /* nothing */
55 #else
56 #define BLOCK_COMMENT(str) __ block_comment(str)
57 #endif // PRODUCT
58
59 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
60
290 __ movl(c_rarg1, c_rarg3); // parameter counter is in c_rarg1
291 __ BIND(loop);
292 __ movptr(rax, Address(c_rarg2, 0));// get parameter
293 __ addptr(c_rarg2, wordSize); // advance to next parameter
294 __ decrementl(c_rarg1); // decrement counter
295 __ push(rax); // pass parameter
296 __ jcc(Assembler::notZero, loop);
297
298 // call Java function
299 __ BIND(parameters_done);
300 __ movptr(rbx, method); // get Method*
301 __ movptr(c_rarg1, entry_point); // get entry_point
302 __ mov(r13, rsp); // set sender sp
303 BLOCK_COMMENT("call Java function");
304 __ call(c_rarg1);
305
306 BLOCK_COMMENT("call_stub_return_address:");
307 return_address = __ pc();
308 entries.append(return_address);
309
310 // store result depending on type (everything that is not
311 // T_OBJECT, T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT)
312 __ movptr(c_rarg0, result);
313 Label is_long, is_float, is_double, exit;
314 __ movl(c_rarg1, result_type);
315 __ cmpl(c_rarg1, T_OBJECT);
316 __ jcc(Assembler::equal, is_long);
317 __ cmpl(c_rarg1, T_LONG);
318 __ jcc(Assembler::equal, is_long);
319 __ cmpl(c_rarg1, T_FLOAT);
320 __ jcc(Assembler::equal, is_float);
321 __ cmpl(c_rarg1, T_DOUBLE);
322 __ jcc(Assembler::equal, is_double);
323 #ifdef ASSERT
324 // make sure the type is INT
325 {
326 Label L;
327 __ cmpl(c_rarg1, T_INT);
328 __ jcc(Assembler::equal, L);
329 __ stop("StubRoutines::call_stub: unexpected result type");
330 __ bind(L);
331 }
332 #endif
333
334 // handle T_INT case
335 __ movl(Address(c_rarg0, 0), rax);
336
337 __ BIND(exit);
338
339 // pop parameters
340 __ lea(rsp, rsp_after_call);
341
342 #ifdef ASSERT
343 // verify that threads correspond
344 {
345 Label L1, L2, L3;
346 __ cmpptr(r15_thread, thread);
347 __ jcc(Assembler::equal, L1);
348 __ stop("StubRoutines::call_stub: r15_thread is corrupted");
349 __ bind(L1);
350 __ get_thread_slow(rbx);
351 __ cmpptr(r15_thread, thread);
352 __ jcc(Assembler::equal, L2);
353 __ stop("StubRoutines::call_stub: r15_thread is modified by call");
354 __ bind(L2);
355 __ cmpptr(r15_thread, rbx);
373 __ movptr(r13, r13_save);
374 __ movptr(r12, r12_save);
375 __ movptr(rbx, rbx_save);
376
377 #ifdef _WIN64
378 __ movptr(rdi, rdi_save);
379 __ movptr(rsi, rsi_save);
380 #else
381 __ ldmxcsr(mxcsr_save);
382 #endif
383
384 // restore rsp
385 __ addptr(rsp, -rsp_after_call_off * wordSize);
386
387 // return
388 __ vzeroupper();
389 __ pop(rbp);
390 __ ret(0);
391
392 // handle return types different from T_INT
393 __ BIND(is_long);
394 __ movq(Address(c_rarg0, 0), rax);
395 __ jmp(exit);
396
397 __ BIND(is_float);
398 __ movflt(Address(c_rarg0, 0), xmm0);
399 __ jmp(exit);
400
401 __ BIND(is_double);
402 __ movdbl(Address(c_rarg0, 0), xmm0);
403 __ jmp(exit);
404
405 // record the stub entry and end plus the auxiliary entry
406 store_archive_data(stub_id, start, __ pc(), &entries);
407
408 return start;
409 }
410
411 // Return point for a Java call if there's an exception thrown in
412 // Java code. The exception is caught and transformed into a
413 // pending exception stored in JavaThread that can be tested from
414 // within the VM.
415 //
416 // Note: Usually the parameters are removed by the callee. In case
417 // of an exception crossing an activation frame boundary, that is
418 // not the case if the callee is compiled code => need to setup the
419 // rsp.
420 //
421 // rax: exception oop
422
4353 return start;
4354 }
4355 StubCodeMark mark(this, stub_id);
4356
4357 start = __ pc();
4358
4359 BLOCK_COMMENT("Entry:");
4360 // No need for RuntimeStub frame since it is called only during JIT compilation
4361
4362 // Convert and put result into rax
4363 __ flt_to_flt16(rax, xmm0, xmm1);
4364
4365 __ ret(0);
4366
4367 // record the stub entry and end
4368 store_archive_data(stub_id, start, __ pc());
4369
4370 return start;
4371 }
4372
4373 address StubGenerator::generate_cont_thaw(StubId stub_id) {
4374 if (!Continuations::enabled()) return nullptr;
4375
4376 bool return_barrier;
4377 bool return_barrier_exception;
4378 Continuation::thaw_kind kind;
4379
4380 switch (stub_id) {
4381 case StubId::stubgen_cont_thaw_id:
4382 return_barrier = false;
4383 return_barrier_exception = false;
4384 kind = Continuation::thaw_top;
4385 break;
4386 case StubId::stubgen_cont_returnBarrier_id:
4387 return_barrier = true;
4388 return_barrier_exception = false;
4389 kind = Continuation::thaw_return_barrier;
4390 break;
4391 case StubId::stubgen_cont_returnBarrierExc_id:
4392 return_barrier = true;
4410 if (!return_barrier) {
4411 // Pop return address. If we don't do this, we get a drift,
4412 // where the bottom-most frozen frame continuously grows.
4413 __ pop(c_rarg3);
4414 } else {
4415 __ movptr(rsp, Address(r15_thread, JavaThread::cont_entry_offset()));
4416 }
4417
4418 #ifdef ASSERT
4419 {
4420 Label L_good_sp;
4421 __ cmpptr(rsp, Address(r15_thread, JavaThread::cont_entry_offset()));
4422 __ jcc(Assembler::equal, L_good_sp);
4423 __ stop("Incorrect rsp at thaw entry");
4424 __ BIND(L_good_sp);
4425 }
4426 #endif // ASSERT
4427
4428 if (return_barrier) {
4429 // Preserve possible return value from a method returning to the return barrier.
4430 __ push_ppx(rax);
4431 __ push_d(xmm0);
4432 }
4433
4434 __ movptr(c_rarg0, r15_thread);
4435 __ movptr(c_rarg1, (return_barrier ? 1 : 0));
4436 __ call_VM_leaf(CAST_FROM_FN_PTR(address, Continuation::prepare_thaw), 2);
4437 __ movptr(rbx, rax);
4438
4439 if (return_barrier) {
4440 // Restore return value from a method returning to the return barrier.
4441 // No safepoint in the call to thaw, so even an oop return value should be OK.
4442 __ pop_d(xmm0);
4443 __ pop_ppx(rax);
4444 }
4445
4446 #ifdef ASSERT
4447 {
4448 Label L_good_sp;
4449 __ cmpptr(rsp, Address(r15_thread, JavaThread::cont_entry_offset()));
4450 __ jcc(Assembler::equal, L_good_sp);
4451 __ stop("Incorrect rsp after prepare thaw");
4452 __ BIND(L_good_sp);
4453 }
4454 #endif // ASSERT
4455
4456 // rbx contains the size of the frames to thaw, 0 if overflow or no more frames
4457 Label L_thaw_success;
4458 __ testptr(rbx, rbx);
4459 __ jccb(Assembler::notZero, L_thaw_success);
4460 __ jump(RuntimeAddress(SharedRuntime::throw_StackOverflowError_entry()));
4461 __ bind(L_thaw_success);
4462
4463 // Make room for the thawed frames and align the stack.
4464 __ subptr(rsp, rbx);
4465 __ andptr(rsp, -StackAlignmentInBytes);
4466
4467 if (return_barrier) {
4468 // Preserve possible return value from a method returning to the return barrier. (Again.)
4469 __ push_ppx(rax);
4470 __ push_d(xmm0);
4471 }
4472
4473 // If we want, we can templatize thaw by kind, and have three different entries.
4474 __ movptr(c_rarg0, r15_thread);
4475 __ movptr(c_rarg1, kind);
4476 __ call_VM_leaf(Continuation::thaw_entry(), 2);
4477 __ movptr(rbx, rax);
4478
4479 if (return_barrier) {
4480 // Restore return value from a method returning to the return barrier. (Again.)
4481 // No safepoint in the call to thaw, so even an oop return value should be OK.
4482 __ pop_d(xmm0);
4483 __ pop_ppx(rax);
4484 } else {
4485 // Return 0 (success) from doYield.
4486 __ xorptr(rax, rax);
4487 }
4488
4489 // After thawing, rbx is the SP of the yielding frame.
4490 // Move there, and then to saved RBP slot.
4491 __ movptr(rsp, rbx);
4492 __ subptr(rsp, 2*wordSize);
4493
4494 if (return_barrier_exception) {
4495 __ movptr(c_rarg0, r15_thread);
4496 __ movptr(c_rarg1, Address(rsp, wordSize)); // return address
4497
4498 // rax still holds the original exception oop, save it before the call
4499 __ push_ppx(rax);
4500
4501 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), 2);
4502 __ movptr(rbx, rax);
4503
|
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 "asm/assembler.hpp"
26 #include "asm/macroAssembler.hpp"
27 #include "classfile/javaClasses.hpp"
28 #include "classfile/vmIntrinsics.hpp"
29 #include "compiler/oopMap.hpp"
30 #include "gc/shared/barrierSet.hpp"
31 #include "gc/shared/barrierSetAssembler.hpp"
32 #include "gc/shared/barrierSetNMethod.hpp"
33 #include "gc/shared/gc_globals.hpp"
34 #include "memory/universe.hpp"
35 #include "oops/inlineKlass.hpp"
36 #include "prims/jvmtiExport.hpp"
37 #include "prims/upcallLinker.hpp"
38 #include "runtime/arguments.hpp"
39 #include "runtime/continuationEntry.hpp"
40 #include "runtime/javaThread.hpp"
41 #include "runtime/sharedRuntime.hpp"
42 #include "runtime/stubRoutines.hpp"
43 #include "utilities/macros.hpp"
44 #include "vmreg_x86.inline.hpp"
45 #include "stubGenerator_x86_64.hpp"
46 #ifdef COMPILER2
47 #include "opto/runtime.hpp"
48 #include "opto/c2_globals.hpp"
49 #endif
50
51 // For a more detailed description of the stub routine structure
52 // see the comment in stubRoutines.hpp
53
54 #define __ _masm->
55 #define TIMES_OOP (UseCompressedOops ? Address::times_4 : Address::times_8)
56
57 #ifdef PRODUCT
58 #define BLOCK_COMMENT(str) /* nothing */
59 #else
60 #define BLOCK_COMMENT(str) __ block_comment(str)
61 #endif // PRODUCT
62
63 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
64
294 __ movl(c_rarg1, c_rarg3); // parameter counter is in c_rarg1
295 __ BIND(loop);
296 __ movptr(rax, Address(c_rarg2, 0));// get parameter
297 __ addptr(c_rarg2, wordSize); // advance to next parameter
298 __ decrementl(c_rarg1); // decrement counter
299 __ push(rax); // pass parameter
300 __ jcc(Assembler::notZero, loop);
301
302 // call Java function
303 __ BIND(parameters_done);
304 __ movptr(rbx, method); // get Method*
305 __ movptr(c_rarg1, entry_point); // get entry_point
306 __ mov(r13, rsp); // set sender sp
307 BLOCK_COMMENT("call Java function");
308 __ call(c_rarg1);
309
310 BLOCK_COMMENT("call_stub_return_address:");
311 return_address = __ pc();
312 entries.append(return_address);
313
314 // All of j_rargN + rax may be used to return inline type fields so be careful
315 // not to clobber those. See SharedRuntime::java_return_convention().
316
317 // store result depending on type (everything that is not
318 // T_OBJECT, T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT)
319 __ movptr(r13, result);
320 Label is_long, is_float, is_double, check_prim, exit;
321 __ movl(rbx, result_type);
322 __ cmpl(rbx, T_OBJECT);
323 __ jcc(Assembler::equal, check_prim);
324 __ cmpl(rbx, T_LONG);
325 __ jcc(Assembler::equal, is_long);
326 __ cmpl(rbx, T_FLOAT);
327 __ jcc(Assembler::equal, is_float);
328 __ cmpl(rbx, T_DOUBLE);
329 __ jcc(Assembler::equal, is_double);
330 #ifdef ASSERT
331 // make sure the type is INT
332 {
333 Label L;
334 __ cmpl(rbx, T_INT);
335 __ jcc(Assembler::equal, L);
336 __ stop("StubRoutines::call_stub: unexpected result type");
337 __ bind(L);
338 }
339 #endif
340
341 // handle T_INT case
342 __ movl(Address(r13, 0), rax);
343
344 __ BIND(exit);
345
346 // pop parameters
347 __ lea(rsp, rsp_after_call);
348
349 #ifdef ASSERT
350 // verify that threads correspond
351 {
352 Label L1, L2, L3;
353 __ cmpptr(r15_thread, thread);
354 __ jcc(Assembler::equal, L1);
355 __ stop("StubRoutines::call_stub: r15_thread is corrupted");
356 __ bind(L1);
357 __ get_thread_slow(rbx);
358 __ cmpptr(r15_thread, thread);
359 __ jcc(Assembler::equal, L2);
360 __ stop("StubRoutines::call_stub: r15_thread is modified by call");
361 __ bind(L2);
362 __ cmpptr(r15_thread, rbx);
380 __ movptr(r13, r13_save);
381 __ movptr(r12, r12_save);
382 __ movptr(rbx, rbx_save);
383
384 #ifdef _WIN64
385 __ movptr(rdi, rdi_save);
386 __ movptr(rsi, rsi_save);
387 #else
388 __ ldmxcsr(mxcsr_save);
389 #endif
390
391 // restore rsp
392 __ addptr(rsp, -rsp_after_call_off * wordSize);
393
394 // return
395 __ vzeroupper();
396 __ pop(rbp);
397 __ ret(0);
398
399 // handle return types different from T_INT
400 __ BIND(check_prim);
401 if (InlineTypeReturnedAsFields) {
402 // Check for scalarized return value
403 __ testptr(rax, 1);
404 __ jcc(Assembler::zero, is_long);
405 // Load pack handler address
406 __ andptr(rax, -2);
407 __ movptr(rax, Address(rax, InlineKlass::adr_members_offset()));
408 __ movptr(rbx, Address(rax, InlineKlass::pack_handler_jobject_offset()));
409 // Call pack handler to initialize the buffer
410 __ call(rbx);
411 __ jmp(exit);
412 }
413 __ BIND(is_long);
414 __ movq(Address(r13, 0), rax);
415 __ jmp(exit);
416
417 __ BIND(is_float);
418 __ movflt(Address(r13, 0), xmm0);
419 __ jmp(exit);
420
421 __ BIND(is_double);
422 __ movdbl(Address(r13, 0), xmm0);
423 __ jmp(exit);
424
425 // record the stub entry and end plus the auxiliary entry
426 store_archive_data(stub_id, start, __ pc(), &entries);
427
428 return start;
429 }
430
431 // Return point for a Java call if there's an exception thrown in
432 // Java code. The exception is caught and transformed into a
433 // pending exception stored in JavaThread that can be tested from
434 // within the VM.
435 //
436 // Note: Usually the parameters are removed by the callee. In case
437 // of an exception crossing an activation frame boundary, that is
438 // not the case if the callee is compiled code => need to setup the
439 // rsp.
440 //
441 // rax: exception oop
442
4373 return start;
4374 }
4375 StubCodeMark mark(this, stub_id);
4376
4377 start = __ pc();
4378
4379 BLOCK_COMMENT("Entry:");
4380 // No need for RuntimeStub frame since it is called only during JIT compilation
4381
4382 // Convert and put result into rax
4383 __ flt_to_flt16(rax, xmm0, xmm1);
4384
4385 __ ret(0);
4386
4387 // record the stub entry and end
4388 store_archive_data(stub_id, start, __ pc());
4389
4390 return start;
4391 }
4392
4393 static void save_return_registers(MacroAssembler* masm) {
4394 masm->push_ppx(rax);
4395 if (InlineTypeReturnedAsFields) {
4396 masm->push(rdi);
4397 masm->push(rsi);
4398 masm->push(rdx);
4399 masm->push(rcx);
4400 masm->push(r8);
4401 masm->push(r9);
4402 }
4403 masm->push_d(xmm0);
4404 if (InlineTypeReturnedAsFields) {
4405 masm->push_d(xmm1);
4406 masm->push_d(xmm2);
4407 masm->push_d(xmm3);
4408 masm->push_d(xmm4);
4409 masm->push_d(xmm5);
4410 masm->push_d(xmm6);
4411 masm->push_d(xmm7);
4412 }
4413 #ifdef ASSERT
4414 masm->movq(rax, 0xBADC0FFE);
4415 masm->movq(rdi, rax);
4416 masm->movq(rsi, rax);
4417 masm->movq(rdx, rax);
4418 masm->movq(rcx, rax);
4419 masm->movq(r8, rax);
4420 masm->movq(r9, rax);
4421 masm->movq(xmm0, rax);
4422 masm->movq(xmm1, rax);
4423 masm->movq(xmm2, rax);
4424 masm->movq(xmm3, rax);
4425 masm->movq(xmm4, rax);
4426 masm->movq(xmm5, rax);
4427 masm->movq(xmm6, rax);
4428 masm->movq(xmm7, rax);
4429 #endif
4430 }
4431
4432 static void restore_return_registers(MacroAssembler* masm) {
4433 if (InlineTypeReturnedAsFields) {
4434 masm->pop_d(xmm7);
4435 masm->pop_d(xmm6);
4436 masm->pop_d(xmm5);
4437 masm->pop_d(xmm4);
4438 masm->pop_d(xmm3);
4439 masm->pop_d(xmm2);
4440 masm->pop_d(xmm1);
4441 }
4442 masm->pop_d(xmm0);
4443 if (InlineTypeReturnedAsFields) {
4444 masm->pop(r9);
4445 masm->pop(r8);
4446 masm->pop(rcx);
4447 masm->pop(rdx);
4448 masm->pop(rsi);
4449 masm->pop(rdi);
4450 }
4451 masm->pop_ppx(rax);
4452 }
4453
4454 address StubGenerator::generate_cont_thaw(StubId stub_id) {
4455 if (!Continuations::enabled()) return nullptr;
4456
4457 bool return_barrier;
4458 bool return_barrier_exception;
4459 Continuation::thaw_kind kind;
4460
4461 switch (stub_id) {
4462 case StubId::stubgen_cont_thaw_id:
4463 return_barrier = false;
4464 return_barrier_exception = false;
4465 kind = Continuation::thaw_top;
4466 break;
4467 case StubId::stubgen_cont_returnBarrier_id:
4468 return_barrier = true;
4469 return_barrier_exception = false;
4470 kind = Continuation::thaw_return_barrier;
4471 break;
4472 case StubId::stubgen_cont_returnBarrierExc_id:
4473 return_barrier = true;
4491 if (!return_barrier) {
4492 // Pop return address. If we don't do this, we get a drift,
4493 // where the bottom-most frozen frame continuously grows.
4494 __ pop(c_rarg3);
4495 } else {
4496 __ movptr(rsp, Address(r15_thread, JavaThread::cont_entry_offset()));
4497 }
4498
4499 #ifdef ASSERT
4500 {
4501 Label L_good_sp;
4502 __ cmpptr(rsp, Address(r15_thread, JavaThread::cont_entry_offset()));
4503 __ jcc(Assembler::equal, L_good_sp);
4504 __ stop("Incorrect rsp at thaw entry");
4505 __ BIND(L_good_sp);
4506 }
4507 #endif // ASSERT
4508
4509 if (return_barrier) {
4510 // Preserve possible return value from a method returning to the return barrier.
4511 save_return_registers(_masm);
4512 }
4513
4514 __ movptr(c_rarg0, r15_thread);
4515 __ movptr(c_rarg1, (return_barrier ? 1 : 0));
4516 __ call_VM_leaf(CAST_FROM_FN_PTR(address, Continuation::prepare_thaw), 2);
4517 __ movptr(rbx, rax);
4518
4519 if (return_barrier) {
4520 // Restore return value from a method returning to the return barrier.
4521 // No safepoint in the call to thaw, so even an oop return value should be OK.
4522 restore_return_registers(_masm);
4523 }
4524
4525 #ifdef ASSERT
4526 {
4527 Label L_good_sp;
4528 __ cmpptr(rsp, Address(r15_thread, JavaThread::cont_entry_offset()));
4529 __ jcc(Assembler::equal, L_good_sp);
4530 __ stop("Incorrect rsp after prepare thaw");
4531 __ BIND(L_good_sp);
4532 }
4533 #endif // ASSERT
4534
4535 // rbx contains the size of the frames to thaw, 0 if overflow or no more frames
4536 Label L_thaw_success;
4537 __ testptr(rbx, rbx);
4538 __ jccb(Assembler::notZero, L_thaw_success);
4539 __ jump(RuntimeAddress(SharedRuntime::throw_StackOverflowError_entry()));
4540 __ bind(L_thaw_success);
4541
4542 // Make room for the thawed frames and align the stack.
4543 __ subptr(rsp, rbx);
4544 __ andptr(rsp, -StackAlignmentInBytes);
4545
4546 if (return_barrier) {
4547 // Preserve possible return value from a method returning to the return barrier. (Again.)
4548 save_return_registers(_masm);
4549 }
4550
4551 // If we want, we can templatize thaw by kind, and have three different entries.
4552 __ movptr(c_rarg0, r15_thread);
4553 __ movptr(c_rarg1, kind);
4554 __ call_VM_leaf(Continuation::thaw_entry(), 2);
4555 __ movptr(rbx, rax);
4556
4557 if (return_barrier) {
4558 // Restore return value from a method returning to the return barrier. (Again.)
4559 // No safepoint in the call to thaw, so even an oop return value should be OK.
4560 restore_return_registers(_masm);
4561 } else {
4562 // Return 0 (success) from doYield.
4563 __ xorptr(rax, rax);
4564 }
4565
4566 // After thawing, rbx is the SP of the yielding frame.
4567 // Move there, and then to saved RBP slot.
4568 __ movptr(rsp, rbx);
4569 __ subptr(rsp, 2*wordSize);
4570
4571 if (return_barrier_exception) {
4572 __ movptr(c_rarg0, r15_thread);
4573 __ movptr(c_rarg1, Address(rsp, wordSize)); // return address
4574
4575 // rax still holds the original exception oop, save it before the call
4576 __ push_ppx(rax);
4577
4578 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), 2);
4579 __ movptr(rbx, rax);
4580
|