1 /* 2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 3 * Copyright 2008, 2009 Red Hat, Inc. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 #ifndef SHARE_VM_SHARK_SHARKBLOCK_HPP 27 #define SHARE_VM_SHARK_SHARKBLOCK_HPP 28 29 #include "ci/ciMethod.hpp" 30 #include "ci/ciStreams.hpp" 31 #include "memory/allocation.hpp" 32 #include "shark/llvmHeaders.hpp" 33 #include "shark/sharkBuilder.hpp" 34 #include "shark/sharkConstant.hpp" 35 #include "shark/sharkInvariants.hpp" 36 #include "shark/sharkState.hpp" 37 #include "shark/sharkValue.hpp" 38 #include "utilities/debug.hpp" 39 40 class SharkState; 41 42 class SharkBlock : public SharkTargetInvariants { 43 protected: 44 SharkBlock(const SharkTargetInvariants* parent) 45 : SharkTargetInvariants(parent), 46 _iter(target()), 47 _current_state(NULL) {} 48 49 SharkBlock(const SharkCompileInvariants* parent, ciMethod* target) 50 : SharkTargetInvariants(parent, target), 51 _iter(target), 52 _current_state(NULL) {} 53 54 private: 55 ciBytecodeStream _iter; 56 SharkState* _current_state; 57 58 public: 59 ciBytecodeStream* iter() { 60 return &_iter; 61 } 62 Bytecodes::Code bc() { 63 return iter()->cur_bc(); 64 } 65 int bci() { 66 return iter()->cur_bci(); 67 } 68 69 // Entry state 70 protected: 71 virtual SharkState* entry_state(); 72 73 // Current state 74 private: 75 SharkState* initial_current_state(); 76 77 public: 78 SharkState* current_state() { 79 if (_current_state == NULL) 80 set_current_state(initial_current_state()); 81 return _current_state; 82 } 83 84 protected: 85 void set_current_state(SharkState* current_state) { 86 _current_state = current_state; 87 } 88 89 // Local variables 90 protected: 91 SharkValue* local(int index) { 92 SharkValue *value = current_state()->local(index); 93 assert(value != NULL, "shouldn't be"); 94 assert(value->is_one_word() || 95 (index + 1 < max_locals() && 96 current_state()->local(index + 1) == NULL), "should be"); 97 return value; 98 } 99 void set_local(int index, SharkValue* value) { 100 assert(value != NULL, "shouldn't be"); 101 current_state()->set_local(index, value); 102 if (value->is_two_word()) 103 current_state()->set_local(index + 1, NULL); 104 } 105 106 // Expression stack (raw) 107 protected: 108 void xpush(SharkValue* value) { 109 current_state()->push(value); 110 } 111 SharkValue* xpop() { 112 return current_state()->pop(); 113 } 114 SharkValue* xstack(int slot) { 115 SharkValue *value = current_state()->stack(slot); 116 assert(value != NULL, "shouldn't be"); 117 assert(value->is_one_word() || 118 (slot > 0 && 119 current_state()->stack(slot - 1) == NULL), "should be"); 120 return value; 121 } 122 int xstack_depth() { 123 return current_state()->stack_depth(); 124 } 125 126 // Expression stack (cooked) 127 protected: 128 void push(SharkValue* value) { 129 assert(value != NULL, "shouldn't be"); 130 xpush(value); 131 if (value->is_two_word()) 132 xpush(NULL); 133 } 134 SharkValue* pop() { 135 int size = current_state()->stack(0) == NULL ? 2 : 1; 136 if (size == 2) 137 xpop(); 138 SharkValue *value = xpop(); 139 assert(value && value->size() == size, "should be"); 140 return value; 141 } 142 SharkValue* pop_result(BasicType type) { 143 SharkValue *result = pop(); 144 145 #ifdef ASSERT 146 switch (result->basic_type()) { 147 case T_BOOLEAN: 148 case T_BYTE: 149 case T_CHAR: 150 case T_SHORT: 151 assert(type == T_INT, "type mismatch"); 152 break; 153 154 case T_ARRAY: 155 assert(type == T_OBJECT, "type mismatch"); 156 break; 157 158 default: 159 assert(result->basic_type() == type, "type mismatch"); 160 } 161 #endif // ASSERT 162 163 return result; 164 } 165 166 // Code generation 167 public: 168 virtual void emit_IR(); 169 170 protected: 171 void parse_bytecode(int start, int limit); 172 173 // Helpers 174 protected: 175 virtual void do_zero_check(SharkValue* value); 176 177 // Zero checking 178 protected: 179 void check_null(SharkValue* object) { 180 zero_check(object); 181 } 182 void check_divide_by_zero(SharkValue* value) { 183 zero_check(value); 184 } 185 private: 186 void zero_check(SharkValue* value) { 187 if (!value->zero_checked()) 188 do_zero_check(value); 189 } 190 191 // Safepoints 192 protected: 193 virtual void maybe_add_backedge_safepoint(); 194 195 // Traps 196 protected: 197 virtual bool has_trap(); 198 virtual int trap_request(); 199 virtual int trap_bci(); 200 virtual void do_trap(int trap_request); 201 202 // arraylength 203 protected: 204 virtual void do_arraylength(); 205 206 // *aload and *astore 207 protected: 208 virtual void do_aload(BasicType basic_type); 209 virtual void do_astore(BasicType basic_type); 210 211 // *div and *rem 212 private: 213 void do_idiv() { 214 do_div_or_rem(false, false); 215 } 216 void do_irem() { 217 do_div_or_rem(false, true); 218 } 219 void do_ldiv() { 220 do_div_or_rem(true, false); 221 } 222 void do_lrem() { 223 do_div_or_rem(true, true); 224 } 225 void do_div_or_rem(bool is_long, bool is_rem); 226 227 // get* and put* 228 private: 229 void do_getstatic() { 230 do_field_access(true, false); 231 } 232 void do_getfield() { 233 do_field_access(true, true); 234 } 235 void do_putstatic() { 236 do_field_access(false, false); 237 } 238 void do_putfield() { 239 do_field_access(false, true); 240 } 241 void do_field_access(bool is_get, bool is_field); 242 243 // lcmp and [fd]cmp[lg] 244 private: 245 void do_lcmp(); 246 void do_fcmp(bool is_double, bool unordered_is_greater); 247 248 // *return and athrow 249 protected: 250 virtual void do_return(BasicType type); 251 virtual void do_athrow(); 252 253 // goto* 254 protected: 255 virtual void do_goto(); 256 257 // jsr* and ret 258 protected: 259 virtual void do_jsr(); 260 virtual void do_ret(); 261 262 // if* 263 protected: 264 virtual void do_if(llvm::ICmpInst::Predicate p, SharkValue* b, SharkValue* a); 265 266 // *switch 267 protected: 268 int switch_default_dest(); 269 int switch_table_length(); 270 int switch_key(int i); 271 int switch_dest(int i); 272 273 virtual void do_switch(); 274 275 // invoke* 276 protected: 277 virtual void do_call(); 278 279 // checkcast and instanceof 280 protected: 281 virtual void do_instance_check(); 282 virtual bool maybe_do_instanceof_if(); 283 284 // new and *newarray 285 protected: 286 virtual void do_new(); 287 virtual void do_newarray(); 288 virtual void do_anewarray(); 289 virtual void do_multianewarray(); 290 291 // monitorenter and monitorexit 292 protected: 293 virtual void do_monitorenter(); 294 virtual void do_monitorexit(); 295 }; 296 297 #endif // SHARE_VM_SHARK_SHARKBLOCK_HPP