1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cpu/x86/vm/interp_masm_x86_32.hpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,235 @@ 1.4 +/* 1.5 + * Copyright 1997-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: public MacroAssembler { 1.32 +#ifndef CC_INTERP 1.33 + protected: 1.34 + // Interpreter specific version of call_VM_base 1.35 + virtual void call_VM_leaf_base( 1.36 + address entry_point, 1.37 + int number_of_arguments 1.38 + ); 1.39 + 1.40 + virtual void call_VM_base( 1.41 + Register oop_result, 1.42 + Register java_thread, 1.43 + Register last_java_sp, 1.44 + address entry_point, 1.45 + int number_of_arguments, 1.46 + bool check_exceptions 1.47 + ); 1.48 + 1.49 + virtual void check_and_handle_popframe(Register java_thread); 1.50 + virtual void check_and_handle_earlyret(Register java_thread); 1.51 + 1.52 + // base routine for all dispatches 1.53 + void dispatch_base(TosState state, address* table, bool verifyoop = true); 1.54 +#endif /* CC_INTERP */ 1.55 + 1.56 + public: 1.57 + InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code) {} 1.58 + 1.59 + void load_earlyret_value(TosState state); 1.60 + 1.61 + // Interpreter-specific registers 1.62 +#ifdef CC_INTERP 1.63 + void save_bcp() { /* not needed in c++ interpreter and harmless */ } 1.64 + void restore_bcp() { /* not needed in c++ interpreter and harmless */ } 1.65 + 1.66 + // Helpers for runtime call arguments/results 1.67 + void get_method(Register reg); 1.68 + 1.69 +#else 1.70 + 1.71 + void save_bcp() { movl(Address(rbp, frame::interpreter_frame_bcx_offset * wordSize), rsi); } 1.72 + void restore_bcp() { movl(rsi, Address(rbp, frame::interpreter_frame_bcx_offset * wordSize)); } 1.73 + void restore_locals() { movl(rdi, Address(rbp, frame::interpreter_frame_locals_offset * wordSize)); } 1.74 + 1.75 + // Helpers for runtime call arguments/results 1.76 + void get_method(Register reg) { movl(reg, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); } 1.77 + void get_constant_pool(Register reg) { get_method(reg); movl(reg, Address(reg, methodOopDesc::constants_offset())); } 1.78 + void get_constant_pool_cache(Register reg) { get_constant_pool(reg); movl(reg, Address(reg, constantPoolOopDesc::cache_offset_in_bytes())); } 1.79 + void get_cpool_and_tags(Register cpool, Register tags) { get_constant_pool(cpool); movl(tags, Address(cpool, constantPoolOopDesc::tags_offset_in_bytes())); 1.80 + } 1.81 + void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset); 1.82 + void get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset); 1.83 + void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset); 1.84 + 1.85 + // Expression stack 1.86 + void f2ieee(); // truncate ftos to 32bits 1.87 + void d2ieee(); // truncate dtos to 64bits 1.88 +#endif // CC_INTERP 1.89 + 1.90 + 1.91 + void pop_ptr(Register r = rax); 1.92 + void pop_ptr(Register r, Register tag); 1.93 + void pop_i(Register r = rax); 1.94 + void pop_l(Register lo = rax, Register hi = rdx); 1.95 + void pop_f(); 1.96 + void pop_d(); 1.97 + void pop_ftos_to_rsp(); 1.98 + void pop_dtos_to_rsp(); 1.99 + 1.100 + void push_ptr(Register r = rax); 1.101 + void push_ptr(Register r, Register tag); 1.102 + void push_i(Register r = rax); 1.103 + void push_l(Register lo = rax, Register hi = rdx); 1.104 + void push_d(Register r = rax); 1.105 + void push_f(); 1.106 + 1.107 + void pop(TosState state); // transition vtos -> state 1.108 + void push(TosState state); // transition state -> vtos 1.109 + 1.110 + DEBUG_ONLY(void verify_stack_tag(frame::Tag t);) 1.111 + 1.112 +#ifndef CC_INTERP 1.113 + 1.114 + void empty_expression_stack() { 1.115 + movl(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize)); 1.116 + // NULL last_sp until next java call 1.117 + movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); 1.118 + } 1.119 + 1.120 + // Tagged stack helpers for swap and dup 1.121 + void load_ptr_and_tag(int n, Register val, Register tag); 1.122 + void store_ptr_and_tag(int n, Register val, Register tag); 1.123 + 1.124 + // Tagged Local support 1.125 + 1.126 + void tag_local(frame::Tag tag, int n); 1.127 + void tag_local(Register tag, int n); 1.128 + void tag_local(frame::Tag tag, Register idx); 1.129 + void tag_local(Register tag, Register idx); 1.130 + 1.131 +#ifdef ASSERT 1.132 + void verify_local_tag(frame::Tag tag, int n); 1.133 + void verify_local_tag(frame::Tag tag, Register idx); 1.134 +#endif // ASSERT 1.135 + 1.136 + // Super call_VM calls - correspond to MacroAssembler::call_VM(_leaf) calls 1.137 + void super_call_VM_leaf(address entry_point); 1.138 + void super_call_VM_leaf(address entry_point, Register arg_1); 1.139 + void super_call_VM_leaf(address entry_point, Register arg_1, Register arg_2); 1.140 + void super_call_VM_leaf(address entry_point, Register arg_1, Register arg_2, Register arg_3); 1.141 + 1.142 + // Generate a subtype check: branch to ok_is_subtype if sub_klass is 1.143 + // a subtype of super_klass. EAX holds the super_klass. Blows ECX 1.144 + // and EDI. Register sub_klass cannot be any of the above. 1.145 + void gen_subtype_check( Register sub_klass, Label &ok_is_subtype ); 1.146 + 1.147 + // Dispatching 1.148 + void dispatch_prolog(TosState state, int step = 0); 1.149 + void dispatch_epilog(TosState state, int step = 0); 1.150 + void dispatch_only(TosState state); // dispatch via rbx, (assume rbx, is loaded already) 1.151 + void dispatch_only_normal(TosState state); // dispatch normal table via rbx, (assume rbx, is loaded already) 1.152 + void dispatch_only_noverify(TosState state); 1.153 + void dispatch_next(TosState state, int step = 0); // load rbx, from [esi + step] and dispatch via rbx, 1.154 + void dispatch_via (TosState state, address* table); // load rbx, from [esi] and dispatch via rbx, and table 1.155 + 1.156 + 1.157 + // jump to an invoked target 1.158 + void jump_from_interpreted(Register method, Register temp); 1.159 + 1.160 + // Returning from interpreted functions 1.161 + // 1.162 + // Removes the current activation (incl. unlocking of monitors) 1.163 + // and sets up the return address. This code is also used for 1.164 + // exception unwindwing. In that case, we do not want to throw 1.165 + // IllegalMonitorStateExceptions, since that might get us into an 1.166 + // infinite rethrow exception loop. 1.167 + // Additionally this code is used for popFrame and earlyReturn. 1.168 + // In popFrame case we want to skip throwing an exception, 1.169 + // installing an exception, and notifying jvmdi. 1.170 + // In earlyReturn case we only want to skip throwing an exception 1.171 + // and installing an exception. 1.172 + void remove_activation(TosState state, Register ret_addr, 1.173 + bool throw_monitor_exception = true, 1.174 + bool install_monitor_exception = true, 1.175 + bool notify_jvmdi = true); 1.176 +#endif /* !CC_INTERP */ 1.177 + 1.178 + // Debugging 1.179 + void verify_oop(Register reg, TosState state = atos); // only if +VerifyOops && state == atos 1.180 +#ifndef CC_INTERP 1.181 + void verify_FPU(int stack_depth, TosState state = ftos); // only if +VerifyFPU && (state == ftos || state == dtos) 1.182 + 1.183 +#endif /* !CC_INTERP */ 1.184 + 1.185 + // Object locking 1.186 + void lock_object (Register lock_reg); 1.187 + void unlock_object(Register lock_reg); 1.188 + 1.189 +#ifndef CC_INTERP 1.190 + 1.191 + // Interpreter profiling operations 1.192 + void set_method_data_pointer_for_bcp(); 1.193 + void test_method_data_pointer(Register mdp, Label& zero_continue); 1.194 + void verify_method_data_pointer(); 1.195 + 1.196 + void set_mdp_data_at(Register mdp_in, int constant, Register value); 1.197 + void increment_mdp_data_at(Address data, bool decrement = false); 1.198 + void increment_mdp_data_at(Register mdp_in, int constant, 1.199 + bool decrement = false); 1.200 + void increment_mdp_data_at(Register mdp_in, Register reg, int constant, 1.201 + bool decrement = false); 1.202 + void set_mdp_flag_at(Register mdp_in, int flag_constant); 1.203 + void test_mdp_data_at(Register mdp_in, int offset, Register value, 1.204 + Register test_value_out, 1.205 + Label& not_equal_continue); 1.206 + 1.207 + void record_klass_in_profile(Register receiver, Register mdp, 1.208 + Register reg2); 1.209 + void record_klass_in_profile_helper(Register receiver, Register mdp, 1.210 + Register reg2, 1.211 + int start_row, Label& done); 1.212 + 1.213 + void update_mdp_by_offset(Register mdp_in, int offset_of_offset); 1.214 + void update_mdp_by_offset(Register mdp_in, Register reg, int offset_of_disp); 1.215 + void update_mdp_by_constant(Register mdp_in, int constant); 1.216 + void update_mdp_for_ret(Register return_bci); 1.217 + 1.218 + void profile_taken_branch(Register mdp, Register bumped_count); 1.219 + void profile_not_taken_branch(Register mdp); 1.220 + void profile_call(Register mdp); 1.221 + void profile_final_call(Register mdp); 1.222 + void profile_virtual_call(Register receiver, Register mdp, Register scratch2); 1.223 + void profile_ret(Register return_bci, Register mdp); 1.224 + void profile_null_seen(Register mdp); 1.225 + void profile_typecheck(Register mdp, Register klass, Register scratch); 1.226 + void profile_typecheck_failed(Register mdp); 1.227 + void profile_switch_default(Register mdp); 1.228 + void profile_switch_case(Register index_in_scratch, Register mdp, Register scratch2); 1.229 + 1.230 +#endif /* !CC_INTERP */ 1.231 + 1.232 + typedef enum { NotifyJVMTI, SkipNotifyJVMTI } NotifyMethodExitMode; 1.233 + 1.234 + // support for jvmti 1.235 + void notify_method_entry(); 1.236 + void notify_method_exit(TosState state, NotifyMethodExitMode mode); 1.237 + 1.238 +};