319 __ BIND(loop); 320 __ movptr(rax, Address(c_rarg2, 0));// get parameter 321 __ addptr(c_rarg2, wordSize); // advance to next parameter 322 __ decrementl(c_rarg1); // decrement counter 323 __ push(rax); // pass parameter 324 __ jcc(Assembler::notZero, loop); 325 326 // call Java function 327 __ BIND(parameters_done); 328 __ movptr(rbx, method); // get Method* 329 __ movptr(c_rarg1, entry_point); // get entry_point 330 __ mov(r13, rsp); // set sender sp 331 BLOCK_COMMENT("call Java function"); 332 __ call(c_rarg1); 333 334 BLOCK_COMMENT("call_stub_return_address:"); 335 return_address = __ pc(); 336 337 // store result depending on type (everything that is not 338 // T_OBJECT, T_VALUETYPE, T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT) 339 __ movptr(c_rarg0, result); 340 Label is_long, is_float, is_double, exit; 341 __ movl(c_rarg1, result_type); 342 __ cmpl(c_rarg1, T_OBJECT); 343 __ jcc(Assembler::equal, is_long); 344 __ cmpl(c_rarg1, T_VALUETYPE); 345 __ jcc(Assembler::equal, is_long); 346 __ cmpl(c_rarg1, T_LONG); 347 __ jcc(Assembler::equal, is_long); 348 __ cmpl(c_rarg1, T_FLOAT); 349 __ jcc(Assembler::equal, is_float); 350 __ cmpl(c_rarg1, T_DOUBLE); 351 __ jcc(Assembler::equal, is_double); 352 353 // handle T_INT case 354 __ movl(Address(c_rarg0, 0), rax); 355 356 __ BIND(exit); 357 358 // pop parameters 359 __ lea(rsp, rsp_after_call); 360 361 #ifdef ASSERT 362 // verify that threads correspond 363 { 364 Label L1, L2, L3; 365 __ cmpptr(r15_thread, thread); 366 __ jcc(Assembler::equal, L1); 367 __ stop("StubRoutines::call_stub: r15_thread is corrupted"); 368 __ bind(L1); 369 __ get_thread(rbx); 370 __ cmpptr(r15_thread, thread); 371 __ jcc(Assembler::equal, L2); 372 __ stop("StubRoutines::call_stub: r15_thread is modified by call"); 373 __ bind(L2); 374 __ cmpptr(r15_thread, rbx); 396 __ movptr(r13, r13_save); 397 __ movptr(r12, r12_save); 398 __ movptr(rbx, rbx_save); 399 400 #ifdef _WIN64 401 __ movptr(rdi, rdi_save); 402 __ movptr(rsi, rsi_save); 403 #else 404 __ ldmxcsr(mxcsr_save); 405 #endif 406 407 // restore rsp 408 __ addptr(rsp, -rsp_after_call_off * wordSize); 409 410 // return 411 __ vzeroupper(); 412 __ pop(rbp); 413 __ ret(0); 414 415 // handle return types different from T_INT 416 __ BIND(is_long); 417 __ movq(Address(c_rarg0, 0), rax); 418 __ jmp(exit); 419 420 __ BIND(is_float); 421 __ movflt(Address(c_rarg0, 0), xmm0); 422 __ jmp(exit); 423 424 __ BIND(is_double); 425 __ movdbl(Address(c_rarg0, 0), xmm0); 426 __ jmp(exit); 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 443 address generate_catch_exception() { 444 StubCodeMark mark(this, "StubRoutines", "catch_exception"); 445 address start = __ pc(); 5881 5882 RuntimeStub* stub = RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_in_words, oop_maps, false); 5883 return stub->entry_point(); 5884 } 5885 5886 // Initialization 5887 void generate_initial() { 5888 // Generates all stubs and initializes the entry points 5889 5890 // This platform-specific settings are needed by generate_call_stub() 5891 create_control_words(); 5892 5893 // entry points that exist in all platforms Note: This is code 5894 // that could be shared among different platforms - however the 5895 // benefit seems to be smaller than the disadvantage of having a 5896 // much more complicated generator structure. See also comment in 5897 // stubRoutines.hpp. 5898 5899 StubRoutines::_forward_exception_entry = generate_forward_exception(); 5900 5901 StubRoutines::_call_stub_entry = 5902 generate_call_stub(StubRoutines::_call_stub_return_address); 5903 5904 // is referenced by megamorphic call 5905 StubRoutines::_catch_exception_entry = generate_catch_exception(); 5906 5907 // atomic calls 5908 StubRoutines::_atomic_xchg_entry = generate_atomic_xchg(); 5909 StubRoutines::_atomic_xchg_long_entry = generate_atomic_xchg_long(); 5910 StubRoutines::_atomic_cmpxchg_entry = generate_atomic_cmpxchg(); 5911 StubRoutines::_atomic_cmpxchg_byte_entry = generate_atomic_cmpxchg_byte(); 5912 StubRoutines::_atomic_cmpxchg_long_entry = generate_atomic_cmpxchg_long(); 5913 StubRoutines::_atomic_add_entry = generate_atomic_add(); 5914 StubRoutines::_atomic_add_long_entry = generate_atomic_add_long(); 5915 StubRoutines::_fence_entry = generate_orderaccess_fence(); 5916 5917 // platform dependent 5918 StubRoutines::x86::_get_previous_fp_entry = generate_get_previous_fp(); 5919 StubRoutines::x86::_get_previous_sp_entry = generate_get_previous_sp(); 5920 5921 StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr(); 5922 5967 } 5968 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog)) { 5969 StubRoutines::_dlog = generate_libmLog(); 5970 } 5971 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog10)) { 5972 StubRoutines::_dlog10 = generate_libmLog10(); 5973 } 5974 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dpow)) { 5975 StubRoutines::_dpow = generate_libmPow(); 5976 } 5977 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin)) { 5978 StubRoutines::_dsin = generate_libmSin(); 5979 } 5980 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos)) { 5981 StubRoutines::_dcos = generate_libmCos(); 5982 } 5983 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtan)) { 5984 StubRoutines::_dtan = generate_libmTan(); 5985 } 5986 } 5987 5988 StubRoutines::_load_value_type_fields_in_regs = generate_return_value_stub(CAST_FROM_FN_PTR(address, SharedRuntime::load_value_type_fields_in_regs), "load_value_type_fields_in_regs", false); 5989 StubRoutines::_store_value_type_fields_to_buf = generate_return_value_stub(CAST_FROM_FN_PTR(address, SharedRuntime::store_value_type_fields_to_buf), "store_value_type_fields_to_buf", true); 5990 } 5991 5992 void generate_all() { 5993 // Generates all stubs and initializes the entry points 5994 5995 // These entry points require SharedInfo::stack0 to be set up in 5996 // non-core builds and need to be relocatable, so they each 5997 // fabricate a RuntimeStub internally. 5998 StubRoutines::_throw_AbstractMethodError_entry = 5999 generate_throw_exception("AbstractMethodError throw_exception", 6000 CAST_FROM_FN_PTR(address, 6001 SharedRuntime:: 6002 throw_AbstractMethodError)); 6003 6004 StubRoutines::_throw_IncompatibleClassChangeError_entry = 6005 generate_throw_exception("IncompatibleClassChangeError throw_exception", 6006 CAST_FROM_FN_PTR(address, 6007 SharedRuntime:: 6008 throw_IncompatibleClassChangeError)); 6009 | 319 __ BIND(loop); 320 __ movptr(rax, Address(c_rarg2, 0));// get parameter 321 __ addptr(c_rarg2, wordSize); // advance to next parameter 322 __ decrementl(c_rarg1); // decrement counter 323 __ push(rax); // pass parameter 324 __ jcc(Assembler::notZero, loop); 325 326 // call Java function 327 __ BIND(parameters_done); 328 __ movptr(rbx, method); // get Method* 329 __ movptr(c_rarg1, entry_point); // get entry_point 330 __ mov(r13, rsp); // set sender sp 331 BLOCK_COMMENT("call Java function"); 332 __ call(c_rarg1); 333 334 BLOCK_COMMENT("call_stub_return_address:"); 335 return_address = __ pc(); 336 337 // store result depending on type (everything that is not 338 // T_OBJECT, T_VALUETYPE, T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT) 339 __ movptr(r13, result); 340 Label is_long, is_float, is_double, is_value, exit; 341 __ movl(rbx, result_type); 342 __ cmpl(rbx, T_OBJECT); 343 __ jcc(Assembler::equal, is_long); 344 __ cmpl(rbx, T_VALUETYPE); 345 __ jcc(Assembler::equal, is_value); 346 __ cmpl(rbx, T_LONG); 347 __ jcc(Assembler::equal, is_long); 348 __ cmpl(rbx, T_FLOAT); 349 __ jcc(Assembler::equal, is_float); 350 __ cmpl(rbx, T_DOUBLE); 351 __ jcc(Assembler::equal, is_double); 352 353 // handle T_INT case 354 __ movl(Address(r13, 0), rax); 355 356 __ BIND(exit); 357 358 // pop parameters 359 __ lea(rsp, rsp_after_call); 360 361 #ifdef ASSERT 362 // verify that threads correspond 363 { 364 Label L1, L2, L3; 365 __ cmpptr(r15_thread, thread); 366 __ jcc(Assembler::equal, L1); 367 __ stop("StubRoutines::call_stub: r15_thread is corrupted"); 368 __ bind(L1); 369 __ get_thread(rbx); 370 __ cmpptr(r15_thread, thread); 371 __ jcc(Assembler::equal, L2); 372 __ stop("StubRoutines::call_stub: r15_thread is modified by call"); 373 __ bind(L2); 374 __ cmpptr(r15_thread, rbx); 396 __ movptr(r13, r13_save); 397 __ movptr(r12, r12_save); 398 __ movptr(rbx, rbx_save); 399 400 #ifdef _WIN64 401 __ movptr(rdi, rdi_save); 402 __ movptr(rsi, rsi_save); 403 #else 404 __ ldmxcsr(mxcsr_save); 405 #endif 406 407 // restore rsp 408 __ addptr(rsp, -rsp_after_call_off * wordSize); 409 410 // return 411 __ vzeroupper(); 412 __ pop(rbp); 413 __ ret(0); 414 415 // handle return types different from T_INT 416 __ BIND(is_value); 417 if (ValueTypeReturnedAsFields) { 418 // Handle value type returned as fields 419 __ store_value_type_fields_to_buf(NULL); 420 __ movptr(r13, result); 421 } 422 __ BIND(is_long); 423 __ movq(Address(r13, 0), rax); 424 __ jmp(exit); 425 426 __ BIND(is_float); 427 __ movflt(Address(r13, 0), xmm0); 428 __ jmp(exit); 429 430 __ BIND(is_double); 431 __ movdbl(Address(r13, 0), xmm0); 432 __ jmp(exit); 433 434 return start; 435 } 436 437 // Return point for a Java call if there's an exception thrown in 438 // Java code. The exception is caught and transformed into a 439 // pending exception stored in JavaThread that can be tested from 440 // within the VM. 441 // 442 // Note: Usually the parameters are removed by the callee. In case 443 // of an exception crossing an activation frame boundary, that is 444 // not the case if the callee is compiled code => need to setup the 445 // rsp. 446 // 447 // rax: exception oop 448 449 address generate_catch_exception() { 450 StubCodeMark mark(this, "StubRoutines", "catch_exception"); 451 address start = __ pc(); 5887 5888 RuntimeStub* stub = RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_in_words, oop_maps, false); 5889 return stub->entry_point(); 5890 } 5891 5892 // Initialization 5893 void generate_initial() { 5894 // Generates all stubs and initializes the entry points 5895 5896 // This platform-specific settings are needed by generate_call_stub() 5897 create_control_words(); 5898 5899 // entry points that exist in all platforms Note: This is code 5900 // that could be shared among different platforms - however the 5901 // benefit seems to be smaller than the disadvantage of having a 5902 // much more complicated generator structure. See also comment in 5903 // stubRoutines.hpp. 5904 5905 StubRoutines::_forward_exception_entry = generate_forward_exception(); 5906 5907 // Generate these first because they are called from other stubs 5908 StubRoutines::_load_value_type_fields_in_regs = generate_return_value_stub(CAST_FROM_FN_PTR(address, SharedRuntime::load_value_type_fields_in_regs), "load_value_type_fields_in_regs", false); 5909 StubRoutines::_store_value_type_fields_to_buf = generate_return_value_stub(CAST_FROM_FN_PTR(address, SharedRuntime::store_value_type_fields_to_buf), "store_value_type_fields_to_buf", true); 5910 5911 StubRoutines::_call_stub_entry = generate_call_stub(StubRoutines::_call_stub_return_address); 5912 5913 // is referenced by megamorphic call 5914 StubRoutines::_catch_exception_entry = generate_catch_exception(); 5915 5916 // atomic calls 5917 StubRoutines::_atomic_xchg_entry = generate_atomic_xchg(); 5918 StubRoutines::_atomic_xchg_long_entry = generate_atomic_xchg_long(); 5919 StubRoutines::_atomic_cmpxchg_entry = generate_atomic_cmpxchg(); 5920 StubRoutines::_atomic_cmpxchg_byte_entry = generate_atomic_cmpxchg_byte(); 5921 StubRoutines::_atomic_cmpxchg_long_entry = generate_atomic_cmpxchg_long(); 5922 StubRoutines::_atomic_add_entry = generate_atomic_add(); 5923 StubRoutines::_atomic_add_long_entry = generate_atomic_add_long(); 5924 StubRoutines::_fence_entry = generate_orderaccess_fence(); 5925 5926 // platform dependent 5927 StubRoutines::x86::_get_previous_fp_entry = generate_get_previous_fp(); 5928 StubRoutines::x86::_get_previous_sp_entry = generate_get_previous_sp(); 5929 5930 StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr(); 5931 5976 } 5977 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog)) { 5978 StubRoutines::_dlog = generate_libmLog(); 5979 } 5980 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog10)) { 5981 StubRoutines::_dlog10 = generate_libmLog10(); 5982 } 5983 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dpow)) { 5984 StubRoutines::_dpow = generate_libmPow(); 5985 } 5986 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin)) { 5987 StubRoutines::_dsin = generate_libmSin(); 5988 } 5989 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos)) { 5990 StubRoutines::_dcos = generate_libmCos(); 5991 } 5992 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtan)) { 5993 StubRoutines::_dtan = generate_libmTan(); 5994 } 5995 } 5996 } 5997 5998 void generate_all() { 5999 // Generates all stubs and initializes the entry points 6000 6001 // These entry points require SharedInfo::stack0 to be set up in 6002 // non-core builds and need to be relocatable, so they each 6003 // fabricate a RuntimeStub internally. 6004 StubRoutines::_throw_AbstractMethodError_entry = 6005 generate_throw_exception("AbstractMethodError throw_exception", 6006 CAST_FROM_FN_PTR(address, 6007 SharedRuntime:: 6008 throw_AbstractMethodError)); 6009 6010 StubRoutines::_throw_IncompatibleClassChangeError_entry = 6011 generate_throw_exception("IncompatibleClassChangeError throw_exception", 6012 CAST_FROM_FN_PTR(address, 6013 SharedRuntime:: 6014 throw_IncompatibleClassChangeError)); 6015 |