src/cpu/x86/vm/assembler_x86.cpp

changeset 2784
92add02409c9
parent 2697
09f96c3ff1ad
parent 2781
e1162778c1c8
child 2787
5d046bf49ce7
equal deleted inserted replaced
2719:4f978fb6c81a 2784:92add02409c9
6900 6900
6901 ////////////////////////////////////////////////////////////////////////////////// 6901 //////////////////////////////////////////////////////////////////////////////////
6902 #ifndef SERIALGC 6902 #ifndef SERIALGC
6903 6903
6904 void MacroAssembler::g1_write_barrier_pre(Register obj, 6904 void MacroAssembler::g1_write_barrier_pre(Register obj,
6905 #ifndef _LP64 6905 Register pre_val,
6906 Register thread, 6906 Register thread,
6907 #endif
6908 Register tmp, 6907 Register tmp,
6909 Register tmp2, 6908 bool tosca_live,
6910 bool tosca_live) { 6909 bool expand_call) {
6911 LP64_ONLY(Register thread = r15_thread;) 6910
6911 // If expand_call is true then we expand the call_VM_leaf macro
6912 // directly to skip generating the check by
6913 // InterpreterMacroAssembler::call_VM_leaf_base that checks _last_sp.
6914
6915 #ifdef _LP64
6916 assert(thread == r15_thread, "must be");
6917 #endif // _LP64
6918
6919 Label done;
6920 Label runtime;
6921
6922 assert(pre_val != noreg, "check this code");
6923
6924 if (obj != noreg) {
6925 assert_different_registers(obj, pre_val, tmp);
6926 assert(pre_val != rax, "check this code");
6927 }
6928
6912 Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() + 6929 Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
6913 PtrQueue::byte_offset_of_active())); 6930 PtrQueue::byte_offset_of_active()));
6914
6915 Address index(thread, in_bytes(JavaThread::satb_mark_queue_offset() + 6931 Address index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
6916 PtrQueue::byte_offset_of_index())); 6932 PtrQueue::byte_offset_of_index()));
6917 Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() + 6933 Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
6918 PtrQueue::byte_offset_of_buf())); 6934 PtrQueue::byte_offset_of_buf()));
6919 6935
6920 6936
6921 Label done; 6937 // Is marking active?
6922 Label runtime;
6923
6924 // if (!marking_in_progress) goto done;
6925 if (in_bytes(PtrQueue::byte_width_of_active()) == 4) { 6938 if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
6926 cmpl(in_progress, 0); 6939 cmpl(in_progress, 0);
6927 } else { 6940 } else {
6928 assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption"); 6941 assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption");
6929 cmpb(in_progress, 0); 6942 cmpb(in_progress, 0);
6930 } 6943 }
6931 jcc(Assembler::equal, done); 6944 jcc(Assembler::equal, done);
6932 6945
6933 // if (x.f == NULL) goto done; 6946 // Do we need to load the previous value?
6934 #ifdef _LP64 6947 if (obj != noreg) {
6935 load_heap_oop(tmp2, Address(obj, 0)); 6948 load_heap_oop(pre_val, Address(obj, 0));
6936 #else 6949 }
6937 movptr(tmp2, Address(obj, 0)); 6950
6938 #endif 6951 // Is the previous value null?
6939 cmpptr(tmp2, (int32_t) NULL_WORD); 6952 cmpptr(pre_val, (int32_t) NULL_WORD);
6940 jcc(Assembler::equal, done); 6953 jcc(Assembler::equal, done);
6941 6954
6942 // Can we store original value in the thread's buffer? 6955 // Can we store original value in the thread's buffer?
6943 6956 // Is index == 0?
6944 #ifdef _LP64 6957 // (The index field is typed as size_t.)
6945 movslq(tmp, index); 6958
6946 cmpq(tmp, 0); 6959 movptr(tmp, index); // tmp := *index_adr
6947 #else 6960 cmpptr(tmp, 0); // tmp == 0?
6948 cmpl(index, 0); 6961 jcc(Assembler::equal, runtime); // If yes, goto runtime
6949 #endif 6962
6950 jcc(Assembler::equal, runtime); 6963 subptr(tmp, wordSize); // tmp := tmp - wordSize
6951 #ifdef _LP64 6964 movptr(index, tmp); // *index_adr := tmp
6952 subq(tmp, wordSize); 6965 addptr(tmp, buffer); // tmp := tmp + *buffer_adr
6953 movl(index, tmp); 6966
6954 addq(tmp, buffer); 6967 // Record the previous value
6955 #else 6968 movptr(Address(tmp, 0), pre_val);
6956 subl(index, wordSize);
6957 movl(tmp, buffer);
6958 addl(tmp, index);
6959 #endif
6960 movptr(Address(tmp, 0), tmp2);
6961 jmp(done); 6969 jmp(done);
6970
6962 bind(runtime); 6971 bind(runtime);
6963 // save the live input values 6972 // save the live input values
6964 if(tosca_live) push(rax); 6973 if(tosca_live) push(rax);
6965 push(obj); 6974
6966 #ifdef _LP64 6975 if (obj != noreg && obj != rax)
6967 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), tmp2, r15_thread); 6976 push(obj);
6968 #else 6977
6969 push(thread); 6978 if (pre_val != rax)
6970 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), tmp2, thread); 6979 push(pre_val);
6971 pop(thread); 6980
6972 #endif 6981 // Calling the runtime using the regular call_VM_leaf mechanism generates
6973 pop(obj); 6982 // code (generated by InterpreterMacroAssember::call_VM_leaf_base)
6983 // that checks that the *(ebp+frame::interpreter_frame_last_sp) == NULL.
6984 //
6985 // If we care generating the pre-barrier without a frame (e.g. in the
6986 // intrinsified Reference.get() routine) then ebp might be pointing to
6987 // the caller frame and so this check will most likely fail at runtime.
6988 //
6989 // Expanding the call directly bypasses the generation of the check.
6990 // So when we do not have have a full interpreter frame on the stack
6991 // expand_call should be passed true.
6992
6993 NOT_LP64( push(thread); )
6994
6995 if (expand_call) {
6996 LP64_ONLY( assert(pre_val != c_rarg1, "smashed arg"); )
6997 pass_arg1(this, thread);
6998 pass_arg0(this, pre_val);
6999 MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), 2);
7000 } else {
7001 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), pre_val, thread);
7002 }
7003
7004 NOT_LP64( pop(thread); )
7005
7006 // save the live input values
7007 if (pre_val != rax)
7008 pop(pre_val);
7009
7010 if (obj != noreg && obj != rax)
7011 pop(obj);
7012
6974 if(tosca_live) pop(rax); 7013 if(tosca_live) pop(rax);
7014
6975 bind(done); 7015 bind(done);
6976
6977 } 7016 }
6978 7017
6979 void MacroAssembler::g1_write_barrier_post(Register store_addr, 7018 void MacroAssembler::g1_write_barrier_post(Register store_addr,
6980 Register new_val, 7019 Register new_val,
6981 #ifndef _LP64
6982 Register thread, 7020 Register thread,
6983 #endif
6984 Register tmp, 7021 Register tmp,
6985 Register tmp2) { 7022 Register tmp2) {
6986 7023 #ifdef _LP64
6987 LP64_ONLY(Register thread = r15_thread;) 7024 assert(thread == r15_thread, "must be");
7025 #endif // _LP64
7026
6988 Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() + 7027 Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
6989 PtrQueue::byte_offset_of_index())); 7028 PtrQueue::byte_offset_of_index()));
6990 Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() + 7029 Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
6991 PtrQueue::byte_offset_of_buf())); 7030 PtrQueue::byte_offset_of_buf()));
7031
6992 BarrierSet* bs = Universe::heap()->barrier_set(); 7032 BarrierSet* bs = Universe::heap()->barrier_set();
6993 CardTableModRefBS* ct = (CardTableModRefBS*)bs; 7033 CardTableModRefBS* ct = (CardTableModRefBS*)bs;
6994 Label done; 7034 Label done;
6995 Label runtime; 7035 Label runtime;
6996 7036
7065 #endif 7105 #endif
7066 pop(new_val); 7106 pop(new_val);
7067 pop(store_addr); 7107 pop(store_addr);
7068 7108
7069 bind(done); 7109 bind(done);
7070
7071 } 7110 }
7072 7111
7073 #endif // SERIALGC 7112 #endif // SERIALGC
7074 ////////////////////////////////////////////////////////////////////////////////// 7113 //////////////////////////////////////////////////////////////////////////////////
7075 7114

mercurial