Wed, 03 Jul 2013 11:50:29 -0700
Merge
duke@435 | 1 | /* |
coleenp@4037 | 2 | * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
duke@435 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | * |
duke@435 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | * published by the Free Software Foundation. |
duke@435 | 8 | * |
duke@435 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | * accompanied this code). |
duke@435 | 14 | * |
duke@435 | 15 | * You should have received a copy of the GNU General Public License version |
duke@435 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | * |
trims@1907 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
trims@1907 | 20 | * or visit www.oracle.com if you need additional information or have any |
trims@1907 | 21 | * questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
stefank@2314 | 25 | #ifndef SHARE_VM_INTERPRETER_TEMPLATETABLE_HPP |
stefank@2314 | 26 | #define SHARE_VM_INTERPRETER_TEMPLATETABLE_HPP |
stefank@2314 | 27 | |
stefank@2314 | 28 | #include "interpreter/bytecodes.hpp" |
stefank@2314 | 29 | #include "memory/allocation.hpp" |
stefank@2314 | 30 | #include "runtime/frame.hpp" |
stefank@2314 | 31 | #ifdef TARGET_ARCH_MODEL_x86_32 |
stefank@2314 | 32 | # include "interp_masm_x86_32.hpp" |
stefank@2314 | 33 | #endif |
stefank@2314 | 34 | #ifdef TARGET_ARCH_MODEL_x86_64 |
stefank@2314 | 35 | # include "interp_masm_x86_64.hpp" |
stefank@2314 | 36 | #endif |
stefank@2314 | 37 | #ifdef TARGET_ARCH_MODEL_sparc |
stefank@2314 | 38 | # include "interp_masm_sparc.hpp" |
stefank@2314 | 39 | #endif |
stefank@2314 | 40 | #ifdef TARGET_ARCH_MODEL_zero |
stefank@2314 | 41 | # include "interp_masm_zero.hpp" |
stefank@2314 | 42 | #endif |
bobv@2508 | 43 | #ifdef TARGET_ARCH_MODEL_arm |
bobv@2508 | 44 | # include "interp_masm_arm.hpp" |
bobv@2508 | 45 | #endif |
goetz@6441 | 46 | #ifdef TARGET_ARCH_MODEL_ppc_32 |
goetz@6441 | 47 | # include "interp_masm_ppc_32.hpp" |
goetz@6441 | 48 | #endif |
goetz@6441 | 49 | #ifdef TARGET_ARCH_MODEL_ppc_64 |
goetz@6441 | 50 | # include "interp_masm_ppc_64.hpp" |
bobv@2508 | 51 | #endif |
stefank@2314 | 52 | |
duke@435 | 53 | #ifndef CC_INTERP |
duke@435 | 54 | // All the necessary definitions used for (bytecode) template generation. Instead of |
duke@435 | 55 | // spreading the implementation functionality for each bytecode in the interpreter |
duke@435 | 56 | // and the snippet generator, a template is assigned to each bytecode which can be |
duke@435 | 57 | // used to generate the bytecode's implementation if needed. |
duke@435 | 58 | |
duke@435 | 59 | |
duke@435 | 60 | // A Template describes the properties of a code template for a given bytecode |
duke@435 | 61 | // and provides a generator to generate the code template. |
duke@435 | 62 | |
duke@435 | 63 | class Template VALUE_OBJ_CLASS_SPEC { |
duke@435 | 64 | private: |
duke@435 | 65 | enum Flags { |
duke@435 | 66 | uses_bcp_bit, // set if template needs the bcp pointing to bytecode |
duke@435 | 67 | does_dispatch_bit, // set if template dispatches on its own |
duke@435 | 68 | calls_vm_bit, // set if template calls the vm |
duke@435 | 69 | wide_bit // set if template belongs to a wide instruction |
duke@435 | 70 | }; |
duke@435 | 71 | |
duke@435 | 72 | typedef void (*generator)(int arg); |
duke@435 | 73 | |
duke@435 | 74 | int _flags; // describes interpreter template properties (bcp unknown) |
duke@435 | 75 | TosState _tos_in; // tos cache state before template execution |
duke@435 | 76 | TosState _tos_out; // tos cache state after template execution |
duke@435 | 77 | generator _gen; // template code generator |
duke@435 | 78 | int _arg; // argument for template code generator |
duke@435 | 79 | |
duke@435 | 80 | void initialize(int flags, TosState tos_in, TosState tos_out, generator gen, int arg); |
duke@435 | 81 | |
duke@435 | 82 | friend class TemplateTable; |
duke@435 | 83 | |
duke@435 | 84 | public: |
duke@435 | 85 | Bytecodes::Code bytecode() const; |
duke@435 | 86 | bool is_valid() const { return _gen != NULL; } |
duke@435 | 87 | bool uses_bcp() const { return (_flags & (1 << uses_bcp_bit )) != 0; } |
duke@435 | 88 | bool does_dispatch() const { return (_flags & (1 << does_dispatch_bit)) != 0; } |
duke@435 | 89 | bool calls_vm() const { return (_flags & (1 << calls_vm_bit )) != 0; } |
duke@435 | 90 | bool is_wide() const { return (_flags & (1 << wide_bit )) != 0; } |
duke@435 | 91 | TosState tos_in() const { return _tos_in; } |
duke@435 | 92 | TosState tos_out() const { return _tos_out; } |
duke@435 | 93 | void generate(InterpreterMacroAssembler* masm); |
duke@435 | 94 | }; |
duke@435 | 95 | |
duke@435 | 96 | |
duke@435 | 97 | // The TemplateTable defines all Templates and provides accessor functions |
duke@435 | 98 | // to get the template for a given bytecode. |
duke@435 | 99 | |
duke@435 | 100 | class TemplateTable: AllStatic { |
duke@435 | 101 | public: |
duke@435 | 102 | enum Operation { add, sub, mul, div, rem, _and, _or, _xor, shl, shr, ushr }; |
duke@435 | 103 | enum Condition { equal, not_equal, less, less_equal, greater, greater_equal }; |
coleenp@4037 | 104 | enum CacheByte { f1_byte = 1, f2_byte = 2 }; // byte_no codes |
duke@435 | 105 | |
duke@435 | 106 | private: |
duke@435 | 107 | static bool _is_initialized; // true if TemplateTable has been initialized |
duke@435 | 108 | static Template _template_table [Bytecodes::number_of_codes]; |
duke@435 | 109 | static Template _template_table_wide[Bytecodes::number_of_codes]; |
duke@435 | 110 | |
duke@435 | 111 | static Template* _desc; // the current template to be generated |
duke@435 | 112 | static Bytecodes::Code bytecode() { return _desc->bytecode(); } |
duke@435 | 113 | |
ysr@777 | 114 | static BarrierSet* _bs; // Cache the barrier set. |
duke@435 | 115 | public: |
duke@435 | 116 | //%note templates_1 |
duke@435 | 117 | static InterpreterMacroAssembler* _masm; // the assembler used when generating templates |
duke@435 | 118 | |
duke@435 | 119 | private: |
duke@435 | 120 | |
duke@435 | 121 | // special registers |
duke@435 | 122 | static inline Address at_bcp(int offset); |
duke@435 | 123 | |
duke@435 | 124 | // helpers |
duke@435 | 125 | static void unimplemented_bc(); |
twisti@3050 | 126 | static void patch_bytecode(Bytecodes::Code bc, Register bc_reg, |
twisti@3050 | 127 | Register temp_reg, bool load_bc_into_bc_reg = true, int byte_no = -1); |
duke@435 | 128 | |
duke@435 | 129 | // C calls |
duke@435 | 130 | static void call_VM(Register oop_result, address entry_point); |
duke@435 | 131 | static void call_VM(Register oop_result, address entry_point, Register arg_1); |
duke@435 | 132 | static void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2); |
duke@435 | 133 | static void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, Register arg_3); |
duke@435 | 134 | |
duke@435 | 135 | // these overloadings are not presently used on SPARC: |
duke@435 | 136 | static void call_VM(Register oop_result, Register last_java_sp, address entry_point); |
duke@435 | 137 | static void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1); |
duke@435 | 138 | static void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2); |
duke@435 | 139 | 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 | 140 | |
duke@435 | 141 | // bytecodes |
duke@435 | 142 | static void nop(); |
duke@435 | 143 | |
duke@435 | 144 | static void aconst_null(); |
duke@435 | 145 | static void iconst(int value); |
duke@435 | 146 | static void lconst(int value); |
duke@435 | 147 | static void fconst(int value); |
duke@435 | 148 | static void dconst(int value); |
duke@435 | 149 | |
duke@435 | 150 | static void bipush(); |
duke@435 | 151 | static void sipush(); |
duke@435 | 152 | static void ldc(bool wide); |
duke@435 | 153 | static void ldc2_w(); |
jrose@1957 | 154 | static void fast_aldc(bool wide); |
duke@435 | 155 | |
duke@435 | 156 | static void locals_index(Register reg, int offset = 1); |
duke@435 | 157 | static void iload(); |
duke@435 | 158 | static void fast_iload(); |
duke@435 | 159 | static void fast_iload2(); |
duke@435 | 160 | static void fast_icaload(); |
duke@435 | 161 | static void lload(); |
duke@435 | 162 | static void fload(); |
duke@435 | 163 | static void dload(); |
duke@435 | 164 | static void aload(); |
duke@435 | 165 | |
duke@435 | 166 | static void locals_index_wide(Register reg); |
duke@435 | 167 | static void wide_iload(); |
duke@435 | 168 | static void wide_lload(); |
duke@435 | 169 | static void wide_fload(); |
duke@435 | 170 | static void wide_dload(); |
duke@435 | 171 | static void wide_aload(); |
duke@435 | 172 | |
duke@435 | 173 | static void iaload(); |
duke@435 | 174 | static void laload(); |
duke@435 | 175 | static void faload(); |
duke@435 | 176 | static void daload(); |
duke@435 | 177 | static void aaload(); |
duke@435 | 178 | static void baload(); |
duke@435 | 179 | static void caload(); |
duke@435 | 180 | static void saload(); |
duke@435 | 181 | |
duke@435 | 182 | static void iload(int n); |
duke@435 | 183 | static void lload(int n); |
duke@435 | 184 | static void fload(int n); |
duke@435 | 185 | static void dload(int n); |
duke@435 | 186 | static void aload(int n); |
duke@435 | 187 | static void aload_0(); |
duke@435 | 188 | |
duke@435 | 189 | static void istore(); |
duke@435 | 190 | static void lstore(); |
duke@435 | 191 | static void fstore(); |
duke@435 | 192 | static void dstore(); |
duke@435 | 193 | static void astore(); |
duke@435 | 194 | |
duke@435 | 195 | static void wide_istore(); |
duke@435 | 196 | static void wide_lstore(); |
duke@435 | 197 | static void wide_fstore(); |
duke@435 | 198 | static void wide_dstore(); |
duke@435 | 199 | static void wide_astore(); |
duke@435 | 200 | |
duke@435 | 201 | static void iastore(); |
duke@435 | 202 | static void lastore(); |
duke@435 | 203 | static void fastore(); |
duke@435 | 204 | static void dastore(); |
duke@435 | 205 | static void aastore(); |
duke@435 | 206 | static void bastore(); |
duke@435 | 207 | static void castore(); |
duke@435 | 208 | static void sastore(); |
duke@435 | 209 | |
duke@435 | 210 | static void istore(int n); |
duke@435 | 211 | static void lstore(int n); |
duke@435 | 212 | static void fstore(int n); |
duke@435 | 213 | static void dstore(int n); |
duke@435 | 214 | static void astore(int n); |
duke@435 | 215 | |
duke@435 | 216 | static void pop(); |
duke@435 | 217 | static void pop2(); |
duke@435 | 218 | static void dup(); |
duke@435 | 219 | static void dup_x1(); |
duke@435 | 220 | static void dup_x2(); |
duke@435 | 221 | static void dup2(); |
duke@435 | 222 | static void dup2_x1(); |
duke@435 | 223 | static void dup2_x2(); |
duke@435 | 224 | static void swap(); |
duke@435 | 225 | |
duke@435 | 226 | static void iop2(Operation op); |
duke@435 | 227 | static void lop2(Operation op); |
duke@435 | 228 | static void fop2(Operation op); |
duke@435 | 229 | static void dop2(Operation op); |
duke@435 | 230 | |
duke@435 | 231 | static void idiv(); |
duke@435 | 232 | static void irem(); |
duke@435 | 233 | |
duke@435 | 234 | static void lmul(); |
duke@435 | 235 | static void ldiv(); |
duke@435 | 236 | static void lrem(); |
duke@435 | 237 | static void lshl(); |
duke@435 | 238 | static void lshr(); |
duke@435 | 239 | static void lushr(); |
duke@435 | 240 | |
duke@435 | 241 | static void ineg(); |
duke@435 | 242 | static void lneg(); |
duke@435 | 243 | static void fneg(); |
duke@435 | 244 | static void dneg(); |
duke@435 | 245 | |
duke@435 | 246 | static void iinc(); |
duke@435 | 247 | static void wide_iinc(); |
duke@435 | 248 | static void convert(); |
duke@435 | 249 | static void lcmp(); |
duke@435 | 250 | |
duke@435 | 251 | static void float_cmp (bool is_float, int unordered_result); |
duke@435 | 252 | static void float_cmp (int unordered_result); |
duke@435 | 253 | static void double_cmp(int unordered_result); |
duke@435 | 254 | |
duke@435 | 255 | static void count_calls(Register method, Register temp); |
duke@435 | 256 | static void branch(bool is_jsr, bool is_wide); |
duke@435 | 257 | static void if_0cmp (Condition cc); |
duke@435 | 258 | static void if_icmp (Condition cc); |
duke@435 | 259 | static void if_nullcmp(Condition cc); |
duke@435 | 260 | static void if_acmp (Condition cc); |
duke@435 | 261 | |
duke@435 | 262 | static void _goto(); |
duke@435 | 263 | static void jsr(); |
duke@435 | 264 | static void ret(); |
duke@435 | 265 | static void wide_ret(); |
duke@435 | 266 | |
duke@435 | 267 | static void goto_w(); |
duke@435 | 268 | static void jsr_w(); |
duke@435 | 269 | |
duke@435 | 270 | static void tableswitch(); |
duke@435 | 271 | static void lookupswitch(); |
duke@435 | 272 | static void fast_linearswitch(); |
duke@435 | 273 | static void fast_binaryswitch(); |
duke@435 | 274 | |
duke@435 | 275 | static void _return(TosState state); |
duke@435 | 276 | |
jrose@1920 | 277 | static void resolve_cache_and_index(int byte_no, // one of 1,2,11 |
jrose@1920 | 278 | Register cache, // output for CP cache |
jrose@1920 | 279 | Register index, // output for CP index |
jrose@1920 | 280 | size_t index_size); // one of 1,2,4 |
duke@435 | 281 | static void load_invoke_cp_cache_entry(int byte_no, |
duke@435 | 282 | Register method, |
duke@435 | 283 | Register itable_index, |
duke@435 | 284 | Register flags, |
jrose@1920 | 285 | bool is_invokevirtual, |
jrose@1920 | 286 | bool is_virtual_final, |
jrose@1920 | 287 | bool is_invokedynamic); |
duke@435 | 288 | static void load_field_cp_cache_entry(Register obj, |
duke@435 | 289 | Register cache, |
duke@435 | 290 | Register index, |
duke@435 | 291 | Register offset, |
duke@435 | 292 | Register flags, |
duke@435 | 293 | bool is_static); |
duke@435 | 294 | static void invokevirtual(int byte_no); |
duke@435 | 295 | static void invokespecial(int byte_no); |
duke@435 | 296 | static void invokestatic(int byte_no); |
duke@435 | 297 | static void invokeinterface(int byte_no); |
jrose@1161 | 298 | static void invokedynamic(int byte_no); |
twisti@3969 | 299 | static void invokehandle(int byte_no); |
duke@435 | 300 | static void fast_invokevfinal(int byte_no); |
duke@435 | 301 | |
duke@435 | 302 | static void getfield_or_static(int byte_no, bool is_static); |
duke@435 | 303 | static void putfield_or_static(int byte_no, bool is_static); |
duke@435 | 304 | static void getfield(int byte_no); |
duke@435 | 305 | static void putfield(int byte_no); |
duke@435 | 306 | static void getstatic(int byte_no); |
duke@435 | 307 | static void putstatic(int byte_no); |
duke@435 | 308 | static void pop_and_check_object(Register obj); |
duke@435 | 309 | |
duke@435 | 310 | static void _new(); |
duke@435 | 311 | static void newarray(); |
duke@435 | 312 | static void anewarray(); |
duke@435 | 313 | static void arraylength(); |
duke@435 | 314 | static void checkcast(); |
duke@435 | 315 | static void instanceof(); |
duke@435 | 316 | |
duke@435 | 317 | static void athrow(); |
duke@435 | 318 | |
duke@435 | 319 | static void monitorenter(); |
duke@435 | 320 | static void monitorexit(); |
duke@435 | 321 | |
duke@435 | 322 | static void wide(); |
duke@435 | 323 | static void multianewarray(); |
duke@435 | 324 | |
duke@435 | 325 | static void fast_xaccess(TosState state); |
duke@435 | 326 | static void fast_accessfield(TosState state); |
duke@435 | 327 | static void fast_storefield(TosState state); |
duke@435 | 328 | |
duke@435 | 329 | static void _breakpoint(); |
duke@435 | 330 | |
duke@435 | 331 | static void shouldnotreachhere(); |
duke@435 | 332 | |
duke@435 | 333 | // jvmti support |
duke@435 | 334 | static void jvmti_post_field_access(Register cache, Register index, bool is_static, bool has_tos); |
duke@435 | 335 | static void jvmti_post_field_mod(Register cache, Register index, bool is_static); |
duke@435 | 336 | static void jvmti_post_fast_field_mod(); |
duke@435 | 337 | |
duke@435 | 338 | // debugging of TemplateGenerator |
duke@435 | 339 | static void transition(TosState tos_in, TosState tos_out);// checks if in/out states expected by template generator correspond to table entries |
duke@435 | 340 | |
duke@435 | 341 | // initialization helpers |
duke@435 | 342 | static void def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)( ), char filler ); |
duke@435 | 343 | static void def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(int arg ), int arg ); |
duke@435 | 344 | static void def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(bool arg ), bool arg ); |
duke@435 | 345 | static void def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(TosState tos), TosState tos); |
duke@435 | 346 | static void def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(Operation op), Operation op); |
duke@435 | 347 | static void def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(Condition cc), Condition cc); |
duke@435 | 348 | |
duke@435 | 349 | friend class Template; |
duke@435 | 350 | |
duke@435 | 351 | // InterpreterMacroAssembler::is_a(), etc., need TemplateTable::call_VM(). |
duke@435 | 352 | friend class InterpreterMacroAssembler; |
duke@435 | 353 | |
duke@435 | 354 | public: |
duke@435 | 355 | // Initialization |
duke@435 | 356 | static void initialize(); |
duke@435 | 357 | static void pd_initialize(); |
duke@435 | 358 | |
duke@435 | 359 | // Templates |
duke@435 | 360 | static Template* template_for (Bytecodes::Code code) { Bytecodes::check (code); return &_template_table [code]; } |
duke@435 | 361 | static Template* template_for_wide(Bytecodes::Code code) { Bytecodes::wide_check(code); return &_template_table_wide[code]; } |
duke@435 | 362 | |
duke@435 | 363 | // Platform specifics |
stefank@2314 | 364 | #ifdef TARGET_ARCH_MODEL_x86_32 |
stefank@2314 | 365 | # include "templateTable_x86_32.hpp" |
stefank@2314 | 366 | #endif |
stefank@2314 | 367 | #ifdef TARGET_ARCH_MODEL_x86_64 |
stefank@2314 | 368 | # include "templateTable_x86_64.hpp" |
stefank@2314 | 369 | #endif |
stefank@2314 | 370 | #ifdef TARGET_ARCH_MODEL_sparc |
stefank@2314 | 371 | # include "templateTable_sparc.hpp" |
stefank@2314 | 372 | #endif |
stefank@2314 | 373 | #ifdef TARGET_ARCH_MODEL_zero |
stefank@2314 | 374 | # include "templateTable_zero.hpp" |
stefank@2314 | 375 | #endif |
bobv@2508 | 376 | #ifdef TARGET_ARCH_MODEL_arm |
bobv@2508 | 377 | # include "templateTable_arm.hpp" |
bobv@2508 | 378 | #endif |
goetz@6441 | 379 | #ifdef TARGET_ARCH_MODEL_ppc_32 |
goetz@6441 | 380 | # include "templateTable_ppc_32.hpp" |
bobv@2508 | 381 | #endif |
stefank@2314 | 382 | |
duke@435 | 383 | }; |
duke@435 | 384 | #endif /* !CC_INTERP */ |
stefank@2314 | 385 | |
stefank@2314 | 386 | #endif // SHARE_VM_INTERPRETER_TEMPLATETABLE_HPP |