Mercurial > hg > truffle
comparison src/cpu/x86/vm/assembler_x86.cpp @ 3464:be4ca325525a
Merge.
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Wed, 27 Jul 2011 17:32:44 -0700 |
parents | 0654ee04b214 a3081a3a2b54 |
children | 04b9a2566eec |
comparison
equal
deleted
inserted
replaced
3239:7c4b4daac19b | 3464:be4ca325525a |
---|---|
3802 void Assembler::addq(Register dst, Register src) { | 3802 void Assembler::addq(Register dst, Register src) { |
3803 (void) prefixq_and_encode(dst->encoding(), src->encoding()); | 3803 (void) prefixq_and_encode(dst->encoding(), src->encoding()); |
3804 emit_arith(0x03, 0xC0, dst, src); | 3804 emit_arith(0x03, 0xC0, dst, src); |
3805 } | 3805 } |
3806 | 3806 |
3807 void Assembler::andq(Address dst, int32_t imm32) { | |
3808 InstructionMark im(this); | |
3809 prefixq(dst); | |
3810 emit_byte(0x81); | |
3811 emit_operand(rsp, dst, 4); | |
3812 emit_long(imm32); | |
3813 } | |
3814 | |
3807 void Assembler::andq(Register dst, int32_t imm32) { | 3815 void Assembler::andq(Register dst, int32_t imm32) { |
3808 (void) prefixq_and_encode(dst->encoding()); | 3816 (void) prefixq_and_encode(dst->encoding()); |
3809 emit_arith(0x81, 0xE0, dst, imm32); | 3817 emit_arith(0x81, 0xE0, dst, imm32); |
3810 } | 3818 } |
3811 | 3819 |
5088 assert(false, "start up GDB"); | 5096 assert(false, "start up GDB"); |
5089 } | 5097 } |
5090 } else { | 5098 } else { |
5091 ttyLocker ttyl; | 5099 ttyLocker ttyl; |
5092 ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", msg); | 5100 ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", msg); |
5093 assert(false, "DEBUG MESSAGE"); | 5101 assert(false, err_msg("DEBUG MESSAGE: %s", msg)); |
5094 } | 5102 } |
5095 ThreadStateTransition::transition(thread, _thread_in_vm, saved_state); | 5103 ThreadStateTransition::transition(thread, _thread_in_vm, saved_state); |
5096 } | 5104 } |
5097 | 5105 |
5098 void MacroAssembler::stop(const char* msg) { | 5106 void MacroAssembler::stop(const char* msg) { |
5651 ThreadStateTransition::transition(thread, _thread_in_vm, saved_state); | 5659 ThreadStateTransition::transition(thread, _thread_in_vm, saved_state); |
5652 } else { | 5660 } else { |
5653 ttyLocker ttyl; | 5661 ttyLocker ttyl; |
5654 ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", | 5662 ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", |
5655 msg); | 5663 msg); |
5664 assert(false, err_msg("DEBUG MESSAGE: %s", msg)); | |
5656 } | 5665 } |
5657 } | 5666 } |
5658 | 5667 |
5659 #endif // _LP64 | 5668 #endif // _LP64 |
5660 | 5669 |
5886 pass_arg3(this, arg_3); | 5895 pass_arg3(this, arg_3); |
5887 LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg")); | 5896 LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg")); |
5888 pass_arg2(this, arg_2); | 5897 pass_arg2(this, arg_2); |
5889 pass_arg1(this, arg_1); | 5898 pass_arg1(this, arg_1); |
5890 call_VM(oop_result, last_java_sp, entry_point, 3, check_exceptions); | 5899 call_VM(oop_result, last_java_sp, entry_point, 3, check_exceptions); |
5900 } | |
5901 | |
5902 void MacroAssembler::super_call_VM(Register oop_result, | |
5903 Register last_java_sp, | |
5904 address entry_point, | |
5905 int number_of_arguments, | |
5906 bool check_exceptions) { | |
5907 Register thread = LP64_ONLY(r15_thread) NOT_LP64(noreg); | |
5908 MacroAssembler::call_VM_base(oop_result, thread, last_java_sp, entry_point, number_of_arguments, check_exceptions); | |
5909 } | |
5910 | |
5911 void MacroAssembler::super_call_VM(Register oop_result, | |
5912 Register last_java_sp, | |
5913 address entry_point, | |
5914 Register arg_1, | |
5915 bool check_exceptions) { | |
5916 pass_arg1(this, arg_1); | |
5917 super_call_VM(oop_result, last_java_sp, entry_point, 1, check_exceptions); | |
5918 } | |
5919 | |
5920 void MacroAssembler::super_call_VM(Register oop_result, | |
5921 Register last_java_sp, | |
5922 address entry_point, | |
5923 Register arg_1, | |
5924 Register arg_2, | |
5925 bool check_exceptions) { | |
5926 | |
5927 LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg")); | |
5928 pass_arg2(this, arg_2); | |
5929 pass_arg1(this, arg_1); | |
5930 super_call_VM(oop_result, last_java_sp, entry_point, 2, check_exceptions); | |
5931 } | |
5932 | |
5933 void MacroAssembler::super_call_VM(Register oop_result, | |
5934 Register last_java_sp, | |
5935 address entry_point, | |
5936 Register arg_1, | |
5937 Register arg_2, | |
5938 Register arg_3, | |
5939 bool check_exceptions) { | |
5940 LP64_ONLY(assert(arg_1 != c_rarg3, "smashed arg")); | |
5941 LP64_ONLY(assert(arg_2 != c_rarg3, "smashed arg")); | |
5942 pass_arg3(this, arg_3); | |
5943 LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg")); | |
5944 pass_arg2(this, arg_2); | |
5945 pass_arg1(this, arg_1); | |
5946 super_call_VM(oop_result, last_java_sp, entry_point, 3, check_exceptions); | |
5891 } | 5947 } |
5892 | 5948 |
5893 void MacroAssembler::call_VM_base(Register oop_result, | 5949 void MacroAssembler::call_VM_base(Register oop_result, |
5894 Register java_thread, | 5950 Register java_thread, |
5895 Register last_java_sp, | 5951 Register last_java_sp, |
6035 pass_arg2(this, arg_2); | 6091 pass_arg2(this, arg_2); |
6036 LP64_ONLY(assert(arg_0 != c_rarg1, "smashed arg")); | 6092 LP64_ONLY(assert(arg_0 != c_rarg1, "smashed arg")); |
6037 pass_arg1(this, arg_1); | 6093 pass_arg1(this, arg_1); |
6038 pass_arg0(this, arg_0); | 6094 pass_arg0(this, arg_0); |
6039 call_VM_leaf(entry_point, 3); | 6095 call_VM_leaf(entry_point, 3); |
6096 } | |
6097 | |
6098 void MacroAssembler::super_call_VM_leaf(address entry_point, Register arg_0) { | |
6099 pass_arg0(this, arg_0); | |
6100 MacroAssembler::call_VM_leaf_base(entry_point, 1); | |
6101 } | |
6102 | |
6103 void MacroAssembler::super_call_VM_leaf(address entry_point, Register arg_0, Register arg_1) { | |
6104 | |
6105 LP64_ONLY(assert(arg_0 != c_rarg1, "smashed arg")); | |
6106 pass_arg1(this, arg_1); | |
6107 pass_arg0(this, arg_0); | |
6108 MacroAssembler::call_VM_leaf_base(entry_point, 2); | |
6109 } | |
6110 | |
6111 void MacroAssembler::super_call_VM_leaf(address entry_point, Register arg_0, Register arg_1, Register arg_2) { | |
6112 LP64_ONLY(assert(arg_0 != c_rarg2, "smashed arg")); | |
6113 LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg")); | |
6114 pass_arg2(this, arg_2); | |
6115 LP64_ONLY(assert(arg_0 != c_rarg1, "smashed arg")); | |
6116 pass_arg1(this, arg_1); | |
6117 pass_arg0(this, arg_0); | |
6118 MacroAssembler::call_VM_leaf_base(entry_point, 3); | |
6119 } | |
6120 | |
6121 void MacroAssembler::super_call_VM_leaf(address entry_point, Register arg_0, Register arg_1, Register arg_2, Register arg_3) { | |
6122 LP64_ONLY(assert(arg_0 != c_rarg3, "smashed arg")); | |
6123 LP64_ONLY(assert(arg_1 != c_rarg3, "smashed arg")); | |
6124 LP64_ONLY(assert(arg_2 != c_rarg3, "smashed arg")); | |
6125 pass_arg3(this, arg_3); | |
6126 LP64_ONLY(assert(arg_0 != c_rarg2, "smashed arg")); | |
6127 LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg")); | |
6128 pass_arg2(this, arg_2); | |
6129 LP64_ONLY(assert(arg_0 != c_rarg1, "smashed arg")); | |
6130 pass_arg1(this, arg_1); | |
6131 pass_arg0(this, arg_0); | |
6132 MacroAssembler::call_VM_leaf_base(entry_point, 4); | |
6040 } | 6133 } |
6041 | 6134 |
6042 void MacroAssembler::check_and_handle_earlyret(Register java_thread) { | 6135 void MacroAssembler::check_and_handle_earlyret(Register java_thread) { |
6043 } | 6136 } |
6044 | 6137 |
6900 | 6993 |
6901 ////////////////////////////////////////////////////////////////////////////////// | 6994 ////////////////////////////////////////////////////////////////////////////////// |
6902 #ifndef SERIALGC | 6995 #ifndef SERIALGC |
6903 | 6996 |
6904 void MacroAssembler::g1_write_barrier_pre(Register obj, | 6997 void MacroAssembler::g1_write_barrier_pre(Register obj, |
6905 #ifndef _LP64 | 6998 Register pre_val, |
6906 Register thread, | 6999 Register thread, |
6907 #endif | |
6908 Register tmp, | 7000 Register tmp, |
6909 Register tmp2, | 7001 bool tosca_live, |
6910 bool tosca_live) { | 7002 bool expand_call) { |
6911 LP64_ONLY(Register thread = r15_thread;) | 7003 |
7004 // If expand_call is true then we expand the call_VM_leaf macro | |
7005 // directly to skip generating the check by | |
7006 // InterpreterMacroAssembler::call_VM_leaf_base that checks _last_sp. | |
7007 | |
7008 #ifdef _LP64 | |
7009 assert(thread == r15_thread, "must be"); | |
7010 #endif // _LP64 | |
7011 | |
7012 Label done; | |
7013 Label runtime; | |
7014 | |
7015 assert(pre_val != noreg, "check this code"); | |
7016 | |
7017 if (obj != noreg) { | |
7018 assert_different_registers(obj, pre_val, tmp); | |
7019 assert(pre_val != rax, "check this code"); | |
7020 } | |
7021 | |
6912 Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() + | 7022 Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() + |
6913 PtrQueue::byte_offset_of_active())); | 7023 PtrQueue::byte_offset_of_active())); |
6914 | |
6915 Address index(thread, in_bytes(JavaThread::satb_mark_queue_offset() + | 7024 Address index(thread, in_bytes(JavaThread::satb_mark_queue_offset() + |
6916 PtrQueue::byte_offset_of_index())); | 7025 PtrQueue::byte_offset_of_index())); |
6917 Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() + | 7026 Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() + |
6918 PtrQueue::byte_offset_of_buf())); | 7027 PtrQueue::byte_offset_of_buf())); |
6919 | 7028 |
6920 | 7029 |
6921 Label done; | 7030 // Is marking active? |
6922 Label runtime; | |
6923 | |
6924 // if (!marking_in_progress) goto done; | |
6925 if (in_bytes(PtrQueue::byte_width_of_active()) == 4) { | 7031 if (in_bytes(PtrQueue::byte_width_of_active()) == 4) { |
6926 cmpl(in_progress, 0); | 7032 cmpl(in_progress, 0); |
6927 } else { | 7033 } else { |
6928 assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption"); | 7034 assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption"); |
6929 cmpb(in_progress, 0); | 7035 cmpb(in_progress, 0); |
6930 } | 7036 } |
6931 jcc(Assembler::equal, done); | 7037 jcc(Assembler::equal, done); |
6932 | 7038 |
6933 // if (x.f == NULL) goto done; | 7039 // Do we need to load the previous value? |
6934 #ifdef _LP64 | 7040 if (obj != noreg) { |
6935 load_heap_oop(tmp2, Address(obj, 0)); | 7041 load_heap_oop(pre_val, Address(obj, 0)); |
6936 #else | 7042 } |
6937 movptr(tmp2, Address(obj, 0)); | 7043 |
6938 #endif | 7044 // Is the previous value null? |
6939 cmpptr(tmp2, (int32_t) NULL_WORD); | 7045 cmpptr(pre_val, (int32_t) NULL_WORD); |
6940 jcc(Assembler::equal, done); | 7046 jcc(Assembler::equal, done); |
6941 | 7047 |
6942 // Can we store original value in the thread's buffer? | 7048 // Can we store original value in the thread's buffer? |
6943 | 7049 // Is index == 0? |
6944 #ifdef _LP64 | 7050 // (The index field is typed as size_t.) |
6945 movslq(tmp, index); | 7051 |
6946 cmpq(tmp, 0); | 7052 movptr(tmp, index); // tmp := *index_adr |
6947 #else | 7053 cmpptr(tmp, 0); // tmp == 0? |
6948 cmpl(index, 0); | 7054 jcc(Assembler::equal, runtime); // If yes, goto runtime |
6949 #endif | 7055 |
6950 jcc(Assembler::equal, runtime); | 7056 subptr(tmp, wordSize); // tmp := tmp - wordSize |
6951 #ifdef _LP64 | 7057 movptr(index, tmp); // *index_adr := tmp |
6952 subq(tmp, wordSize); | 7058 addptr(tmp, buffer); // tmp := tmp + *buffer_adr |
6953 movl(index, tmp); | 7059 |
6954 addq(tmp, buffer); | 7060 // Record the previous value |
6955 #else | 7061 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); | 7062 jmp(done); |
7063 | |
6962 bind(runtime); | 7064 bind(runtime); |
6963 // save the live input values | 7065 // save the live input values |
6964 if(tosca_live) push(rax); | 7066 if(tosca_live) push(rax); |
6965 push(obj); | 7067 |
6966 #ifdef _LP64 | 7068 if (obj != noreg && obj != rax) |
6967 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), tmp2, r15_thread); | 7069 push(obj); |
6968 #else | 7070 |
6969 push(thread); | 7071 if (pre_val != rax) |
6970 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), tmp2, thread); | 7072 push(pre_val); |
6971 pop(thread); | 7073 |
6972 #endif | 7074 // Calling the runtime using the regular call_VM_leaf mechanism generates |
6973 pop(obj); | 7075 // code (generated by InterpreterMacroAssember::call_VM_leaf_base) |
7076 // that checks that the *(ebp+frame::interpreter_frame_last_sp) == NULL. | |
7077 // | |
7078 // If we care generating the pre-barrier without a frame (e.g. in the | |
7079 // intrinsified Reference.get() routine) then ebp might be pointing to | |
7080 // the caller frame and so this check will most likely fail at runtime. | |
7081 // | |
7082 // Expanding the call directly bypasses the generation of the check. | |
7083 // So when we do not have have a full interpreter frame on the stack | |
7084 // expand_call should be passed true. | |
7085 | |
7086 NOT_LP64( push(thread); ) | |
7087 | |
7088 if (expand_call) { | |
7089 LP64_ONLY( assert(pre_val != c_rarg1, "smashed arg"); ) | |
7090 pass_arg1(this, thread); | |
7091 pass_arg0(this, pre_val); | |
7092 MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), 2); | |
7093 } else { | |
7094 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), pre_val, thread); | |
7095 } | |
7096 | |
7097 NOT_LP64( pop(thread); ) | |
7098 | |
7099 // save the live input values | |
7100 if (pre_val != rax) | |
7101 pop(pre_val); | |
7102 | |
7103 if (obj != noreg && obj != rax) | |
7104 pop(obj); | |
7105 | |
6974 if(tosca_live) pop(rax); | 7106 if(tosca_live) pop(rax); |
7107 | |
6975 bind(done); | 7108 bind(done); |
6976 | |
6977 } | 7109 } |
6978 | 7110 |
6979 void MacroAssembler::g1_write_barrier_post(Register store_addr, | 7111 void MacroAssembler::g1_write_barrier_post(Register store_addr, |
6980 Register new_val, | 7112 Register new_val, |
6981 #ifndef _LP64 | |
6982 Register thread, | 7113 Register thread, |
6983 #endif | |
6984 Register tmp, | 7114 Register tmp, |
6985 Register tmp2) { | 7115 Register tmp2) { |
6986 | 7116 #ifdef _LP64 |
6987 LP64_ONLY(Register thread = r15_thread;) | 7117 assert(thread == r15_thread, "must be"); |
7118 #endif // _LP64 | |
7119 | |
6988 Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() + | 7120 Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() + |
6989 PtrQueue::byte_offset_of_index())); | 7121 PtrQueue::byte_offset_of_index())); |
6990 Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() + | 7122 Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() + |
6991 PtrQueue::byte_offset_of_buf())); | 7123 PtrQueue::byte_offset_of_buf())); |
7124 | |
6992 BarrierSet* bs = Universe::heap()->barrier_set(); | 7125 BarrierSet* bs = Universe::heap()->barrier_set(); |
6993 CardTableModRefBS* ct = (CardTableModRefBS*)bs; | 7126 CardTableModRefBS* ct = (CardTableModRefBS*)bs; |
6994 Label done; | 7127 Label done; |
6995 Label runtime; | 7128 Label runtime; |
6996 | 7129 |
7065 #endif | 7198 #endif |
7066 pop(new_val); | 7199 pop(new_val); |
7067 pop(store_addr); | 7200 pop(store_addr); |
7068 | 7201 |
7069 bind(done); | 7202 bind(done); |
7070 | |
7071 } | 7203 } |
7072 | 7204 |
7073 #endif // SERIALGC | 7205 #endif // SERIALGC |
7074 ////////////////////////////////////////////////////////////////////////////////// | 7206 ////////////////////////////////////////////////////////////////////////////////// |
7075 | 7207 |