duke@435: /* coleenp@4037: * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: stefank@2314: #ifndef SHARE_VM_INTERPRETER_TEMPLATETABLE_HPP stefank@2314: #define SHARE_VM_INTERPRETER_TEMPLATETABLE_HPP stefank@2314: stefank@2314: #include "interpreter/bytecodes.hpp" stefank@2314: #include "memory/allocation.hpp" stefank@2314: #include "runtime/frame.hpp" stefank@2314: #ifdef TARGET_ARCH_MODEL_x86_32 stefank@2314: # include "interp_masm_x86_32.hpp" stefank@2314: #endif stefank@2314: #ifdef TARGET_ARCH_MODEL_x86_64 stefank@2314: # include "interp_masm_x86_64.hpp" stefank@2314: #endif stefank@2314: #ifdef TARGET_ARCH_MODEL_sparc stefank@2314: # include "interp_masm_sparc.hpp" stefank@2314: #endif stefank@2314: #ifdef TARGET_ARCH_MODEL_zero stefank@2314: # include "interp_masm_zero.hpp" stefank@2314: #endif bobv@2508: #ifdef TARGET_ARCH_MODEL_arm bobv@2508: # include "interp_masm_arm.hpp" bobv@2508: #endif bobv@2508: #ifdef TARGET_ARCH_MODEL_ppc bobv@2508: # include "interp_masm_ppc.hpp" bobv@2508: #endif stefank@2314: duke@435: #ifndef CC_INTERP duke@435: // All the necessary definitions used for (bytecode) template generation. Instead of duke@435: // spreading the implementation functionality for each bytecode in the interpreter duke@435: // and the snippet generator, a template is assigned to each bytecode which can be duke@435: // used to generate the bytecode's implementation if needed. duke@435: duke@435: duke@435: // A Template describes the properties of a code template for a given bytecode duke@435: // and provides a generator to generate the code template. duke@435: duke@435: class Template VALUE_OBJ_CLASS_SPEC { duke@435: private: duke@435: enum Flags { duke@435: uses_bcp_bit, // set if template needs the bcp pointing to bytecode duke@435: does_dispatch_bit, // set if template dispatches on its own duke@435: calls_vm_bit, // set if template calls the vm duke@435: wide_bit // set if template belongs to a wide instruction duke@435: }; duke@435: duke@435: typedef void (*generator)(int arg); duke@435: duke@435: int _flags; // describes interpreter template properties (bcp unknown) duke@435: TosState _tos_in; // tos cache state before template execution duke@435: TosState _tos_out; // tos cache state after template execution duke@435: generator _gen; // template code generator duke@435: int _arg; // argument for template code generator duke@435: duke@435: void initialize(int flags, TosState tos_in, TosState tos_out, generator gen, int arg); duke@435: duke@435: friend class TemplateTable; duke@435: duke@435: public: duke@435: Bytecodes::Code bytecode() const; duke@435: bool is_valid() const { return _gen != NULL; } duke@435: bool uses_bcp() const { return (_flags & (1 << uses_bcp_bit )) != 0; } duke@435: bool does_dispatch() const { return (_flags & (1 << does_dispatch_bit)) != 0; } duke@435: bool calls_vm() const { return (_flags & (1 << calls_vm_bit )) != 0; } duke@435: bool is_wide() const { return (_flags & (1 << wide_bit )) != 0; } duke@435: TosState tos_in() const { return _tos_in; } duke@435: TosState tos_out() const { return _tos_out; } duke@435: void generate(InterpreterMacroAssembler* masm); duke@435: }; duke@435: duke@435: duke@435: // The TemplateTable defines all Templates and provides accessor functions duke@435: // to get the template for a given bytecode. duke@435: duke@435: class TemplateTable: AllStatic { duke@435: public: duke@435: enum Operation { add, sub, mul, div, rem, _and, _or, _xor, shl, shr, ushr }; duke@435: enum Condition { equal, not_equal, less, less_equal, greater, greater_equal }; coleenp@4037: enum CacheByte { f1_byte = 1, f2_byte = 2 }; // byte_no codes duke@435: duke@435: private: duke@435: static bool _is_initialized; // true if TemplateTable has been initialized duke@435: static Template _template_table [Bytecodes::number_of_codes]; duke@435: static Template _template_table_wide[Bytecodes::number_of_codes]; duke@435: duke@435: static Template* _desc; // the current template to be generated duke@435: static Bytecodes::Code bytecode() { return _desc->bytecode(); } duke@435: ysr@777: static BarrierSet* _bs; // Cache the barrier set. duke@435: public: duke@435: //%note templates_1 duke@435: static InterpreterMacroAssembler* _masm; // the assembler used when generating templates duke@435: duke@435: private: duke@435: duke@435: // special registers duke@435: static inline Address at_bcp(int offset); duke@435: duke@435: // helpers duke@435: static void unimplemented_bc(); twisti@3050: static void patch_bytecode(Bytecodes::Code bc, Register bc_reg, twisti@3050: Register temp_reg, bool load_bc_into_bc_reg = true, int byte_no = -1); duke@435: duke@435: // C calls duke@435: static void call_VM(Register oop_result, address entry_point); duke@435: static void call_VM(Register oop_result, address entry_point, Register arg_1); duke@435: static void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2); duke@435: static void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, Register arg_3); duke@435: duke@435: // these overloadings are not presently used on SPARC: duke@435: static void call_VM(Register oop_result, Register last_java_sp, address entry_point); duke@435: static void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1); duke@435: static void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2); duke@435: static void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, Register arg_3); duke@435: duke@435: // bytecodes duke@435: static void nop(); duke@435: duke@435: static void aconst_null(); duke@435: static void iconst(int value); duke@435: static void lconst(int value); duke@435: static void fconst(int value); duke@435: static void dconst(int value); duke@435: duke@435: static void bipush(); duke@435: static void sipush(); duke@435: static void ldc(bool wide); duke@435: static void ldc2_w(); jrose@1957: static void fast_aldc(bool wide); duke@435: duke@435: static void locals_index(Register reg, int offset = 1); duke@435: static void iload(); duke@435: static void fast_iload(); duke@435: static void fast_iload2(); duke@435: static void fast_icaload(); duke@435: static void lload(); duke@435: static void fload(); duke@435: static void dload(); duke@435: static void aload(); duke@435: duke@435: static void locals_index_wide(Register reg); duke@435: static void wide_iload(); duke@435: static void wide_lload(); duke@435: static void wide_fload(); duke@435: static void wide_dload(); duke@435: static void wide_aload(); duke@435: duke@435: static void iaload(); duke@435: static void laload(); duke@435: static void faload(); duke@435: static void daload(); duke@435: static void aaload(); duke@435: static void baload(); duke@435: static void caload(); duke@435: static void saload(); duke@435: duke@435: static void iload(int n); duke@435: static void lload(int n); duke@435: static void fload(int n); duke@435: static void dload(int n); duke@435: static void aload(int n); duke@435: static void aload_0(); duke@435: duke@435: static void istore(); duke@435: static void lstore(); duke@435: static void fstore(); duke@435: static void dstore(); duke@435: static void astore(); duke@435: duke@435: static void wide_istore(); duke@435: static void wide_lstore(); duke@435: static void wide_fstore(); duke@435: static void wide_dstore(); duke@435: static void wide_astore(); duke@435: duke@435: static void iastore(); duke@435: static void lastore(); duke@435: static void fastore(); duke@435: static void dastore(); duke@435: static void aastore(); duke@435: static void bastore(); duke@435: static void castore(); duke@435: static void sastore(); duke@435: duke@435: static void istore(int n); duke@435: static void lstore(int n); duke@435: static void fstore(int n); duke@435: static void dstore(int n); duke@435: static void astore(int n); duke@435: duke@435: static void pop(); duke@435: static void pop2(); duke@435: static void dup(); duke@435: static void dup_x1(); duke@435: static void dup_x2(); duke@435: static void dup2(); duke@435: static void dup2_x1(); duke@435: static void dup2_x2(); duke@435: static void swap(); duke@435: duke@435: static void iop2(Operation op); duke@435: static void lop2(Operation op); duke@435: static void fop2(Operation op); duke@435: static void dop2(Operation op); duke@435: duke@435: static void idiv(); duke@435: static void irem(); duke@435: duke@435: static void lmul(); duke@435: static void ldiv(); duke@435: static void lrem(); duke@435: static void lshl(); duke@435: static void lshr(); duke@435: static void lushr(); duke@435: duke@435: static void ineg(); duke@435: static void lneg(); duke@435: static void fneg(); duke@435: static void dneg(); duke@435: duke@435: static void iinc(); duke@435: static void wide_iinc(); duke@435: static void convert(); duke@435: static void lcmp(); duke@435: duke@435: static void float_cmp (bool is_float, int unordered_result); duke@435: static void float_cmp (int unordered_result); duke@435: static void double_cmp(int unordered_result); duke@435: duke@435: static void count_calls(Register method, Register temp); duke@435: static void branch(bool is_jsr, bool is_wide); duke@435: static void if_0cmp (Condition cc); duke@435: static void if_icmp (Condition cc); duke@435: static void if_nullcmp(Condition cc); duke@435: static void if_acmp (Condition cc); duke@435: duke@435: static void _goto(); duke@435: static void jsr(); duke@435: static void ret(); duke@435: static void wide_ret(); duke@435: duke@435: static void goto_w(); duke@435: static void jsr_w(); duke@435: duke@435: static void tableswitch(); duke@435: static void lookupswitch(); duke@435: static void fast_linearswitch(); duke@435: static void fast_binaryswitch(); duke@435: duke@435: static void _return(TosState state); duke@435: jrose@1920: static void resolve_cache_and_index(int byte_no, // one of 1,2,11 jrose@1920: Register cache, // output for CP cache jrose@1920: Register index, // output for CP index jrose@1920: size_t index_size); // one of 1,2,4 duke@435: static void load_invoke_cp_cache_entry(int byte_no, duke@435: Register method, duke@435: Register itable_index, duke@435: Register flags, jrose@1920: bool is_invokevirtual, jrose@1920: bool is_virtual_final, jrose@1920: bool is_invokedynamic); duke@435: static void load_field_cp_cache_entry(Register obj, duke@435: Register cache, duke@435: Register index, duke@435: Register offset, duke@435: Register flags, duke@435: bool is_static); duke@435: static void invokevirtual(int byte_no); duke@435: static void invokespecial(int byte_no); duke@435: static void invokestatic(int byte_no); duke@435: static void invokeinterface(int byte_no); jrose@1161: static void invokedynamic(int byte_no); twisti@3969: static void invokehandle(int byte_no); duke@435: static void fast_invokevfinal(int byte_no); duke@435: duke@435: static void getfield_or_static(int byte_no, bool is_static); duke@435: static void putfield_or_static(int byte_no, bool is_static); duke@435: static void getfield(int byte_no); duke@435: static void putfield(int byte_no); duke@435: static void getstatic(int byte_no); duke@435: static void putstatic(int byte_no); duke@435: static void pop_and_check_object(Register obj); duke@435: duke@435: static void _new(); duke@435: static void newarray(); duke@435: static void anewarray(); duke@435: static void arraylength(); duke@435: static void checkcast(); duke@435: static void instanceof(); duke@435: duke@435: static void athrow(); duke@435: duke@435: static void monitorenter(); duke@435: static void monitorexit(); duke@435: duke@435: static void wide(); duke@435: static void multianewarray(); duke@435: duke@435: static void fast_xaccess(TosState state); duke@435: static void fast_accessfield(TosState state); duke@435: static void fast_storefield(TosState state); duke@435: duke@435: static void _breakpoint(); duke@435: duke@435: static void shouldnotreachhere(); duke@435: duke@435: // jvmti support duke@435: static void jvmti_post_field_access(Register cache, Register index, bool is_static, bool has_tos); duke@435: static void jvmti_post_field_mod(Register cache, Register index, bool is_static); duke@435: static void jvmti_post_fast_field_mod(); duke@435: duke@435: // debugging of TemplateGenerator duke@435: static void transition(TosState tos_in, TosState tos_out);// checks if in/out states expected by template generator correspond to table entries duke@435: duke@435: // initialization helpers duke@435: static void def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)( ), char filler ); duke@435: static void def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(int arg ), int arg ); duke@435: static void def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(bool arg ), bool arg ); duke@435: static void def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(TosState tos), TosState tos); duke@435: static void def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(Operation op), Operation op); duke@435: static void def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(Condition cc), Condition cc); duke@435: duke@435: friend class Template; duke@435: duke@435: // InterpreterMacroAssembler::is_a(), etc., need TemplateTable::call_VM(). duke@435: friend class InterpreterMacroAssembler; duke@435: duke@435: public: duke@435: // Initialization duke@435: static void initialize(); duke@435: static void pd_initialize(); duke@435: duke@435: // Templates duke@435: static Template* template_for (Bytecodes::Code code) { Bytecodes::check (code); return &_template_table [code]; } duke@435: static Template* template_for_wide(Bytecodes::Code code) { Bytecodes::wide_check(code); return &_template_table_wide[code]; } duke@435: duke@435: // Platform specifics stefank@2314: #ifdef TARGET_ARCH_MODEL_x86_32 stefank@2314: # include "templateTable_x86_32.hpp" stefank@2314: #endif stefank@2314: #ifdef TARGET_ARCH_MODEL_x86_64 stefank@2314: # include "templateTable_x86_64.hpp" stefank@2314: #endif stefank@2314: #ifdef TARGET_ARCH_MODEL_sparc stefank@2314: # include "templateTable_sparc.hpp" stefank@2314: #endif stefank@2314: #ifdef TARGET_ARCH_MODEL_zero stefank@2314: # include "templateTable_zero.hpp" stefank@2314: #endif bobv@2508: #ifdef TARGET_ARCH_MODEL_arm bobv@2508: # include "templateTable_arm.hpp" bobv@2508: #endif bobv@2508: #ifdef TARGET_ARCH_MODEL_ppc bobv@2508: # include "templateTable_ppc.hpp" bobv@2508: #endif stefank@2314: duke@435: }; duke@435: #endif /* !CC_INTERP */ stefank@2314: stefank@2314: #endif // SHARE_VM_INTERPRETER_TEMPLATETABLE_HPP