< prev index next >

src/hotspot/cpu/x86/stubGenerator_x86_64.cpp

Print this page

 325     __ movl(c_rarg1, c_rarg3);            // parameter counter is in c_rarg1
 326     __ BIND(loop);
 327     __ movptr(rax, Address(c_rarg2, 0));// get parameter
 328     __ addptr(c_rarg2, wordSize);       // advance to next parameter
 329     __ decrementl(c_rarg1);             // decrement counter
 330     __ push(rax);                       // pass parameter
 331     __ jcc(Assembler::notZero, loop);
 332 
 333     // call Java function
 334     __ BIND(parameters_done);
 335     __ movptr(rbx, method);             // get Method*
 336     __ movptr(c_rarg1, entry_point);    // get entry_point
 337     __ mov(r13, rsp);                   // set sender sp
 338     BLOCK_COMMENT("call Java function");
 339     __ call(c_rarg1);
 340 
 341     BLOCK_COMMENT("call_stub_return_address:");
 342     return_address = __ pc();
 343 
 344     // store result depending on type (everything that is not
 345     // T_OBJECT, T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT)
 346     __ movptr(c_rarg0, result);
 347     Label is_long, is_float, is_double, exit;
 348     __ movl(c_rarg1, result_type);
 349     __ cmpl(c_rarg1, T_OBJECT);
 350     __ jcc(Assembler::equal, is_long);
 351     __ cmpl(c_rarg1, T_LONG);


 352     __ jcc(Assembler::equal, is_long);
 353     __ cmpl(c_rarg1, T_FLOAT);
 354     __ jcc(Assembler::equal, is_float);
 355     __ cmpl(c_rarg1, T_DOUBLE);
 356     __ jcc(Assembler::equal, is_double);
 357 
 358     // handle T_INT case
 359     __ movl(Address(c_rarg0, 0), rax);
 360 
 361     __ BIND(exit);
 362 
 363     // pop parameters
 364     __ lea(rsp, rsp_after_call);
 365 
 366 #ifdef ASSERT
 367     // verify that threads correspond
 368     {
 369      Label L1, L2, L3;
 370       __ cmpptr(r15_thread, thread);
 371       __ jcc(Assembler::equal, L1);
 372       __ stop("StubRoutines::call_stub: r15_thread is corrupted");
 373       __ bind(L1);
 374       __ get_thread(rbx);
 375       __ cmpptr(r15_thread, thread);
 376       __ jcc(Assembler::equal, L2);
 377       __ stop("StubRoutines::call_stub: r15_thread is modified by call");
 378       __ bind(L2);
 379       __ cmpptr(r15_thread, rbx);

 401     __ movptr(r13, r13_save);
 402     __ movptr(r12, r12_save);
 403     __ movptr(rbx, rbx_save);
 404 
 405 #ifdef _WIN64
 406     __ movptr(rdi, rdi_save);
 407     __ movptr(rsi, rsi_save);
 408 #else
 409     __ ldmxcsr(mxcsr_save);
 410 #endif
 411 
 412     // restore rsp
 413     __ addptr(rsp, -rsp_after_call_off * wordSize);
 414 
 415     // return
 416     __ vzeroupper();
 417     __ pop(rbp);
 418     __ ret(0);
 419 
 420     // handle return types different from T_INT













 421     __ BIND(is_long);
 422     __ movq(Address(c_rarg0, 0), rax);
 423     __ jmp(exit);
 424 
 425     __ BIND(is_float);
 426     __ movflt(Address(c_rarg0, 0), xmm0);
 427     __ jmp(exit);
 428 
 429     __ BIND(is_double);
 430     __ movdbl(Address(c_rarg0, 0), xmm0);
 431     __ jmp(exit);
 432 
 433     return start;
 434   }
 435 
 436   // Return point for a Java call if there's an exception thrown in
 437   // Java code.  The exception is caught and transformed into a
 438   // pending exception stored in JavaThread that can be tested from
 439   // within the VM.
 440   //
 441   // Note: Usually the parameters are removed by the callee. In case
 442   // of an exception crossing an activation frame boundary, that is
 443   // not the case if the callee is compiled code => need to setup the
 444   // rsp.
 445   //
 446   // rax: exception oop
 447 
 448   address generate_catch_exception() {
 449     StubCodeMark mark(this, "StubRoutines", "catch_exception");
 450     address start = __ pc();

2825     // Copy from low to high addresses, indexed from the end of each array.
2826     __ lea(end_from, end_from_addr);
2827     __ lea(end_to,   end_to_addr);
2828     __ movptr(r14_length, length);        // save a copy of the length
2829     assert(length == count, "");          // else fix next line:
2830     __ negptr(count);                     // negate and test the length
2831     __ jcc(Assembler::notZero, L_load_element);
2832 
2833     // Empty array:  Nothing to do.
2834     __ xorptr(rax, rax);                  // return 0 on (trivial) success
2835     __ jmp(L_done);
2836 
2837     // ======== begin loop ========
2838     // (Loop is rotated; its entry is L_load_element.)
2839     // Loop control:
2840     //   for (count = -count; count != 0; count++)
2841     // Base pointers src, dst are biased by 8*(count-1),to last element.
2842     __ align(OptoLoopAlignment);
2843 
2844     __ BIND(L_store_element);
2845     __ store_heap_oop(to_element_addr, rax_oop, noreg, noreg, AS_RAW);  // store the oop
2846     __ increment(count);               // increment the count toward zero
2847     __ jcc(Assembler::zero, L_do_card_marks);
2848 
2849     // ======== loop entry is here ========
2850     __ BIND(L_load_element);
2851     __ load_heap_oop(rax_oop, from_element_addr, noreg, noreg, AS_RAW); // load the oop
2852     __ testptr(rax_oop, rax_oop);
2853     __ jcc(Assembler::zero, L_store_element);
2854 
2855     __ load_klass(r11_klass, rax_oop, rscratch1);// query the object klass
2856     generate_type_check(r11_klass, ckoff, ckval, L_store_element);
2857     // ======== end loop ========
2858 
2859     // It was a real error; we must depend on the caller to finish the job.
2860     // Register rdx = -1 * number of *remaining* oops, r14 = *total* oops.
2861     // Emit GC store barriers for the oops we have copied (r14 + rdx),
2862     // and report their number to the caller.
2863     assert_different_registers(rax, r14_length, count, to, end_to, rcx, rscratch1);
2864     Label L_post_barrier;
2865     __ addptr(r14_length, count);     // K = (original - remaining) oops

3120     // 32        30    24            16              8     2                 0
3121     //
3122     //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
3123     //
3124 
3125     const int lh_offset = in_bytes(Klass::layout_helper_offset());
3126 
3127     // Handle objArrays completely differently...
3128     const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
3129     __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
3130     __ jcc(Assembler::equal, L_objArray);
3131 
3132     //  if (src->klass() != dst->klass()) return -1;
3133     __ load_klass(rax, dst, rklass_tmp);
3134     __ cmpq(r10_src_klass, rax);
3135     __ jcc(Assembler::notEqual, L_failed);
3136 
3137     const Register rax_lh = rax;  // layout helper
3138     __ movl(rax_lh, Address(r10_src_klass, lh_offset));
3139 








3140     //  if (!src->is_Array()) return -1;
3141     __ cmpl(rax_lh, Klass::_lh_neutral_value);
3142     __ jcc(Assembler::greaterEqual, L_failed);
3143 
3144     // At this point, it is known to be a typeArray (array_tag 0x3).
3145 #ifdef ASSERT
3146     {
3147       BLOCK_COMMENT("assert primitive array {");
3148       Label L;
3149       __ cmpl(rax_lh, (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift));
3150       __ jcc(Assembler::greaterEqual, L);


3151       __ stop("must be a primitive array");
3152       __ bind(L);
3153       BLOCK_COMMENT("} assert primitive array done");
3154     }
3155 #endif
3156 
3157     arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3158                            r10, L_failed);
3159 
3160     // TypeArrayKlass
3161     //
3162     // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
3163     // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
3164     //
3165 
3166     const Register r10_offset = r10;    // array offset
3167     const Register rax_elsize = rax_lh; // element size
3168 
3169     __ movl(r10_offset, rax_lh);
3170     __ shrl(r10_offset, Klass::_lh_header_size_shift);

3238 
3239     // Identically typed arrays can be copied without element-wise checks.
3240     arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3241                            r10, L_failed);
3242 
3243     __ lea(from, Address(src, src_pos, TIMES_OOP,
3244                  arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
3245     __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
3246                  arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
3247     __ movl2ptr(count, r11_length); // length
3248   __ BIND(L_plain_copy);
3249 #ifdef _WIN64
3250     __ pop(rklass_tmp); // Restore callee-save rdi
3251 #endif
3252     __ jump(RuntimeAddress(oop_copy_entry));
3253 
3254   __ BIND(L_checkcast_copy);
3255     // live at this point:  r10_src_klass, r11_length, rax (dst_klass)
3256     {
3257       // Before looking at dst.length, make sure dst is also an objArray.

3258       __ cmpl(Address(rax, lh_offset), objArray_lh);
3259       __ jcc(Assembler::notEqual, L_failed);
3260 













3261       // It is safe to examine both src.length and dst.length.
3262       arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3263                              rax, L_failed);
3264 
3265       const Register r11_dst_klass = r11;
3266       __ load_klass(r11_dst_klass, dst, rklass_tmp); // reload
3267 
3268       // Marshal the base address arguments now, freeing registers.
3269       __ lea(from, Address(src, src_pos, TIMES_OOP,
3270                    arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
3271       __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
3272                    arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
3273       __ movl(count, length);           // length (reloaded)
3274       Register sco_temp = c_rarg3;      // this register is free now
3275       assert_different_registers(from, to, count, sco_temp,
3276                                  r11_dst_klass, r10_src_klass);
3277       assert_clean_int(count, sco_temp);
3278 
3279       // Generate the type check.
3280       const int sco_offset = in_bytes(Klass::super_check_offset_offset());

7511     __ bind(L);
7512 #endif // ASSERT
7513     __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
7514 
7515 
7516     // codeBlob framesize is in words (not VMRegImpl::slot_size)
7517     RuntimeStub* stub =
7518       RuntimeStub::new_runtime_stub(name,
7519                                     &code,
7520                                     frame_complete,
7521                                     (framesize >> (LogBytesPerWord - LogBytesPerInt)),
7522                                     oop_maps, false);
7523     return stub->entry_point();
7524   }
7525 
7526   void create_control_words() {
7527     // Round to nearest, 64-bit mode, exceptions masked
7528     StubRoutines::x86::_mxcsr_std = 0x1F80;
7529   }
7530 












































































































































7531   // Initialization
7532   void generate_initial() {
7533     // Generates all stubs and initializes the entry points
7534 
7535     // This platform-specific settings are needed by generate_call_stub()
7536     create_control_words();
7537 
7538     // entry points that exist in all platforms Note: This is code
7539     // that could be shared among different platforms - however the
7540     // benefit seems to be smaller than the disadvantage of having a
7541     // much more complicated generator structure. See also comment in
7542     // stubRoutines.hpp.
7543 
7544     StubRoutines::_forward_exception_entry = generate_forward_exception();
7545 
7546     StubRoutines::_call_stub_entry =
7547       generate_call_stub(StubRoutines::_call_stub_return_address);






7548 
7549     // is referenced by megamorphic call
7550     StubRoutines::_catch_exception_entry = generate_catch_exception();
7551 
7552     // atomic calls
7553     StubRoutines::_fence_entry                = generate_orderaccess_fence();
7554 
7555     // platform dependent
7556     StubRoutines::x86::_get_previous_sp_entry = generate_get_previous_sp();
7557 
7558     StubRoutines::x86::_verify_mxcsr_entry    = generate_verify_mxcsr();
7559 
7560     StubRoutines::x86::_f2i_fixup             = generate_f2i_fixup();
7561     StubRoutines::x86::_f2l_fixup             = generate_f2l_fixup();
7562     StubRoutines::x86::_d2i_fixup             = generate_d2i_fixup();
7563     StubRoutines::x86::_d2l_fixup             = generate_d2l_fixup();
7564 
7565     StubRoutines::x86::_float_sign_mask       = generate_fp_mask("float_sign_mask",  0x7FFFFFFF7FFFFFFF);
7566     StubRoutines::x86::_float_sign_flip       = generate_fp_mask("float_sign_flip",  0x8000000080000000);
7567     StubRoutines::x86::_double_sign_mask      = generate_fp_mask("double_sign_mask", 0x7FFFFFFFFFFFFFFF);

 325     __ movl(c_rarg1, c_rarg3);            // parameter counter is in c_rarg1
 326     __ BIND(loop);
 327     __ movptr(rax, Address(c_rarg2, 0));// get parameter
 328     __ addptr(c_rarg2, wordSize);       // advance to next parameter
 329     __ decrementl(c_rarg1);             // decrement counter
 330     __ push(rax);                       // pass parameter
 331     __ jcc(Assembler::notZero, loop);
 332 
 333     // call Java function
 334     __ BIND(parameters_done);
 335     __ movptr(rbx, method);             // get Method*
 336     __ movptr(c_rarg1, entry_point);    // get entry_point
 337     __ mov(r13, rsp);                   // set sender sp
 338     BLOCK_COMMENT("call Java function");
 339     __ call(c_rarg1);
 340 
 341     BLOCK_COMMENT("call_stub_return_address:");
 342     return_address = __ pc();
 343 
 344     // store result depending on type (everything that is not
 345     // T_OBJECT, T_INLINE_TYPE, T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT)
 346     __ movptr(r13, result);
 347     Label is_long, is_float, is_double, is_value, exit;
 348     __ movl(rbx, result_type);
 349     __ cmpl(rbx, T_OBJECT);
 350     __ jcc(Assembler::equal, is_long);
 351     __ cmpl(rbx, T_INLINE_TYPE);
 352     __ jcc(Assembler::equal, is_value);
 353     __ cmpl(rbx, T_LONG);
 354     __ jcc(Assembler::equal, is_long);
 355     __ cmpl(rbx, T_FLOAT);
 356     __ jcc(Assembler::equal, is_float);
 357     __ cmpl(rbx, T_DOUBLE);
 358     __ jcc(Assembler::equal, is_double);
 359 
 360     // handle T_INT case
 361     __ movl(Address(r13, 0), rax);
 362 
 363     __ BIND(exit);
 364 
 365     // pop parameters
 366     __ lea(rsp, rsp_after_call);
 367 
 368 #ifdef ASSERT
 369     // verify that threads correspond
 370     {
 371      Label L1, L2, L3;
 372       __ cmpptr(r15_thread, thread);
 373       __ jcc(Assembler::equal, L1);
 374       __ stop("StubRoutines::call_stub: r15_thread is corrupted");
 375       __ bind(L1);
 376       __ get_thread(rbx);
 377       __ cmpptr(r15_thread, thread);
 378       __ jcc(Assembler::equal, L2);
 379       __ stop("StubRoutines::call_stub: r15_thread is modified by call");
 380       __ bind(L2);
 381       __ cmpptr(r15_thread, rbx);

 403     __ movptr(r13, r13_save);
 404     __ movptr(r12, r12_save);
 405     __ movptr(rbx, rbx_save);
 406 
 407 #ifdef _WIN64
 408     __ movptr(rdi, rdi_save);
 409     __ movptr(rsi, rsi_save);
 410 #else
 411     __ ldmxcsr(mxcsr_save);
 412 #endif
 413 
 414     // restore rsp
 415     __ addptr(rsp, -rsp_after_call_off * wordSize);
 416 
 417     // return
 418     __ vzeroupper();
 419     __ pop(rbp);
 420     __ ret(0);
 421 
 422     // handle return types different from T_INT
 423     __ BIND(is_value);
 424     if (InlineTypeReturnedAsFields) {
 425       // Check for flattened return value
 426       __ testptr(rax, 1);
 427       __ jcc(Assembler::zero, is_long);
 428       // Load pack handler address
 429       __ andptr(rax, -2);
 430       __ movptr(rax, Address(rax, InstanceKlass::adr_inlineklass_fixed_block_offset()));
 431       __ movptr(rbx, Address(rax, InlineKlass::pack_handler_jobject_offset()));
 432       // Call pack handler to initialize the buffer
 433       __ call(rbx);
 434       __ jmp(exit);
 435     }
 436     __ BIND(is_long);
 437     __ movq(Address(r13, 0), rax);
 438     __ jmp(exit);
 439 
 440     __ BIND(is_float);
 441     __ movflt(Address(r13, 0), xmm0);
 442     __ jmp(exit);
 443 
 444     __ BIND(is_double);
 445     __ movdbl(Address(r13, 0), xmm0);
 446     __ jmp(exit);
 447 
 448     return start;
 449   }
 450 
 451   // Return point for a Java call if there's an exception thrown in
 452   // Java code.  The exception is caught and transformed into a
 453   // pending exception stored in JavaThread that can be tested from
 454   // within the VM.
 455   //
 456   // Note: Usually the parameters are removed by the callee. In case
 457   // of an exception crossing an activation frame boundary, that is
 458   // not the case if the callee is compiled code => need to setup the
 459   // rsp.
 460   //
 461   // rax: exception oop
 462 
 463   address generate_catch_exception() {
 464     StubCodeMark mark(this, "StubRoutines", "catch_exception");
 465     address start = __ pc();

2840     // Copy from low to high addresses, indexed from the end of each array.
2841     __ lea(end_from, end_from_addr);
2842     __ lea(end_to,   end_to_addr);
2843     __ movptr(r14_length, length);        // save a copy of the length
2844     assert(length == count, "");          // else fix next line:
2845     __ negptr(count);                     // negate and test the length
2846     __ jcc(Assembler::notZero, L_load_element);
2847 
2848     // Empty array:  Nothing to do.
2849     __ xorptr(rax, rax);                  // return 0 on (trivial) success
2850     __ jmp(L_done);
2851 
2852     // ======== begin loop ========
2853     // (Loop is rotated; its entry is L_load_element.)
2854     // Loop control:
2855     //   for (count = -count; count != 0; count++)
2856     // Base pointers src, dst are biased by 8*(count-1),to last element.
2857     __ align(OptoLoopAlignment);
2858 
2859     __ BIND(L_store_element);
2860     __ store_heap_oop(to_element_addr, rax_oop, noreg, noreg, noreg, AS_RAW);  // store the oop
2861     __ increment(count);               // increment the count toward zero
2862     __ jcc(Assembler::zero, L_do_card_marks);
2863 
2864     // ======== loop entry is here ========
2865     __ BIND(L_load_element);
2866     __ load_heap_oop(rax_oop, from_element_addr, noreg, noreg, AS_RAW); // load the oop
2867     __ testptr(rax_oop, rax_oop);
2868     __ jcc(Assembler::zero, L_store_element);
2869 
2870     __ load_klass(r11_klass, rax_oop, rscratch1);// query the object klass
2871     generate_type_check(r11_klass, ckoff, ckval, L_store_element);
2872     // ======== end loop ========
2873 
2874     // It was a real error; we must depend on the caller to finish the job.
2875     // Register rdx = -1 * number of *remaining* oops, r14 = *total* oops.
2876     // Emit GC store barriers for the oops we have copied (r14 + rdx),
2877     // and report their number to the caller.
2878     assert_different_registers(rax, r14_length, count, to, end_to, rcx, rscratch1);
2879     Label L_post_barrier;
2880     __ addptr(r14_length, count);     // K = (original - remaining) oops

3135     // 32        30    24            16              8     2                 0
3136     //
3137     //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
3138     //
3139 
3140     const int lh_offset = in_bytes(Klass::layout_helper_offset());
3141 
3142     // Handle objArrays completely differently...
3143     const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
3144     __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
3145     __ jcc(Assembler::equal, L_objArray);
3146 
3147     //  if (src->klass() != dst->klass()) return -1;
3148     __ load_klass(rax, dst, rklass_tmp);
3149     __ cmpq(r10_src_klass, rax);
3150     __ jcc(Assembler::notEqual, L_failed);
3151 
3152     const Register rax_lh = rax;  // layout helper
3153     __ movl(rax_lh, Address(r10_src_klass, lh_offset));
3154 
3155     // Check for flat inline type array -> return -1
3156     __ testl(rax_lh, Klass::_lh_array_tag_flat_value_bit_inplace);
3157     __ jcc(Assembler::notZero, L_failed);
3158 
3159     // Check for null-free (non-flat) inline type array -> handle as object array
3160     __ testl(rax_lh, Klass::_lh_null_free_array_bit_inplace);
3161     __ jcc(Assembler::notZero, L_objArray);
3162 
3163     //  if (!src->is_Array()) return -1;
3164     __ cmpl(rax_lh, Klass::_lh_neutral_value);
3165     __ jcc(Assembler::greaterEqual, L_failed);
3166 
3167     // At this point, it is known to be a typeArray (array_tag 0x3).
3168 #ifdef ASSERT
3169     {
3170       BLOCK_COMMENT("assert primitive array {");
3171       Label L;
3172       __ movl(rklass_tmp, rax_lh);
3173       __ sarl(rklass_tmp, Klass::_lh_array_tag_shift);
3174       __ cmpl(rklass_tmp, Klass::_lh_array_tag_type_value);
3175       __ jcc(Assembler::equal, L);
3176       __ stop("must be a primitive array");
3177       __ bind(L);
3178       BLOCK_COMMENT("} assert primitive array done");
3179     }
3180 #endif
3181 
3182     arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3183                            r10, L_failed);
3184 
3185     // TypeArrayKlass
3186     //
3187     // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
3188     // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
3189     //
3190 
3191     const Register r10_offset = r10;    // array offset
3192     const Register rax_elsize = rax_lh; // element size
3193 
3194     __ movl(r10_offset, rax_lh);
3195     __ shrl(r10_offset, Klass::_lh_header_size_shift);

3263 
3264     // Identically typed arrays can be copied without element-wise checks.
3265     arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3266                            r10, L_failed);
3267 
3268     __ lea(from, Address(src, src_pos, TIMES_OOP,
3269                  arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
3270     __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
3271                  arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
3272     __ movl2ptr(count, r11_length); // length
3273   __ BIND(L_plain_copy);
3274 #ifdef _WIN64
3275     __ pop(rklass_tmp); // Restore callee-save rdi
3276 #endif
3277     __ jump(RuntimeAddress(oop_copy_entry));
3278 
3279   __ BIND(L_checkcast_copy);
3280     // live at this point:  r10_src_klass, r11_length, rax (dst_klass)
3281     {
3282       // Before looking at dst.length, make sure dst is also an objArray.
3283       // This check also fails for flat/null-free arrays which are not supported.
3284       __ cmpl(Address(rax, lh_offset), objArray_lh);
3285       __ jcc(Assembler::notEqual, L_failed);
3286 
3287 #ifdef ASSERT
3288       {
3289         BLOCK_COMMENT("assert not null-free array {");
3290         Label L;
3291         __ movl(rklass_tmp, Address(rax, lh_offset));
3292         __ testl(rklass_tmp, Klass::_lh_null_free_array_bit_inplace);
3293         __ jcc(Assembler::zero, L);
3294         __ stop("unexpected null-free array");
3295         __ bind(L);
3296         BLOCK_COMMENT("} assert not null-free array");
3297       }
3298 #endif
3299 
3300       // It is safe to examine both src.length and dst.length.
3301       arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
3302                              rax, L_failed);
3303 
3304       const Register r11_dst_klass = r11;
3305       __ load_klass(r11_dst_klass, dst, rklass_tmp); // reload
3306 
3307       // Marshal the base address arguments now, freeing registers.
3308       __ lea(from, Address(src, src_pos, TIMES_OOP,
3309                    arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
3310       __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
3311                    arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
3312       __ movl(count, length);           // length (reloaded)
3313       Register sco_temp = c_rarg3;      // this register is free now
3314       assert_different_registers(from, to, count, sco_temp,
3315                                  r11_dst_klass, r10_src_klass);
3316       assert_clean_int(count, sco_temp);
3317 
3318       // Generate the type check.
3319       const int sco_offset = in_bytes(Klass::super_check_offset_offset());

7550     __ bind(L);
7551 #endif // ASSERT
7552     __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
7553 
7554 
7555     // codeBlob framesize is in words (not VMRegImpl::slot_size)
7556     RuntimeStub* stub =
7557       RuntimeStub::new_runtime_stub(name,
7558                                     &code,
7559                                     frame_complete,
7560                                     (framesize >> (LogBytesPerWord - LogBytesPerInt)),
7561                                     oop_maps, false);
7562     return stub->entry_point();
7563   }
7564 
7565   void create_control_words() {
7566     // Round to nearest, 64-bit mode, exceptions masked
7567     StubRoutines::x86::_mxcsr_std = 0x1F80;
7568   }
7569 
7570   // Call here from the interpreter or compiled code to either load
7571   // multiple returned values from the inline type instance being
7572   // returned to registers or to store returned values to a newly
7573   // allocated inline type instance.
7574   address generate_return_value_stub(address destination, const char* name, bool has_res) {
7575     // We need to save all registers the calling convention may use so
7576     // the runtime calls read or update those registers. This needs to
7577     // be in sync with SharedRuntime::java_return_convention().
7578     enum layout {
7579       pad_off = frame::arg_reg_save_area_bytes/BytesPerInt, pad_off_2,
7580       rax_off, rax_off_2,
7581       j_rarg5_off, j_rarg5_2,
7582       j_rarg4_off, j_rarg4_2,
7583       j_rarg3_off, j_rarg3_2,
7584       j_rarg2_off, j_rarg2_2,
7585       j_rarg1_off, j_rarg1_2,
7586       j_rarg0_off, j_rarg0_2,
7587       j_farg0_off, j_farg0_2,
7588       j_farg1_off, j_farg1_2,
7589       j_farg2_off, j_farg2_2,
7590       j_farg3_off, j_farg3_2,
7591       j_farg4_off, j_farg4_2,
7592       j_farg5_off, j_farg5_2,
7593       j_farg6_off, j_farg6_2,
7594       j_farg7_off, j_farg7_2,
7595       rbp_off, rbp_off_2,
7596       return_off, return_off_2,
7597 
7598       framesize
7599     };
7600 
7601     CodeBuffer buffer(name, 1000, 512);
7602     MacroAssembler* masm = new MacroAssembler(&buffer);
7603 
7604     int frame_size_in_bytes = align_up(framesize*BytesPerInt, 16);
7605     assert(frame_size_in_bytes == framesize*BytesPerInt, "misaligned");
7606     int frame_size_in_slots = frame_size_in_bytes / BytesPerInt;
7607     int frame_size_in_words = frame_size_in_bytes / wordSize;
7608 
7609     OopMapSet *oop_maps = new OopMapSet();
7610     OopMap* map = new OopMap(frame_size_in_slots, 0);
7611 
7612     map->set_callee_saved(VMRegImpl::stack2reg(rax_off), rax->as_VMReg());
7613     map->set_callee_saved(VMRegImpl::stack2reg(j_rarg5_off), j_rarg5->as_VMReg());
7614     map->set_callee_saved(VMRegImpl::stack2reg(j_rarg4_off), j_rarg4->as_VMReg());
7615     map->set_callee_saved(VMRegImpl::stack2reg(j_rarg3_off), j_rarg3->as_VMReg());
7616     map->set_callee_saved(VMRegImpl::stack2reg(j_rarg2_off), j_rarg2->as_VMReg());
7617     map->set_callee_saved(VMRegImpl::stack2reg(j_rarg1_off), j_rarg1->as_VMReg());
7618     map->set_callee_saved(VMRegImpl::stack2reg(j_rarg0_off), j_rarg0->as_VMReg());
7619     map->set_callee_saved(VMRegImpl::stack2reg(j_farg0_off), j_farg0->as_VMReg());
7620     map->set_callee_saved(VMRegImpl::stack2reg(j_farg1_off), j_farg1->as_VMReg());
7621     map->set_callee_saved(VMRegImpl::stack2reg(j_farg2_off), j_farg2->as_VMReg());
7622     map->set_callee_saved(VMRegImpl::stack2reg(j_farg3_off), j_farg3->as_VMReg());
7623     map->set_callee_saved(VMRegImpl::stack2reg(j_farg4_off), j_farg4->as_VMReg());
7624     map->set_callee_saved(VMRegImpl::stack2reg(j_farg5_off), j_farg5->as_VMReg());
7625     map->set_callee_saved(VMRegImpl::stack2reg(j_farg6_off), j_farg6->as_VMReg());
7626     map->set_callee_saved(VMRegImpl::stack2reg(j_farg7_off), j_farg7->as_VMReg());
7627 
7628     int start = __ offset();
7629 
7630     __ subptr(rsp, frame_size_in_bytes - 8 /* return address*/);
7631 
7632     __ movptr(Address(rsp, rbp_off * BytesPerInt), rbp);
7633     __ movdbl(Address(rsp, j_farg7_off * BytesPerInt), j_farg7);
7634     __ movdbl(Address(rsp, j_farg6_off * BytesPerInt), j_farg6);
7635     __ movdbl(Address(rsp, j_farg5_off * BytesPerInt), j_farg5);
7636     __ movdbl(Address(rsp, j_farg4_off * BytesPerInt), j_farg4);
7637     __ movdbl(Address(rsp, j_farg3_off * BytesPerInt), j_farg3);
7638     __ movdbl(Address(rsp, j_farg2_off * BytesPerInt), j_farg2);
7639     __ movdbl(Address(rsp, j_farg1_off * BytesPerInt), j_farg1);
7640     __ movdbl(Address(rsp, j_farg0_off * BytesPerInt), j_farg0);
7641 
7642     __ movptr(Address(rsp, j_rarg0_off * BytesPerInt), j_rarg0);
7643     __ movptr(Address(rsp, j_rarg1_off * BytesPerInt), j_rarg1);
7644     __ movptr(Address(rsp, j_rarg2_off * BytesPerInt), j_rarg2);
7645     __ movptr(Address(rsp, j_rarg3_off * BytesPerInt), j_rarg3);
7646     __ movptr(Address(rsp, j_rarg4_off * BytesPerInt), j_rarg4);
7647     __ movptr(Address(rsp, j_rarg5_off * BytesPerInt), j_rarg5);
7648     __ movptr(Address(rsp, rax_off * BytesPerInt), rax);
7649 
7650     int frame_complete = __ offset();
7651 
7652     __ set_last_Java_frame(noreg, noreg, NULL);
7653 
7654     __ mov(c_rarg0, r15_thread);
7655     __ mov(c_rarg1, rax);
7656 
7657     __ call(RuntimeAddress(destination));
7658 
7659     // Set an oopmap for the call site.
7660 
7661     oop_maps->add_gc_map( __ offset() - start, map);
7662 
7663     // clear last_Java_sp
7664     __ reset_last_Java_frame(false);
7665 
7666     __ movptr(rbp, Address(rsp, rbp_off * BytesPerInt));
7667     __ movdbl(j_farg7, Address(rsp, j_farg7_off * BytesPerInt));
7668     __ movdbl(j_farg6, Address(rsp, j_farg6_off * BytesPerInt));
7669     __ movdbl(j_farg5, Address(rsp, j_farg5_off * BytesPerInt));
7670     __ movdbl(j_farg4, Address(rsp, j_farg4_off * BytesPerInt));
7671     __ movdbl(j_farg3, Address(rsp, j_farg3_off * BytesPerInt));
7672     __ movdbl(j_farg2, Address(rsp, j_farg2_off * BytesPerInt));
7673     __ movdbl(j_farg1, Address(rsp, j_farg1_off * BytesPerInt));
7674     __ movdbl(j_farg0, Address(rsp, j_farg0_off * BytesPerInt));
7675 
7676     __ movptr(j_rarg0, Address(rsp, j_rarg0_off * BytesPerInt));
7677     __ movptr(j_rarg1, Address(rsp, j_rarg1_off * BytesPerInt));
7678     __ movptr(j_rarg2, Address(rsp, j_rarg2_off * BytesPerInt));
7679     __ movptr(j_rarg3, Address(rsp, j_rarg3_off * BytesPerInt));
7680     __ movptr(j_rarg4, Address(rsp, j_rarg4_off * BytesPerInt));
7681     __ movptr(j_rarg5, Address(rsp, j_rarg5_off * BytesPerInt));
7682     __ movptr(rax, Address(rsp, rax_off * BytesPerInt));
7683 
7684     __ addptr(rsp, frame_size_in_bytes-8);
7685 
7686     // check for pending exceptions
7687     Label pending;
7688     __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
7689     __ jcc(Assembler::notEqual, pending);
7690 
7691     if (has_res) {
7692       __ get_vm_result(rax, r15_thread);
7693     }
7694 
7695     __ ret(0);
7696 
7697     __ bind(pending);
7698 
7699     __ movptr(rax, Address(r15_thread, Thread::pending_exception_offset()));
7700     __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
7701 
7702     // -------------
7703     // make sure all code is generated
7704     masm->flush();
7705 
7706     RuntimeStub* stub = RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_in_words, oop_maps, false);
7707     return stub->entry_point();
7708   }
7709 
7710   // Initialization
7711   void generate_initial() {
7712     // Generates all stubs and initializes the entry points
7713 
7714     // This platform-specific settings are needed by generate_call_stub()
7715     create_control_words();
7716 
7717     // entry points that exist in all platforms Note: This is code
7718     // that could be shared among different platforms - however the
7719     // benefit seems to be smaller than the disadvantage of having a
7720     // much more complicated generator structure. See also comment in
7721     // stubRoutines.hpp.
7722 
7723     StubRoutines::_forward_exception_entry = generate_forward_exception();
7724 
7725     // Generate these first because they are called from other stubs
7726     if (InlineTypeReturnedAsFields) {
7727       StubRoutines::_load_inline_type_fields_in_regs =
7728         generate_return_value_stub(CAST_FROM_FN_PTR(address, SharedRuntime::load_inline_type_fields_in_regs), "load_inline_type_fields_in_regs", false);
7729       StubRoutines::_store_inline_type_fields_to_buf =
7730         generate_return_value_stub(CAST_FROM_FN_PTR(address, SharedRuntime::store_inline_type_fields_to_buf), "store_inline_type_fields_to_buf", true);
7731     }
7732     StubRoutines::_call_stub_entry = generate_call_stub(StubRoutines::_call_stub_return_address);
7733 
7734     // is referenced by megamorphic call
7735     StubRoutines::_catch_exception_entry = generate_catch_exception();
7736 
7737     // atomic calls
7738     StubRoutines::_fence_entry                = generate_orderaccess_fence();
7739 
7740     // platform dependent
7741     StubRoutines::x86::_get_previous_sp_entry = generate_get_previous_sp();
7742 
7743     StubRoutines::x86::_verify_mxcsr_entry    = generate_verify_mxcsr();
7744 
7745     StubRoutines::x86::_f2i_fixup             = generate_f2i_fixup();
7746     StubRoutines::x86::_f2l_fixup             = generate_f2l_fixup();
7747     StubRoutines::x86::_d2i_fixup             = generate_d2i_fixup();
7748     StubRoutines::x86::_d2l_fixup             = generate_d2l_fixup();
7749 
7750     StubRoutines::x86::_float_sign_mask       = generate_fp_mask("float_sign_mask",  0x7FFFFFFF7FFFFFFF);
7751     StubRoutines::x86::_float_sign_flip       = generate_fp_mask("float_sign_flip",  0x8000000080000000);
7752     StubRoutines::x86::_double_sign_mask      = generate_fp_mask("double_sign_mask", 0x7FFFFFFFFFFFFFFF);
< prev index next >