< 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();

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

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








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


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

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

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













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

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












































































































































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






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

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

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

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

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