1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cpu/x86/vm/interp_masm_x86_64.hpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,245 @@ 1.4 +/* 1.5 + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +// This file specializes the assember with interpreter-specific macros 1.29 + 1.30 + 1.31 +class InterpreterMacroAssembler 1.32 + : public MacroAssembler { 1.33 + protected: 1.34 + // Interpreter specific version of call_VM_base 1.35 + virtual void call_VM_leaf_base(address entry_point, 1.36 + int number_of_arguments); 1.37 + 1.38 + virtual void call_VM_base(Register oop_result, 1.39 + Register java_thread, 1.40 + Register last_java_sp, 1.41 + address entry_point, 1.42 + int number_of_arguments, 1.43 + bool check_exceptions); 1.44 + 1.45 + virtual void check_and_handle_popframe(Register java_thread); 1.46 + virtual void check_and_handle_earlyret(Register java_thread); 1.47 + 1.48 + // base routine for all dispatches 1.49 + void dispatch_base(TosState state, address* table, bool verifyoop = true); 1.50 + 1.51 + public: 1.52 + InterpreterMacroAssembler(CodeBuffer* code) 1.53 + : MacroAssembler(code) 1.54 + {} 1.55 + 1.56 + void load_earlyret_value(TosState state); 1.57 + 1.58 + // Interpreter-specific registers 1.59 + void save_bcp() 1.60 + { 1.61 + movq(Address(rbp, frame::interpreter_frame_bcx_offset * wordSize), r13); 1.62 + } 1.63 + 1.64 + void restore_bcp() 1.65 + { 1.66 + movq(r13, Address(rbp, frame::interpreter_frame_bcx_offset * wordSize)); 1.67 + } 1.68 + 1.69 + void restore_locals() 1.70 + { 1.71 + movq(r14, Address(rbp, frame::interpreter_frame_locals_offset * wordSize)); 1.72 + } 1.73 + 1.74 + // Helpers for runtime call arguments/results 1.75 + void get_method(Register reg) 1.76 + { 1.77 + movq(reg, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); 1.78 + } 1.79 + 1.80 + void get_constant_pool(Register reg) 1.81 + { 1.82 + get_method(reg); 1.83 + movq(reg, Address(reg, methodOopDesc::constants_offset())); 1.84 + } 1.85 + 1.86 + void get_constant_pool_cache(Register reg) 1.87 + { 1.88 + get_constant_pool(reg); 1.89 + movq(reg, Address(reg, constantPoolOopDesc::cache_offset_in_bytes())); 1.90 + } 1.91 + 1.92 + void get_cpool_and_tags(Register cpool, Register tags) 1.93 + { 1.94 + get_constant_pool(cpool); 1.95 + movq(tags, Address(cpool, constantPoolOopDesc::tags_offset_in_bytes())); 1.96 + } 1.97 + 1.98 + void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset); 1.99 + void get_cache_and_index_at_bcp(Register cache, Register index, 1.100 + int bcp_offset); 1.101 + void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, 1.102 + int bcp_offset); 1.103 + 1.104 + void pop_ptr(Register r = rax); 1.105 + void pop_i(Register r = rax); 1.106 + void pop_l(Register r = rax); 1.107 + void pop_f(XMMRegister r = xmm0); 1.108 + void pop_d(XMMRegister r = xmm0); 1.109 + void push_ptr(Register r = rax); 1.110 + void push_i(Register r = rax); 1.111 + void push_l(Register r = rax); 1.112 + void push_f(XMMRegister r = xmm0); 1.113 + void push_d(XMMRegister r = xmm0); 1.114 + 1.115 + void pop(TosState state); // transition vtos -> state 1.116 + void push(TosState state); // transition state -> vtos 1.117 + 1.118 + // Tagged stack support, pop and push both tag and value. 1.119 + void pop_ptr(Register r, Register tag); 1.120 + void push_ptr(Register r, Register tag); 1.121 + 1.122 + DEBUG_ONLY(void verify_stack_tag(frame::Tag t);) 1.123 + 1.124 + // Tagged stack helpers for swap and dup 1.125 + void load_ptr_and_tag(int n, Register val, Register tag); 1.126 + void store_ptr_and_tag(int n, Register val, Register tag); 1.127 + 1.128 + // Tagged Local support 1.129 + void tag_local(frame::Tag tag, int n); 1.130 + void tag_local(Register tag, int n); 1.131 + void tag_local(frame::Tag tag, Register idx); 1.132 + void tag_local(Register tag, Register idx); 1.133 + 1.134 +#ifdef ASSERT 1.135 + void verify_local_tag(frame::Tag tag, int n); 1.136 + void verify_local_tag(frame::Tag tag, Register idx); 1.137 +#endif // ASSERT 1.138 + 1.139 + void empty_expression_stack() 1.140 + { 1.141 + movq(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * 1.142 + wordSize)); 1.143 + // NULL last_sp until next java call 1.144 + movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); 1.145 + } 1.146 + 1.147 + // Super call_VM calls - correspond to MacroAssembler::call_VM(_leaf) calls 1.148 + void super_call_VM_leaf(address entry_point); 1.149 + void super_call_VM_leaf(address entry_point, Register arg_1); 1.150 + void super_call_VM_leaf(address entry_point, Register arg_1, Register arg_2); 1.151 + void super_call_VM_leaf(address entry_point, 1.152 + Register arg_1, Register arg_2, Register arg_3); 1.153 + 1.154 + // Generate a subtype check: branch to ok_is_subtype if sub_klass is 1.155 + // a subtype of super_klass. 1.156 + void gen_subtype_check( Register sub_klass, Label &ok_is_subtype ); 1.157 + 1.158 + // Dispatching 1.159 + void dispatch_prolog(TosState state, int step = 0); 1.160 + void dispatch_epilog(TosState state, int step = 0); 1.161 + // dispatch via ebx (assume ebx is loaded already) 1.162 + void dispatch_only(TosState state); 1.163 + // dispatch normal table via ebx (assume ebx is loaded already) 1.164 + void dispatch_only_normal(TosState state); 1.165 + void dispatch_only_noverify(TosState state); 1.166 + // load ebx from [esi + step] and dispatch via ebx 1.167 + void dispatch_next(TosState state, int step = 0); 1.168 + // load ebx from [esi] and dispatch via ebx and table 1.169 + void dispatch_via (TosState state, address* table); 1.170 + 1.171 + // jump to an invoked target 1.172 + void jump_from_interpreted(Register method, Register temp); 1.173 + 1.174 + 1.175 + // Returning from interpreted functions 1.176 + // 1.177 + // Removes the current activation (incl. unlocking of monitors) 1.178 + // and sets up the return address. This code is also used for 1.179 + // exception unwindwing. In that case, we do not want to throw 1.180 + // IllegalMonitorStateExceptions, since that might get us into an 1.181 + // infinite rethrow exception loop. 1.182 + // Additionally this code is used for popFrame and earlyReturn. 1.183 + // In popFrame case we want to skip throwing an exception, 1.184 + // installing an exception, and notifying jvmdi. 1.185 + // In earlyReturn case we only want to skip throwing an exception 1.186 + // and installing an exception. 1.187 + void remove_activation(TosState state, Register ret_addr, 1.188 + bool throw_monitor_exception = true, 1.189 + bool install_monitor_exception = true, 1.190 + bool notify_jvmdi = true); 1.191 + 1.192 + // Object locking 1.193 + void lock_object (Register lock_reg); 1.194 + void unlock_object(Register lock_reg); 1.195 + 1.196 + // Interpreter profiling operations 1.197 + void set_method_data_pointer_for_bcp(); 1.198 + void test_method_data_pointer(Register mdp, Label& zero_continue); 1.199 + void verify_method_data_pointer(); 1.200 + 1.201 + void set_mdp_data_at(Register mdp_in, int constant, Register value); 1.202 + void increment_mdp_data_at(Address data, bool decrement = false); 1.203 + void increment_mdp_data_at(Register mdp_in, int constant, 1.204 + bool decrement = false); 1.205 + void increment_mdp_data_at(Register mdp_in, Register reg, int constant, 1.206 + bool decrement = false); 1.207 + void set_mdp_flag_at(Register mdp_in, int flag_constant); 1.208 + void test_mdp_data_at(Register mdp_in, int offset, Register value, 1.209 + Register test_value_out, 1.210 + Label& not_equal_continue); 1.211 + 1.212 + void record_klass_in_profile(Register receiver, Register mdp, 1.213 + Register reg2); 1.214 + void record_klass_in_profile_helper(Register receiver, Register mdp, 1.215 + Register reg2, 1.216 + int start_row, Label& done); 1.217 + 1.218 + void update_mdp_by_offset(Register mdp_in, int offset_of_offset); 1.219 + void update_mdp_by_offset(Register mdp_in, Register reg, int offset_of_disp); 1.220 + void update_mdp_by_constant(Register mdp_in, int constant); 1.221 + void update_mdp_for_ret(Register return_bci); 1.222 + 1.223 + void profile_taken_branch(Register mdp, Register bumped_count); 1.224 + void profile_not_taken_branch(Register mdp); 1.225 + void profile_call(Register mdp); 1.226 + void profile_final_call(Register mdp); 1.227 + void profile_virtual_call(Register receiver, Register mdp, 1.228 + Register scratch2); 1.229 + void profile_ret(Register return_bci, Register mdp); 1.230 + void profile_null_seen(Register mdp); 1.231 + void profile_typecheck(Register mdp, Register klass, Register scratch); 1.232 + void profile_typecheck_failed(Register mdp); 1.233 + void profile_switch_default(Register mdp); 1.234 + void profile_switch_case(Register index_in_scratch, Register mdp, 1.235 + Register scratch2); 1.236 + 1.237 + // Debugging 1.238 + // only if +VerifyOops && state == atos 1.239 + void verify_oop(Register reg, TosState state = atos); 1.240 + // only if +VerifyFPU && (state == ftos || state == dtos) 1.241 + void verify_FPU(int stack_depth, TosState state = ftos); 1.242 + 1.243 + typedef enum { NotifyJVMTI, SkipNotifyJVMTI } NotifyMethodExitMode; 1.244 + 1.245 + // support for jvmti/dtrace 1.246 + void notify_method_entry(); 1.247 + void notify_method_exit(TosState state, NotifyMethodExitMode mode); 1.248 +};