1 /* 2 * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "interpreter/extendedBytecodes.hpp" 26 #include "interpreter/interpreter.hpp" 27 #include "interpreter/interp_masm.hpp" 28 #include "interpreter/templateInterpreterGenerator.hpp" 29 #include "interpreter/templateTable.hpp" 30 31 BCSetTemplate* BCSetTemplate::_BCSetTemplates[Bytecodes::number_of_bcset]; 32 33 //------------------------------------------------------------------------------------------------------------------------ 34 35 void BCSetTemplate::initialize() { 36 for (int i = 0; i < Bytecodes::number_of_bcset; i++) { 37 _BCSetTemplates[i] = NULL; 38 } 39 assign(Bytecodes::_bcset_int, initialize_type_I_BCSet()); 40 assign(Bytecodes::_bcset_float, initialize_type_F_BCSet()); 41 42 } 43 44 // This method should be in TemplateInterpreter rather than in 45 // the TypedBytecodesGenerator class 46 Bytecodes::BCSet BCSetTemplate::resolve(Symbol* type) { 47 switch(type->byte_at(0)) { 48 case 'B': 49 return Bytecodes::_bcset_byte; 50 case 'S': 51 return Bytecodes::_bcset_short; 52 case 'I': 53 return Bytecodes::_bcset_int; 54 case 'J': 55 return Bytecodes::_bcset_long; 56 case 'C': 57 return Bytecodes::_bcset_char; 58 case 'F': 59 return Bytecodes::_bcset_float; 60 case 'D': 61 return Bytecodes::_bcset_double; 62 case 'L': 63 return Bytecodes::_bcset_reference; 64 case '[': 65 return Bytecodes::_bcset_array; 66 default: 67 ShouldNotReachHere(); 68 } 69 return Bytecodes::_bcset_illegal; 70 } 71 72 void BCSetTemplate::assign(Bytecodes::BCSet bcset, BCSetTemplate* gen) { 73 assert(_BCSetTemplates[bcset] == NULL, "Double assignment"); 74 _BCSetTemplates[bcset] = gen; 75 } 76 77 //------------------------------------------------------------------------------------------------------------------------ 78 79 void BCSetTemplate::define_alias(Bytecodes::Code new_bytecode, Bytecodes::Code existing_bytecode) { 80 assert(Bytecodes::bcset(new_bytecode) == _bcset, "BType mismatch"); 81 assert(Bytecodes::bcset(existing_bytecode) == Bytecodes::_bcset_default, "Aliasing only works to legacy bytecodes"); 82 assert(Bytecodes::is_defined(new_bytecode), "Sanity check"); 83 if (_aliases == NULL) { 84 _aliases = new (ResourceObj::C_HEAP, mtInternal) 85 GrowableArray<Alias>(8, true); // Hard coded random constant => BAD! 86 } 87 Alias alias; 88 alias._extended_bytecode = new_bytecode; 89 alias._alias = existing_bytecode; 90 _aliases->push(alias); 91 } 92 93 void BCSetTemplate::define_template(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(), char filler) { 94 assert(filler == ' ', "just checkin'"); 95 define_template(code, flags, in, out, (Template::generator)gen, 0); 96 } 97 98 void BCSetTemplate::define_template(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(TosState tos), TosState tos) { 99 define_template(code, flags, in, out, (Template::generator)gen, (int)tos); 100 } 101 102 void BCSetTemplate::define_template(Bytecodes::Code code, int flags, TosState in, TosState out, 103 void (*gen)(int arg), int arg) { 104 const int iswd = 1 << Template::wide_bit; 105 // determine which table to use 106 bool is_wide = (flags & iswd) != 0; 107 // make sure that typed bytecode have a vtos entry point 108 // TosCa is currently not supported by typed bytecodes 109 // temporarely disabling this assert to test typed I bytecodes with legacy templates 110 // assert(in == vtos, "typed bytecodes have vtos entry point only"); 111 Template t; 112 t.initialize(code, flags, in, out, gen, arg); 113 if (_templates == NULL) { 114 _templates = new (ResourceObj::C_HEAP, mtInternal) 115 GrowableArray<Template>(8, true); // Hard coded random constant => BAD! 116 } 117 _templates->push(t); 118 } 119 120 //------------------------------------------------------------------------------------------------------------------------ 121 122 #define USE_ALIASES 1 123 124 BCSetTemplate* BCSetTemplate::initialize_type_I_BCSet() { 125 // For better readability 126 const char _ = ' '; 127 const int ____ = 0; 128 const int ubcp = 1 << Template::uses_bcp_bit; 129 const int disp = 1 << Template::does_dispatch_bit; 130 const int clvm = 1 << Template::calls_vm_bit; 131 const int iswd = 1 << Template::wide_bit; 132 BCSetTemplate* t = new BCSetTemplate(Bytecodes::_bcset_int); 133 #if USE_ALIASES 134 // Aliases based implementation 135 t->define_alias(Bytecodes::cast(Bytecodes::_typed_I_aload) , Bytecodes::_nofast_iload); 136 t->define_alias(Bytecodes::cast(Bytecodes::_typed_I_aload_0) , Bytecodes::_iload_0); 137 t->define_alias(Bytecodes::cast(Bytecodes::_typed_I_aload_1) , Bytecodes::_iload_1); 138 t->define_alias(Bytecodes::cast(Bytecodes::_typed_I_aload_2) , Bytecodes::_iload_2); 139 t->define_alias(Bytecodes::cast(Bytecodes::_typed_I_aload_3) , Bytecodes::_iload_3); 140 t->define_alias(Bytecodes::cast(Bytecodes::_typed_I_astore) , Bytecodes::_istore); 141 t->define_alias(Bytecodes::cast(Bytecodes::_typed_I_astore_0) , Bytecodes::_istore_0); 142 t->define_alias(Bytecodes::cast(Bytecodes::_typed_I_astore_1) , Bytecodes::_istore_1); 143 t->define_alias(Bytecodes::cast(Bytecodes::_typed_I_astore_2) , Bytecodes::_istore_2); 144 t->define_alias(Bytecodes::cast(Bytecodes::_typed_I_astore_3) , Bytecodes::_istore_3); 145 t->define_alias(Bytecodes::cast(Bytecodes::_typed_I_aaload) , Bytecodes::_iaload); 146 t->define_alias(Bytecodes::cast(Bytecodes::_typed_I_aastore) , Bytecodes::_iastore); 147 t->define_alias(Bytecodes::cast(Bytecodes::_typed_I_areturn) , Bytecodes::_ireturn); 148 t->define_alias(Bytecodes::cast(Bytecodes::_typed_I_aconst_null), Bytecodes::_iconst_0); 149 #else 150 // Templates based implementation 151 152 t->define_template(Bytecodes::cast(Bytecodes::_typed_I_aload) , ubcp|____|clvm|____, vtos, itos, TemplateTable::iload , _ ); 153 t->define_template(Bytecodes::cast(Bytecodes::_typed_I_aload_0) , ubcp|____|____|____, vtos, itos, TemplateTable::iload , 0 ); 154 t->define_template(Bytecodes::cast(Bytecodes::_typed_I_aload_1) , ubcp|____|____|____, vtos, itos, TemplateTable::iload , 1 ); 155 t->define_template(Bytecodes::cast(Bytecodes::_typed_I_aload_2) , ubcp|____|____|____, vtos, itos, TemplateTable::iload , 2 ); 156 t->define_template(Bytecodes::cast(Bytecodes::_typed_I_aload_3) , ubcp|____|____|____, vtos, itos, TemplateTable::iload , 3 ); 157 t->define_template(Bytecodes::cast(Bytecodes::_typed_I_astore) , ubcp|____|clvm|____, itos, vtos, TemplateTable::istore , _ ); 158 t->define_template(Bytecodes::cast(Bytecodes::_typed_I_astore_0), ubcp|____|____|____, itos, vtos, TemplateTable::istore , 0 ); 159 t->define_template(Bytecodes::cast(Bytecodes::_typed_I_astore_1), ubcp|____|____|____, itos, vtos, TemplateTable::istore , 1 ); 160 t->define_template(Bytecodes::cast(Bytecodes::_typed_I_astore_2), ubcp|____|____|____, itos, vtos, TemplateTable::istore , 2 ); 161 t->define_template(Bytecodes::cast(Bytecodes::_typed_I_astore_3), ubcp|____|____|____, itos, vtos, TemplateTable::istore , 3 ); 162 t->define_template(Bytecodes::cast(Bytecodes::_typed_I_aaload) , ____|____|____|____, itos, itos, TemplateTable::iaload , _ ); 163 t->define_template(Bytecodes::cast(Bytecodes::_typed_I_aastore) , ____|____|clvm|____, itos, vtos, TemplateTable::iastore , _ ); 164 t->define_template(Bytecodes::cast(Bytecodes::_typed_I_areturn) , ____|disp|clvm|____, itos, itos, TemplateTable::_return , itos ); 165 // wide variants 166 t->define_template(Bytecodes::cast(Bytecodes::_typed_I_aload) , ubcp|____|____|iswd, vtos, itos, TemplateTable::wide_iload , _ ); 167 t->define_template(Bytecodes::cast(Bytecodes::_typed_I_astore) , ubcp|____|____|iswd, vtos, vtos, TemplateTable::wide_istore , _ ); 168 #endif 169 // A new template is required for typed anewarray 170 t->define_template(Bytecodes::cast(Bytecodes::_typed_I_anewarray) , ubcp|____|clvm|____, itos, atos, TemplateTable::new_primitive_array , T_INT ); 171 return t; 172 } 173 174 BCSetTemplate* BCSetTemplate::initialize_type_F_BCSet() { 175 // For better readability 176 const char _ = ' '; 177 const int ____ = 0; 178 const int ubcp = 1 << Template::uses_bcp_bit; 179 const int disp = 1 << Template::does_dispatch_bit; 180 const int clvm = 1 << Template::calls_vm_bit; 181 const int iswd = 1 << Template::wide_bit; 182 BCSetTemplate* t = new BCSetTemplate(Bytecodes::_bcset_float); 183 #if USE_ALIASES 184 // Aliases based implementation 185 t->define_alias(Bytecodes::cast(Bytecodes::_typed_F_aload) , Bytecodes::_fload); 186 t->define_alias(Bytecodes::cast(Bytecodes::_typed_F_aload_0) , Bytecodes::_fload_0); 187 t->define_alias(Bytecodes::cast(Bytecodes::_typed_F_aload_1) , Bytecodes::_fload_1); 188 t->define_alias(Bytecodes::cast(Bytecodes::_typed_F_aload_2) , Bytecodes::_fload_2); 189 t->define_alias(Bytecodes::cast(Bytecodes::_typed_F_aload_3) , Bytecodes::_fload_3); 190 t->define_alias(Bytecodes::cast(Bytecodes::_typed_F_astore) , Bytecodes::_fstore); 191 t->define_alias(Bytecodes::cast(Bytecodes::_typed_F_astore_0) , Bytecodes::_fstore_0); 192 t->define_alias(Bytecodes::cast(Bytecodes::_typed_F_astore_1) , Bytecodes::_fstore_1); 193 t->define_alias(Bytecodes::cast(Bytecodes::_typed_F_astore_2) , Bytecodes::_fstore_2); 194 t->define_alias(Bytecodes::cast(Bytecodes::_typed_F_astore_3) , Bytecodes::_fstore_3); 195 t->define_alias(Bytecodes::cast(Bytecodes::_typed_F_aaload) , Bytecodes::_faload); 196 t->define_alias(Bytecodes::cast(Bytecodes::_typed_F_aastore) , Bytecodes::_fastore); 197 t->define_alias(Bytecodes::cast(Bytecodes::_typed_F_areturn) , Bytecodes::_freturn); 198 t->define_alias(Bytecodes::cast(Bytecodes::_typed_F_aconst_null), Bytecodes::_fconst_0); 199 #else 200 // Templates based implementation 201 t->define_template(Bytecodes::cast(Bytecodes::_typed_F_aload) , ubcp|____|clvm|____, vtos, ftos, TemplateTable::fload , _ ); 202 t->define_template(Bytecodes::cast(Bytecodes::_typed_F_aload_0) , ubcp|____|____|____, vtos, ftos, TemplateTable::fload , 0 ); 203 t->define_template(Bytecodes::cast(Bytecodes::_typed_F_aload_1) , ubcp|____|____|____, vtos, ftos, TemplateTable::fload , 1 ); 204 t->define_template(Bytecodes::cast(Bytecodes::_typed_F_aload_2) , ubcp|____|____|____, vtos, ftos, TemplateTable::fload , 2 ); 205 t->define_template(Bytecodes::cast(Bytecodes::_typed_F_aload_3) , ubcp|____|____|____, vtos, ftos, TemplateTable::fload , 3 ); 206 t->define_template(Bytecodes::cast(Bytecodes::_typed_F_astore) , ubcp|____|clvm|____, ftos, vtos, TemplateTable::fstore , _ ); 207 t->define_template(Bytecodes::cast(Bytecodes::_typed_F_astore_0), ubcp|____|____|____, ftos, vtos, TemplateTable::fstore , 0 ); 208 t->define_template(Bytecodes::cast(Bytecodes::_typed_F_astore_1), ubcp|____|____|____, ftos, vtos, TemplateTable::fstore , 1 ); 209 t->define_template(Bytecodes::cast(Bytecodes::_typed_F_astore_2), ubcp|____|____|____, ftos, vtos, TemplateTable::fstore , 2 ); 210 t->define_template(Bytecodes::cast(Bytecodes::_typed_F_astore_3), ubcp|____|____|____, ftos, vtos, TemplateTable::fstore , 3 ); 211 t->define_template(Bytecodes::cast(Bytecodes::_typed_F_aaload) , ____|____|____|____, itos, ftos, TemplateTable::faload , _ ); 212 t->define_template(Bytecodes::cast(Bytecodes::_typed_F_aastore) , ____|____|clvm|____, ftos, vtos, TemplateTable::fastore , _ ); 213 t->define_template(Bytecodes::cast(Bytecodes::_typed_F_areturn) , ____|disp|clvm|____, ftos, ftos, TemplateTable::_return , ftos ); 214 // wide variants 215 t->define_template(Bytecodes::cast(Bytecodes::_typed_F_aload) , ubcp|____|____|iswd, vtos, ftos, TemplateTable::wide_fload , _ ); 216 t->define_template(Bytecodes::cast(Bytecodes::_typed_F_astore) , ubcp|____|____|iswd, vtos, vtos, TemplateTable::wide_fstore , _ ); 217 #endif 218 // A new template is required for typed anewarray 219 t->define_template(Bytecodes::cast(Bytecodes::_typed_F_anewarray) , ubcp|____|clvm|____, itos, atos, TemplateTable::new_primitive_array , T_FLOAT ); 220 221 return t; 222 } 223 224 #undef USE_ALIASES