1 /* 2 * Copyright (c) 1999, 2007, 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 // Items on the stack and in local variables are tracked using 27 // SharkValue objects. 28 // 29 // All SharkValues are one of two core types, SharkNormalValue 30 // and SharkAddressValue, but no code outside this file should 31 // ever refer to those directly. The split is because of the 32 // way JSRs are handled: the typeflow pass expands them into 33 // multiple copies, so the return addresses pushed by jsr and 34 // popped by ret only exist at compile time. Having separate 35 // classes for these allows us to check that our jsr handling 36 // is correct, via assertions. 37 // 38 // There is one more type, SharkPHIValue, which is a subclass 39 // of SharkNormalValue with a couple of extra methods. Use of 40 // SharkPHIValue outside of this file is acceptable, so long 41 // as it is obtained via SharkValue::as_phi(). 42 43 class SharkBuilder; 44 class SharkPHIValue; 45 46 class SharkValue : public ResourceObj { 47 protected: 48 SharkValue() {} 49 50 // Cloning 51 public: 52 virtual SharkValue* clone() const = 0; 53 54 // Casting 55 public: 56 virtual bool is_phi() const; 57 virtual SharkPHIValue* as_phi(); 58 59 // Comparison 60 public: 61 virtual bool equal_to(SharkValue* other) const = 0; 62 63 // Type access 64 public: 65 virtual BasicType basic_type() const = 0; 66 virtual ciType* type() const; 67 68 virtual bool is_jint() const; 69 virtual bool is_jlong() const; 70 virtual bool is_jfloat() const; 71 virtual bool is_jdouble() const; 72 virtual bool is_jobject() const; 73 virtual bool is_jarray() const; 74 virtual bool is_address() const; 75 76 virtual int size() const = 0; 77 78 bool is_one_word() const { 79 return size() == 1; 80 } 81 bool is_two_word() const { 82 return size() == 2; 83 } 84 85 // Typed conversion from SharkValues 86 public: 87 virtual llvm::Value* jint_value() const; 88 virtual llvm::Value* jlong_value() const; 89 virtual llvm::Value* jfloat_value() const; 90 virtual llvm::Value* jdouble_value() const; 91 virtual llvm::Value* jobject_value() const; 92 virtual llvm::Value* jarray_value() const; 93 virtual int address_value() const; 94 95 // Typed conversion to SharkValues 96 public: 97 static SharkValue* create_jint(llvm::Value* value, bool zero_checked) { 98 assert(value->getType() == SharkType::jint_type(), "should be"); 99 return create_generic(ciType::make(T_INT), value, zero_checked); 100 } 101 static SharkValue* create_jlong(llvm::Value* value, bool zero_checked) { 102 assert(value->getType() == SharkType::jlong_type(), "should be"); 103 return create_generic(ciType::make(T_LONG), value, zero_checked); 104 } 105 static SharkValue* create_jfloat(llvm::Value* value) { 106 assert(value->getType() == SharkType::jfloat_type(), "should be"); 107 return create_generic(ciType::make(T_FLOAT), value, false); 108 } 109 static SharkValue* create_jdouble(llvm::Value* value) { 110 assert(value->getType() == SharkType::jdouble_type(), "should be"); 111 return create_generic(ciType::make(T_DOUBLE), value, false); 112 } 113 static SharkValue* create_jobject(llvm::Value* value, bool zero_checked) { 114 assert(value->getType() == SharkType::oop_type(), "should be"); 115 return create_generic(ciType::make(T_OBJECT), value, zero_checked); 116 } 117 118 // Typed conversion from constants of various types 119 public: 120 static SharkValue* jint_constant(jint value) { 121 return create_jint(LLVMValue::jint_constant(value), value != 0); 122 } 123 static SharkValue* jlong_constant(jlong value) { 124 return create_jlong(LLVMValue::jlong_constant(value), value != 0); 125 } 126 static SharkValue* jfloat_constant(jfloat value) { 127 return create_jfloat(LLVMValue::jfloat_constant(value)); 128 } 129 static SharkValue* jdouble_constant(jdouble value) { 130 return create_jdouble(LLVMValue::jdouble_constant(value)); 131 } 132 static SharkValue* null() { 133 return create_jobject(LLVMValue::null(), false); 134 } 135 static inline SharkValue* address_constant(int bci); 136 137 // Type-losing conversions -- use with care! 138 public: 139 virtual llvm::Value* generic_value() const = 0; 140 virtual llvm::Value* intptr_value(SharkBuilder* builder) const; 141 142 static inline SharkValue* create_generic(ciType* type, 143 llvm::Value* value, 144 bool zero_checked); 145 static inline SharkValue* create_phi(ciType* type, 146 llvm::PHINode* phi, 147 const SharkPHIValue* parent = NULL); 148 149 // Phi-style stuff 150 public: 151 virtual void addIncoming(SharkValue* value, llvm::BasicBlock* block); 152 virtual SharkValue* merge(SharkBuilder* builder, 153 SharkValue* other, 154 llvm::BasicBlock* other_block, 155 llvm::BasicBlock* this_block, 156 const char* name) = 0; 157 158 // Repeated null and divide-by-zero check removal 159 public: 160 virtual bool zero_checked() const; 161 virtual void set_zero_checked(bool zero_checked); 162 }; 163 164 class SharkNormalValue : public SharkValue { 165 friend class SharkValue; 166 167 protected: 168 SharkNormalValue(ciType* type, llvm::Value* value, bool zero_checked) 169 : _type(type), _llvm_value(value), _zero_checked(zero_checked) {} 170 171 private: 172 ciType* _type; 173 llvm::Value* _llvm_value; 174 bool _zero_checked; 175 176 private: 177 llvm::Value* llvm_value() const { 178 return _llvm_value; 179 } 180 181 // Cloning 182 public: 183 SharkValue* clone() const; 184 185 // Comparison 186 public: 187 bool equal_to(SharkValue* other) const; 188 189 // Type access 190 public: 191 ciType* type() const; 192 BasicType basic_type() const; 193 int size() const; 194 195 public: 196 bool is_jint() const; 197 bool is_jlong() const; 198 bool is_jfloat() const; 199 bool is_jdouble() const; 200 bool is_jobject() const; 201 bool is_jarray() const; 202 203 // Typed conversions to LLVM values 204 public: 205 llvm::Value* jint_value() const; 206 llvm::Value* jlong_value() const; 207 llvm::Value* jfloat_value() const; 208 llvm::Value* jdouble_value() const; 209 llvm::Value* jobject_value() const; 210 llvm::Value* jarray_value() const; 211 212 // Type-losing conversions, use with care 213 public: 214 llvm::Value* generic_value() const; 215 llvm::Value* intptr_value(SharkBuilder* builder) const; 216 217 // Phi-style stuff 218 public: 219 SharkValue* merge(SharkBuilder* builder, 220 SharkValue* other, 221 llvm::BasicBlock* other_block, 222 llvm::BasicBlock* this_block, 223 const char* name); 224 225 // Repeated null and divide-by-zero check removal 226 public: 227 bool zero_checked() const; 228 void set_zero_checked(bool zero_checked); 229 }; 230 231 class SharkPHIValue : public SharkNormalValue { 232 friend class SharkValue; 233 234 protected: 235 SharkPHIValue(ciType* type, llvm::PHINode* phi, const SharkPHIValue *parent) 236 : SharkNormalValue(type, phi, parent && parent->zero_checked()), 237 _parent(parent), 238 _all_incomers_zero_checked(true) {} 239 240 private: 241 const SharkPHIValue* _parent; 242 bool _all_incomers_zero_checked; 243 244 private: 245 const SharkPHIValue* parent() const { 246 return _parent; 247 } 248 bool is_clone() const { 249 return parent() != NULL; 250 } 251 252 public: 253 bool all_incomers_zero_checked() const { 254 if (is_clone()) 255 return parent()->all_incomers_zero_checked(); 256 257 return _all_incomers_zero_checked; 258 } 259 260 // Cloning 261 public: 262 SharkValue* clone() const; 263 264 // Casting 265 public: 266 bool is_phi() const; 267 SharkPHIValue* as_phi(); 268 269 // Phi-style stuff 270 public: 271 void addIncoming(SharkValue *value, llvm::BasicBlock* block); 272 }; 273 274 class SharkAddressValue : public SharkValue { 275 friend class SharkValue; 276 277 protected: 278 SharkAddressValue(int bci) 279 : _bci(bci) {} 280 281 private: 282 int _bci; 283 284 // Cloning 285 public: 286 SharkValue* clone() const; 287 288 // Comparison 289 public: 290 bool equal_to(SharkValue* other) const; 291 292 // Type access 293 public: 294 BasicType basic_type() const; 295 int size() const; 296 bool is_address() const; 297 298 // Typed conversion from SharkValues 299 public: 300 int address_value() const; 301 302 // Type-losing conversion -- use with care! 303 public: 304 llvm::Value* generic_value() const; 305 306 // Phi-style stuff 307 public: 308 void addIncoming(SharkValue *value, llvm::BasicBlock* block); 309 SharkValue* merge(SharkBuilder* builder, 310 SharkValue* other, 311 llvm::BasicBlock* other_block, 312 llvm::BasicBlock* this_block, 313 const char* name); 314 }; 315 316 // SharkValue methods that can't be declared above 317 318 inline SharkValue* SharkValue::create_generic(ciType* type, 319 llvm::Value* value, 320 bool zero_checked) { 321 return new SharkNormalValue(type, value, zero_checked); 322 } 323 324 inline SharkValue* SharkValue::create_phi(ciType* type, 325 llvm::PHINode* phi, 326 const SharkPHIValue* parent) { 327 return new SharkPHIValue(type, phi, parent); 328 } 329 330 inline SharkValue* SharkValue::address_constant(int bci) { 331 return new SharkAddressValue(bci); 332 }