5866 } else {
5867 movdqu(Address(base, 0), xtmp);
5868 movdqu(Address(base, 16), xtmp);
5869 }
5870 addptr(base, 32);
5871 subptr(cnt, 4);
5872
5873 BIND(L_tail);
5874 addptr(cnt, 4);
5875 jccb(Assembler::lessEqual, L_end);
5876 decrement(cnt);
5877
5878 BIND(L_sloop);
5879 movq(Address(base, 0), xtmp);
5880 addptr(base, 8);
5881 decrement(cnt);
5882 jccb(Assembler::greaterEqual, L_sloop);
5883 BIND(L_end);
5884 }
5885
5886 void MacroAssembler::store_value_type_fields_to_buf(ciValueKlass* vk) {
5887 #ifndef _LP64
5888 super_call_VM_leaf(StubRoutines::store_value_type_fields_to_buf());
5889 #else
5890 // A value type might be returned. If fields are in registers we
5891 // need to allocate a value type instance and initialize it with
5892 // the value of the fields.
5893 Label skip, slow_case;
5894 // We only need a new buffered value if a new one is not returned
5895 testptr(rax, 1);
5896 jcc(Assembler::zero, skip);
5897
5898 // Try to allocate a new buffered value (from the heap)
5899 if (UseTLAB) {
5900 // FIXME -- for smaller code, the inline allocation (and the slow case) should be moved inside the pack handler.
5901 if (vk != NULL) {
5902 // Called from C1, where the return type is statically known.
5903 movptr(rbx, (intptr_t)vk->get_ValueKlass());
5904 jint lh = vk->layout_helper();
5905 assert(lh != Klass::_lh_neutral_value, "inline class in return type must have been resolved");
5906 movl(r14, lh);
5907 } else {
5908 // Call from interpreter. RAX contains ((the ValueKlass* of the return type) | 0x01)
5909 mov(rbx, rax);
5910 andptr(rbx, -2);
5911 movl(r14, Address(rbx, Klass::layout_helper_offset()));
5912 }
5913
5914 movptr(r13, Address(r15_thread, in_bytes(JavaThread::tlab_top_offset())));
5915 lea(r14, Address(r13, r14, Address::times_1));
5916 cmpptr(r14, Address(r15_thread, in_bytes(JavaThread::tlab_end_offset())));
5930 // We have our new buffered value, initialize its fields with a
5931 // value class specific handler
5932 if (vk != NULL) {
5933 // FIXME -- do the packing in-line to avoid the runtime call
5934 mov(rax, r13);
5935 call(RuntimeAddress(vk->pack_handler()));
5936 } else {
5937 movptr(rbx, Address(rax, InstanceKlass::adr_valueklass_fixed_block_offset()));
5938 movptr(rbx, Address(rbx, ValueKlass::pack_handler_offset()));
5939 mov(rax, r13);
5940 call(rbx);
5941 }
5942 jmp(skip);
5943 }
5944
5945 bind(slow_case);
5946 // We failed to allocate a new value, fall back to a runtime
5947 // call. Some oop field may be live in some registers but we can't
5948 // tell. That runtime call will take care of preserving them
5949 // across a GC if there's one.
5950 super_call_VM_leaf(StubRoutines::store_value_type_fields_to_buf());
5951 bind(skip);
5952 #endif
5953 }
5954
5955
5956 // Move a value between registers/stack slots and update the reg_state
5957 bool MacroAssembler::move_helper(VMReg from, VMReg to, BasicType bt, RegState reg_state[], int ret_off, int extra_stack_offset) {
5958 if (reg_state[to->value()] == reg_written) {
5959 return true; // Already written
5960 }
5961 if (from != to && bt != T_VOID) {
5962 if (reg_state[to->value()] == reg_readonly) {
5963 return false; // Not yet writable
5964 }
5965 if (from->is_reg()) {
5966 if (to->is_reg()) {
5967 if (from->is_XMMRegister()) {
5968 if (bt == T_DOUBLE) {
5969 movdbl(to->as_XMMRegister(), from->as_XMMRegister());
5970 } else {
5971 assert(bt == T_FLOAT, "must be float");
5972 movflt(to->as_XMMRegister(), from->as_XMMRegister());
|
5866 } else {
5867 movdqu(Address(base, 0), xtmp);
5868 movdqu(Address(base, 16), xtmp);
5869 }
5870 addptr(base, 32);
5871 subptr(cnt, 4);
5872
5873 BIND(L_tail);
5874 addptr(cnt, 4);
5875 jccb(Assembler::lessEqual, L_end);
5876 decrement(cnt);
5877
5878 BIND(L_sloop);
5879 movq(Address(base, 0), xtmp);
5880 addptr(base, 8);
5881 decrement(cnt);
5882 jccb(Assembler::greaterEqual, L_sloop);
5883 BIND(L_end);
5884 }
5885
5886 int MacroAssembler::store_value_type_fields_to_buf(ciValueKlass* vk, bool from_interpreter) {
5887 // A value type might be returned. If fields are in registers we
5888 // need to allocate a value type instance and initialize it with
5889 // the value of the fields.
5890 Label skip;
5891 // We only need a new buffered value if a new one is not returned
5892 testptr(rax, 1);
5893 jcc(Assembler::zero, skip);
5894 int call_offset = -1;
5895
5896 #ifdef _LP64
5897 Label slow_case;
5898
5899 // Try to allocate a new buffered value (from the heap)
5900 if (UseTLAB) {
5901 // FIXME -- for smaller code, the inline allocation (and the slow case) should be moved inside the pack handler.
5902 if (vk != NULL) {
5903 // Called from C1, where the return type is statically known.
5904 movptr(rbx, (intptr_t)vk->get_ValueKlass());
5905 jint lh = vk->layout_helper();
5906 assert(lh != Klass::_lh_neutral_value, "inline class in return type must have been resolved");
5907 movl(r14, lh);
5908 } else {
5909 // Call from interpreter. RAX contains ((the ValueKlass* of the return type) | 0x01)
5910 mov(rbx, rax);
5911 andptr(rbx, -2);
5912 movl(r14, Address(rbx, Klass::layout_helper_offset()));
5913 }
5914
5915 movptr(r13, Address(r15_thread, in_bytes(JavaThread::tlab_top_offset())));
5916 lea(r14, Address(r13, r14, Address::times_1));
5917 cmpptr(r14, Address(r15_thread, in_bytes(JavaThread::tlab_end_offset())));
5931 // We have our new buffered value, initialize its fields with a
5932 // value class specific handler
5933 if (vk != NULL) {
5934 // FIXME -- do the packing in-line to avoid the runtime call
5935 mov(rax, r13);
5936 call(RuntimeAddress(vk->pack_handler()));
5937 } else {
5938 movptr(rbx, Address(rax, InstanceKlass::adr_valueklass_fixed_block_offset()));
5939 movptr(rbx, Address(rbx, ValueKlass::pack_handler_offset()));
5940 mov(rax, r13);
5941 call(rbx);
5942 }
5943 jmp(skip);
5944 }
5945
5946 bind(slow_case);
5947 // We failed to allocate a new value, fall back to a runtime
5948 // call. Some oop field may be live in some registers but we can't
5949 // tell. That runtime call will take care of preserving them
5950 // across a GC if there's one.
5951 #endif
5952
5953 if (from_interpreter) {
5954 super_call_VM_leaf(StubRoutines::store_value_type_fields_to_buf());
5955 } else {
5956 call(RuntimeAddress(StubRoutines::store_value_type_fields_to_buf()));
5957 call_offset = offset();
5958 }
5959
5960 bind(skip);
5961 return call_offset;
5962 }
5963
5964
5965 // Move a value between registers/stack slots and update the reg_state
5966 bool MacroAssembler::move_helper(VMReg from, VMReg to, BasicType bt, RegState reg_state[], int ret_off, int extra_stack_offset) {
5967 if (reg_state[to->value()] == reg_written) {
5968 return true; // Already written
5969 }
5970 if (from != to && bt != T_VOID) {
5971 if (reg_state[to->value()] == reg_readonly) {
5972 return false; // Not yet writable
5973 }
5974 if (from->is_reg()) {
5975 if (to->is_reg()) {
5976 if (from->is_XMMRegister()) {
5977 if (bt == T_DOUBLE) {
5978 movdbl(to->as_XMMRegister(), from->as_XMMRegister());
5979 } else {
5980 assert(bt == T_FLOAT, "must be float");
5981 movflt(to->as_XMMRegister(), from->as_XMMRegister());
|