src/cpu/x86/vm/assembler_x86.cpp

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

mercurial