< prev index next >

src/hotspot/cpu/x86/macroAssembler_x86.cpp

Print this page


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


< prev index next >