1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cpu/mips/vm/interp_masm_mips_64.hpp Fri Apr 29 00:06:10 2016 +0800 1.3 @@ -0,0 +1,311 @@ 1.4 +/* 1.5 + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved. 1.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 + * 1.9 + * This code is free software; you can redistribute it and/or modify it 1.10 + * under the terms of the GNU General Public License version 2 only, as 1.11 + * published by the Free Software Foundation. 1.12 + * 1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.16 + * version 2 for more details (a copy is included in the LICENSE file that 1.17 + * accompanied this code). 1.18 + * 1.19 + * You should have received a copy of the GNU General Public License version 1.20 + * 2 along with this work; if not, write to the Free Software Foundation, 1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.22 + * 1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.24 + * or visit www.oracle.com if you need additional information or have any 1.25 + * questions. 1.26 + * 1.27 + */ 1.28 + 1.29 +// This file specializes the assember with interpreter-specific macros 1.30 + 1.31 +#ifndef CPU_MIPS_VM_INTERP_MASM_MIPS_64_HPP 1.32 +#define CPU_MIPS_VM_INTERP_MASM_MIPS_64_HPP 1.33 + 1.34 +#include "asm/macroAssembler.hpp" 1.35 +#include "asm/macroAssembler.inline.hpp" 1.36 +#include "interpreter/invocationCounter.hpp" 1.37 +#include "runtime/frame.hpp" 1.38 + 1.39 + 1.40 +class InterpreterMacroAssembler: public MacroAssembler { 1.41 +#ifndef CC_INTERP 1.42 + private: 1.43 + Register _locals_register; // register that contains the pointer to the locals 1.44 + Register _bcp_register; // register that contains the bcp 1.45 + 1.46 + protected: 1.47 + // Interpreter specific version of call_VM_base 1.48 + virtual void call_VM_leaf_base(address entry_point, 1.49 + int number_of_arguments); 1.50 + 1.51 + virtual void call_VM_base(Register oop_result, 1.52 + Register java_thread, 1.53 + Register last_java_sp, 1.54 + address entry_point, 1.55 + int number_of_arguments, 1.56 + bool check_exceptions); 1.57 + 1.58 + virtual void check_and_handle_popframe(Register java_thread); 1.59 + virtual void check_and_handle_earlyret(Register java_thread); 1.60 + 1.61 + // base routine for all dispatches 1.62 + void dispatch_base(TosState state, address* table, bool verifyoop = true); 1.63 +#endif // CC_INTERP 1.64 + 1.65 + public: 1.66 + InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code), _locals_register(LVP), _bcp_register(BCP) {} 1.67 + 1.68 + void load_earlyret_value(TosState state); 1.69 + 1.70 +#ifdef CC_INTERP 1.71 + void save_bcp() { /* not needed in c++ interpreter and harmless */ } 1.72 + void restore_bcp() { /* not needed in c++ interpreter and harmless */ } 1.73 + 1.74 + // Helpers for runtime call arguments/results 1.75 + void get_method(Register reg); 1.76 + 1.77 +#else 1.78 + 1.79 + // Interpreter-specific registers 1.80 + void save_bcp() { 1.81 + sd(BCP, FP, frame::interpreter_frame_bcx_offset * wordSize); 1.82 + } 1.83 + 1.84 + void restore_bcp() { 1.85 + ld(BCP, FP, frame::interpreter_frame_bcx_offset * wordSize); 1.86 + } 1.87 + 1.88 + void restore_locals() { 1.89 + ld(LVP, FP, frame::interpreter_frame_locals_offset * wordSize); 1.90 + } 1.91 + 1.92 + // Helpers for runtime call arguments/results 1.93 + void get_method(Register reg) { 1.94 + ld(reg, FP, frame::interpreter_frame_method_offset * wordSize); 1.95 + } 1.96 + 1.97 + void get_const(Register reg){ 1.98 + get_method(reg); 1.99 + ld(reg, reg, in_bytes(Method::const_offset())); 1.100 + } 1.101 + 1.102 + void get_constant_pool(Register reg) { 1.103 + get_const(reg); 1.104 + ld(reg, reg, in_bytes(ConstMethod::constants_offset())); 1.105 + } 1.106 + 1.107 + void get_constant_pool_cache(Register reg) { 1.108 + get_constant_pool(reg); 1.109 + ld(reg, reg, ConstantPool::cache_offset_in_bytes()); 1.110 + } 1.111 + 1.112 + void get_cpool_and_tags(Register cpool, Register tags) { 1.113 + get_constant_pool(cpool); 1.114 + ld(tags, cpool, ConstantPool::tags_offset_in_bytes()); 1.115 + } 1.116 + 1.117 + void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset); 1.118 + void get_cache_and_index_at_bcp(Register cache, Register index, 1.119 + int bcp_offset, size_t index_size = sizeof (u2)); 1.120 + void get_cache_and_index_and_bytecode_at_bcp(Register cache, Register index, 1.121 + Register bytecode, int byte_no, 1.122 + int bcp_offset, size_t index_size = sizeof(u2)); 1.123 + void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, 1.124 + int bcp_offset, size_t index_size = sizeof(u2)); 1.125 + void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2)); 1.126 + void get_method_counters(Register method, Register mcs, Label& skip); 1.127 + // load cpool->resolved_references(index); 1.128 + void load_resolved_reference_at_index(Register result, Register index); 1.129 + 1.130 + void pop_ptr(Register r = V0); 1.131 + void pop_i(Register r = V0); 1.132 + //void pop_l(Register r = V0); 1.133 + void pop_l(Register lo = V0, Register hi = V1); 1.134 + //void pop_f(XMMRegister r = xmm0); 1.135 + //void pop_d(XMMRegister r = xmm0); 1.136 + void pop_f(); 1.137 + void pop_d(); 1.138 + void push_ptr(Register r = V0); 1.139 + void push_i(Register r = V0); 1.140 + //void push_l(Register r = V0); 1.141 + void push_l(Register lo = V0, Register hi = V1); 1.142 + //void push_f(XMMRegister r = xmm0); 1.143 + //void push_d(XMMRegister r = xmm0); 1.144 + void push_f(); 1.145 + void push_d(FloatRegister r = F0); 1.146 + 1.147 + void pop(Register r ) { ((MacroAssembler*)this)->pop(r); } 1.148 + 1.149 + void push(Register r ) { ((MacroAssembler*)this)->push(r); } 1.150 + //void push(int32_t imm ) { ((MacroAssembler*)this)->push(imm); } 1.151 + 1.152 + void pop_dtos_to_esp(); 1.153 + void pop_ftos_to_esp(); 1.154 + 1.155 + void pop(TosState state); // transition vtos -> state 1.156 + void push(TosState state); // transition state -> vtos 1.157 +/* 1.158 + // Tagged stack support, pop and push both tag and value. 1.159 + void pop_ptr(Register r, Register tag); 1.160 + void push_ptr(Register r, Register tag); 1.161 +#endif // CC_INTERP 1.162 + 1.163 + DEBUG_ONLY(void verify_stack_tag(frame::Tag t);) 1.164 + 1.165 +#ifndef CC_INTERP 1.166 + 1.167 + // Tagged stack helpers for swap and dup 1.168 + void load_ptr_and_tag(int n, Register val, Register tag); 1.169 + void store_ptr_and_tag(int n, Register val, Register tag); 1.170 + 1.171 + // Tagged Local support 1.172 + void tag_local(frame::Tag tag, int n); 1.173 + void tag_local(Register tag, int n); 1.174 + void tag_local(frame::Tag tag, Register idx); 1.175 + void tag_local(Register tag, Register idx); 1.176 + 1.177 +#ifdef ASSERT 1.178 + void verify_local_tag(frame::Tag tag, int n); 1.179 + void verify_local_tag(frame::Tag tag, Register idx); 1.180 +#endif // ASSERT 1.181 + 1.182 +*/ 1.183 + void empty_expression_stack() 1.184 + { 1.185 + ld(SP, FP, frame::interpreter_frame_monitor_block_top_offset * wordSize); 1.186 + // NULL last_sp until next java call 1.187 + sd(R0, FP, frame::interpreter_frame_last_sp_offset * wordSize); 1.188 + } 1.189 + 1.190 + // Super call_VM calls - correspond to MacroAssembler::call_VM(_leaf) calls 1.191 + /*void super_call_VM_leaf(address entry_point); 1.192 + void super_call_VM_leaf(address entry_point, Register arg_1); 1.193 + void super_call_VM_leaf(address entry_point, Register arg_1, Register arg_2); 1.194 + void super_call_VM_leaf(address entry_point, 1.195 + Register arg_1, Register arg_2, Register arg_3);*/ 1.196 + void load_ptr(int n, Register val); 1.197 + void store_ptr(int n, Register val); 1.198 + 1.199 + // Generate a subtype check: branch to ok_is_subtype if sub_klass is 1.200 + // a subtype of super_klass. 1.201 + //void gen_subtype_check( Register sub_klass, Label &ok_is_subtype ); 1.202 + void gen_subtype_check( Register Rsup_klass, Register sub_klass, Label &ok_is_subtype ); 1.203 + 1.204 + // Dispatching 1.205 + void dispatch_prolog(TosState state, int step = 0); 1.206 + void dispatch_epilog(TosState state, int step = 0); 1.207 + // dispatch via ebx (assume ebx is loaded already) 1.208 + void dispatch_only(TosState state); 1.209 + // dispatch normal table via ebx (assume ebx is loaded already) 1.210 + void dispatch_only_normal(TosState state); 1.211 + void dispatch_only_noverify(TosState state); 1.212 + // load ebx from [esi + step] and dispatch via ebx 1.213 + void dispatch_next(TosState state, int step = 0); 1.214 + // load ebx from [esi] and dispatch via ebx and table 1.215 + void dispatch_via (TosState state, address* table); 1.216 + 1.217 + // jump to an invoked target 1.218 + void prepare_to_jump_from_interpreted(); 1.219 + void jump_from_interpreted(Register method, Register temp); 1.220 + 1.221 + 1.222 + // Returning from interpreted functions 1.223 + // 1.224 + // Removes the current activation (incl. unlocking of monitors) 1.225 + // and sets up the return address. This code is also used for 1.226 + // exception unwindwing. In that case, we do not want to throw 1.227 + // IllegalMonitorStateExceptions, since that might get us into an 1.228 + // infinite rethrow exception loop. 1.229 + // Additionally this code is used for popFrame and earlyReturn. 1.230 + // In popFrame case we want to skip throwing an exception, 1.231 + // installing an exception, and notifying jvmdi. 1.232 + // In earlyReturn case we only want to skip throwing an exception 1.233 + // and installing an exception. 1.234 + void remove_activation(TosState state, Register ret_addr, 1.235 + bool throw_monitor_exception = true, 1.236 + bool install_monitor_exception = true, 1.237 + bool notify_jvmdi = true); 1.238 +#endif // CC_INTERP 1.239 + 1.240 + // Object locking 1.241 + void lock_object (Register lock_reg); 1.242 + void unlock_object(Register lock_reg); 1.243 + 1.244 +#ifndef CC_INTERP 1.245 + 1.246 + // Interpreter profiling operations 1.247 + void set_method_data_pointer_for_bcp(); 1.248 + void test_method_data_pointer(Register mdp, Label& zero_continue); 1.249 + void verify_method_data_pointer(); 1.250 + 1.251 + void set_mdp_data_at(Register mdp_in, int constant, Register value); 1.252 + void increment_mdp_data_at(Address data, bool decrement = false); 1.253 + void increment_mdp_data_at(Register mdp_in, int constant, 1.254 + bool decrement = false); 1.255 + void increment_mdp_data_at(Register mdp_in, Register reg, int constant, 1.256 + bool decrement = false); 1.257 +/* void increment_mask_and_jump(Address counter_addr, 1.258 + int increment, int mask, 1.259 + Register scratch, bool preloaded, 1.260 + Condition cond, Label* where); */ 1.261 + void set_mdp_flag_at(Register mdp_in, int flag_constant); 1.262 + void test_mdp_data_at(Register mdp_in, int offset, Register value, 1.263 + Register test_value_out, 1.264 + Label& not_equal_continue); 1.265 + 1.266 + void record_klass_in_profile(Register receiver, Register mdp, 1.267 + Register reg2, bool is_virtual_call); 1.268 + void record_klass_in_profile_helper(Register receiver, Register mdp, 1.269 + Register reg2, int start_row, 1.270 + Label& done, bool is_virtual_call); 1.271 + 1.272 + void update_mdp_by_offset(Register mdp_in, int offset_of_offset); 1.273 + void update_mdp_by_offset(Register mdp_in, Register reg, int offset_of_disp); 1.274 + void update_mdp_by_constant(Register mdp_in, int constant); 1.275 + void update_mdp_for_ret(Register return_bci); 1.276 + 1.277 + void profile_taken_branch(Register mdp, Register bumped_count); 1.278 + void profile_not_taken_branch(Register mdp); 1.279 + void profile_call(Register mdp); 1.280 + void profile_final_call(Register mdp); 1.281 + void profile_virtual_call(Register receiver, Register mdp, 1.282 + Register scratch2, 1.283 + bool receiver_can_be_null = false); 1.284 + void profile_ret(Register return_bci, Register mdp); 1.285 + void profile_checkcast(bool is_null , Register mdp); 1.286 + void profile_null_seen(Register mdp); 1.287 + void profile_typecheck(Register mdp, Register klass, Register scratch); 1.288 + void profile_typecheck_failed(Register mdp); 1.289 + void profile_switch_default(Register mdp); 1.290 + void profile_switch_case(Register index_in_scratch, Register mdp, 1.291 + Register scratch2); 1.292 + 1.293 + // Debugging 1.294 + // only if +VerifyOops && state == atos 1.295 + void verify_oop(Register reg, TosState state = atos); 1.296 + // only if +VerifyFPU && (state == ftos || state == dtos) 1.297 + void verify_FPU(int stack_depth, TosState state = ftos); 1.298 + 1.299 + void profile_obj_type(Register obj, const Address& mdo_addr); 1.300 + void profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual); 1.301 + void profile_return_type(Register mdp, Register ret, Register tmp); 1.302 + void profile_parameters_type(Register mdp, Register tmp1, Register tmp2); 1.303 +#endif // !CC_INTERP 1.304 + 1.305 + typedef enum { NotifyJVMTI, SkipNotifyJVMTI } NotifyMethodExitMode; 1.306 + 1.307 + // support for jvmti/dtrace 1.308 + void notify_method_entry(); 1.309 + void notify_method_exit(bool is_native_method, TosState state, NotifyMethodExitMode mode); 1.310 + void save_return_value(TosState state, bool is_native_call); 1.311 + void restore_return_value(TosState state, bool is_native_call); 1.312 +}; 1.313 + 1.314 +#endif // CPU_MIPS_VM_INTERP_MASM_MIPS_64_HPP