Wed, 31 Jan 2018 19:24:57 -0500
8189170: Add option to disable stack overflow checking in primordial thread for use with JNI_CreateJavaJVM
Reviewed-by: dcubed
twisti@2047 | 1 | /* |
stefank@2314 | 2 | * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. |
twisti@2047 | 3 | * Copyright 2008, 2009 Red Hat, Inc. |
twisti@2047 | 4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
twisti@2047 | 5 | * |
twisti@2047 | 6 | * This code is free software; you can redistribute it and/or modify it |
twisti@2047 | 7 | * under the terms of the GNU General Public License version 2 only, as |
twisti@2047 | 8 | * published by the Free Software Foundation. |
twisti@2047 | 9 | * |
twisti@2047 | 10 | * This code is distributed in the hope that it will be useful, but WITHOUT |
twisti@2047 | 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
twisti@2047 | 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
twisti@2047 | 13 | * version 2 for more details (a copy is included in the LICENSE file that |
twisti@2047 | 14 | * accompanied this code). |
twisti@2047 | 15 | * |
twisti@2047 | 16 | * You should have received a copy of the GNU General Public License version |
twisti@2047 | 17 | * 2 along with this work; if not, write to the Free Software Foundation, |
twisti@2047 | 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
twisti@2047 | 19 | * |
twisti@2047 | 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
twisti@2047 | 21 | * or visit www.oracle.com if you need additional information or have any |
twisti@2047 | 22 | * questions. |
twisti@2047 | 23 | * |
twisti@2047 | 24 | */ |
twisti@2047 | 25 | |
stefank@2314 | 26 | #ifndef SHARE_VM_SHARK_SHARKVALUE_HPP |
stefank@2314 | 27 | #define SHARE_VM_SHARK_SHARKVALUE_HPP |
stefank@2314 | 28 | |
stefank@2314 | 29 | #include "ci/ciType.hpp" |
stefank@2314 | 30 | #include "memory/allocation.hpp" |
stefank@2314 | 31 | #include "shark/llvmHeaders.hpp" |
stefank@2314 | 32 | #include "shark/llvmValue.hpp" |
stefank@2314 | 33 | #include "shark/sharkType.hpp" |
stefank@2314 | 34 | |
twisti@2047 | 35 | // Items on the stack and in local variables are tracked using |
twisti@2047 | 36 | // SharkValue objects. |
twisti@2047 | 37 | // |
twisti@2047 | 38 | // All SharkValues are one of two core types, SharkNormalValue |
twisti@2047 | 39 | // and SharkAddressValue, but no code outside this file should |
twisti@2047 | 40 | // ever refer to those directly. The split is because of the |
twisti@2047 | 41 | // way JSRs are handled: the typeflow pass expands them into |
twisti@2047 | 42 | // multiple copies, so the return addresses pushed by jsr and |
twisti@2047 | 43 | // popped by ret only exist at compile time. Having separate |
twisti@2047 | 44 | // classes for these allows us to check that our jsr handling |
twisti@2047 | 45 | // is correct, via assertions. |
twisti@2047 | 46 | // |
twisti@2047 | 47 | // There is one more type, SharkPHIValue, which is a subclass |
twisti@2047 | 48 | // of SharkNormalValue with a couple of extra methods. Use of |
twisti@2047 | 49 | // SharkPHIValue outside of this file is acceptable, so long |
twisti@2047 | 50 | // as it is obtained via SharkValue::as_phi(). |
twisti@2047 | 51 | |
twisti@2047 | 52 | class SharkBuilder; |
twisti@2047 | 53 | class SharkPHIValue; |
twisti@2047 | 54 | |
twisti@2047 | 55 | class SharkValue : public ResourceObj { |
twisti@2047 | 56 | protected: |
twisti@2047 | 57 | SharkValue() {} |
twisti@2047 | 58 | |
twisti@2047 | 59 | // Cloning |
twisti@2047 | 60 | public: |
twisti@2047 | 61 | virtual SharkValue* clone() const = 0; |
twisti@2047 | 62 | |
twisti@2047 | 63 | // Casting |
twisti@2047 | 64 | public: |
twisti@2047 | 65 | virtual bool is_phi() const; |
twisti@2047 | 66 | virtual SharkPHIValue* as_phi(); |
twisti@2047 | 67 | |
twisti@2047 | 68 | // Comparison |
twisti@2047 | 69 | public: |
twisti@2047 | 70 | virtual bool equal_to(SharkValue* other) const = 0; |
twisti@2047 | 71 | |
twisti@2047 | 72 | // Type access |
twisti@2047 | 73 | public: |
twisti@2047 | 74 | virtual BasicType basic_type() const = 0; |
twisti@2047 | 75 | virtual ciType* type() const; |
twisti@2047 | 76 | |
twisti@2047 | 77 | virtual bool is_jint() const; |
twisti@2047 | 78 | virtual bool is_jlong() const; |
twisti@2047 | 79 | virtual bool is_jfloat() const; |
twisti@2047 | 80 | virtual bool is_jdouble() const; |
twisti@2047 | 81 | virtual bool is_jobject() const; |
twisti@2047 | 82 | virtual bool is_jarray() const; |
twisti@2047 | 83 | virtual bool is_address() const; |
twisti@2047 | 84 | |
twisti@2047 | 85 | virtual int size() const = 0; |
twisti@2047 | 86 | |
twisti@2047 | 87 | bool is_one_word() const { |
twisti@2047 | 88 | return size() == 1; |
twisti@2047 | 89 | } |
twisti@2047 | 90 | bool is_two_word() const { |
twisti@2047 | 91 | return size() == 2; |
twisti@2047 | 92 | } |
twisti@2047 | 93 | |
twisti@2047 | 94 | // Typed conversion from SharkValues |
twisti@2047 | 95 | public: |
twisti@2047 | 96 | virtual llvm::Value* jint_value() const; |
twisti@2047 | 97 | virtual llvm::Value* jlong_value() const; |
twisti@2047 | 98 | virtual llvm::Value* jfloat_value() const; |
twisti@2047 | 99 | virtual llvm::Value* jdouble_value() const; |
twisti@2047 | 100 | virtual llvm::Value* jobject_value() const; |
twisti@2047 | 101 | virtual llvm::Value* jarray_value() const; |
twisti@2047 | 102 | virtual int address_value() const; |
twisti@2047 | 103 | |
twisti@2047 | 104 | // Typed conversion to SharkValues |
twisti@2047 | 105 | public: |
twisti@2047 | 106 | static SharkValue* create_jint(llvm::Value* value, bool zero_checked) { |
twisti@2047 | 107 | assert(value->getType() == SharkType::jint_type(), "should be"); |
twisti@2047 | 108 | return create_generic(ciType::make(T_INT), value, zero_checked); |
twisti@2047 | 109 | } |
twisti@2047 | 110 | static SharkValue* create_jlong(llvm::Value* value, bool zero_checked) { |
twisti@2047 | 111 | assert(value->getType() == SharkType::jlong_type(), "should be"); |
twisti@2047 | 112 | return create_generic(ciType::make(T_LONG), value, zero_checked); |
twisti@2047 | 113 | } |
twisti@2047 | 114 | static SharkValue* create_jfloat(llvm::Value* value) { |
twisti@2047 | 115 | assert(value->getType() == SharkType::jfloat_type(), "should be"); |
twisti@2047 | 116 | return create_generic(ciType::make(T_FLOAT), value, false); |
twisti@2047 | 117 | } |
twisti@2047 | 118 | static SharkValue* create_jdouble(llvm::Value* value) { |
twisti@2047 | 119 | assert(value->getType() == SharkType::jdouble_type(), "should be"); |
twisti@2047 | 120 | return create_generic(ciType::make(T_DOUBLE), value, false); |
twisti@2047 | 121 | } |
twisti@2047 | 122 | static SharkValue* create_jobject(llvm::Value* value, bool zero_checked) { |
twisti@2047 | 123 | assert(value->getType() == SharkType::oop_type(), "should be"); |
twisti@2047 | 124 | return create_generic(ciType::make(T_OBJECT), value, zero_checked); |
twisti@2047 | 125 | } |
twisti@2047 | 126 | |
twisti@2047 | 127 | // Typed conversion from constants of various types |
twisti@2047 | 128 | public: |
twisti@2047 | 129 | static SharkValue* jint_constant(jint value) { |
twisti@2047 | 130 | return create_jint(LLVMValue::jint_constant(value), value != 0); |
twisti@2047 | 131 | } |
twisti@2047 | 132 | static SharkValue* jlong_constant(jlong value) { |
twisti@2047 | 133 | return create_jlong(LLVMValue::jlong_constant(value), value != 0); |
twisti@2047 | 134 | } |
twisti@2047 | 135 | static SharkValue* jfloat_constant(jfloat value) { |
twisti@2047 | 136 | return create_jfloat(LLVMValue::jfloat_constant(value)); |
twisti@2047 | 137 | } |
twisti@2047 | 138 | static SharkValue* jdouble_constant(jdouble value) { |
twisti@2047 | 139 | return create_jdouble(LLVMValue::jdouble_constant(value)); |
twisti@2047 | 140 | } |
twisti@2047 | 141 | static SharkValue* null() { |
twisti@2047 | 142 | return create_jobject(LLVMValue::null(), false); |
twisti@2047 | 143 | } |
twisti@2047 | 144 | static inline SharkValue* address_constant(int bci); |
twisti@2047 | 145 | |
twisti@2047 | 146 | // Type-losing conversions -- use with care! |
twisti@2047 | 147 | public: |
twisti@2047 | 148 | virtual llvm::Value* generic_value() const = 0; |
twisti@2047 | 149 | virtual llvm::Value* intptr_value(SharkBuilder* builder) const; |
twisti@2047 | 150 | |
twisti@2047 | 151 | static inline SharkValue* create_generic(ciType* type, |
twisti@2047 | 152 | llvm::Value* value, |
twisti@2047 | 153 | bool zero_checked); |
twisti@2047 | 154 | static inline SharkValue* create_phi(ciType* type, |
twisti@2047 | 155 | llvm::PHINode* phi, |
twisti@2047 | 156 | const SharkPHIValue* parent = NULL); |
twisti@2047 | 157 | |
twisti@2047 | 158 | // Phi-style stuff |
twisti@2047 | 159 | public: |
twisti@2047 | 160 | virtual void addIncoming(SharkValue* value, llvm::BasicBlock* block); |
twisti@2047 | 161 | virtual SharkValue* merge(SharkBuilder* builder, |
twisti@2047 | 162 | SharkValue* other, |
twisti@2047 | 163 | llvm::BasicBlock* other_block, |
twisti@2047 | 164 | llvm::BasicBlock* this_block, |
twisti@2047 | 165 | const char* name) = 0; |
twisti@2047 | 166 | |
twisti@2047 | 167 | // Repeated null and divide-by-zero check removal |
twisti@2047 | 168 | public: |
twisti@2047 | 169 | virtual bool zero_checked() const; |
twisti@2047 | 170 | virtual void set_zero_checked(bool zero_checked); |
twisti@2047 | 171 | }; |
twisti@2047 | 172 | |
twisti@2047 | 173 | class SharkNormalValue : public SharkValue { |
twisti@2047 | 174 | friend class SharkValue; |
twisti@2047 | 175 | |
twisti@2047 | 176 | protected: |
twisti@2047 | 177 | SharkNormalValue(ciType* type, llvm::Value* value, bool zero_checked) |
twisti@2047 | 178 | : _type(type), _llvm_value(value), _zero_checked(zero_checked) {} |
twisti@2047 | 179 | |
twisti@2047 | 180 | private: |
twisti@2047 | 181 | ciType* _type; |
twisti@2047 | 182 | llvm::Value* _llvm_value; |
twisti@2047 | 183 | bool _zero_checked; |
twisti@2047 | 184 | |
twisti@2047 | 185 | private: |
twisti@2047 | 186 | llvm::Value* llvm_value() const { |
twisti@2047 | 187 | return _llvm_value; |
twisti@2047 | 188 | } |
twisti@2047 | 189 | |
twisti@2047 | 190 | // Cloning |
twisti@2047 | 191 | public: |
twisti@2047 | 192 | SharkValue* clone() const; |
twisti@2047 | 193 | |
twisti@2047 | 194 | // Comparison |
twisti@2047 | 195 | public: |
twisti@2047 | 196 | bool equal_to(SharkValue* other) const; |
twisti@2047 | 197 | |
twisti@2047 | 198 | // Type access |
twisti@2047 | 199 | public: |
twisti@2047 | 200 | ciType* type() const; |
twisti@2047 | 201 | BasicType basic_type() const; |
twisti@2047 | 202 | int size() const; |
twisti@2047 | 203 | |
twisti@2047 | 204 | public: |
twisti@2047 | 205 | bool is_jint() const; |
twisti@2047 | 206 | bool is_jlong() const; |
twisti@2047 | 207 | bool is_jfloat() const; |
twisti@2047 | 208 | bool is_jdouble() const; |
twisti@2047 | 209 | bool is_jobject() const; |
twisti@2047 | 210 | bool is_jarray() const; |
twisti@2047 | 211 | |
twisti@2047 | 212 | // Typed conversions to LLVM values |
twisti@2047 | 213 | public: |
twisti@2047 | 214 | llvm::Value* jint_value() const; |
twisti@2047 | 215 | llvm::Value* jlong_value() const; |
twisti@2047 | 216 | llvm::Value* jfloat_value() const; |
twisti@2047 | 217 | llvm::Value* jdouble_value() const; |
twisti@2047 | 218 | llvm::Value* jobject_value() const; |
twisti@2047 | 219 | llvm::Value* jarray_value() const; |
twisti@2047 | 220 | |
twisti@2047 | 221 | // Type-losing conversions, use with care |
twisti@2047 | 222 | public: |
twisti@2047 | 223 | llvm::Value* generic_value() const; |
twisti@2047 | 224 | llvm::Value* intptr_value(SharkBuilder* builder) const; |
twisti@2047 | 225 | |
twisti@2047 | 226 | // Phi-style stuff |
twisti@2047 | 227 | public: |
twisti@2047 | 228 | SharkValue* merge(SharkBuilder* builder, |
twisti@2047 | 229 | SharkValue* other, |
twisti@2047 | 230 | llvm::BasicBlock* other_block, |
twisti@2047 | 231 | llvm::BasicBlock* this_block, |
twisti@2047 | 232 | const char* name); |
twisti@2047 | 233 | |
twisti@2047 | 234 | // Repeated null and divide-by-zero check removal |
twisti@2047 | 235 | public: |
twisti@2047 | 236 | bool zero_checked() const; |
twisti@2047 | 237 | void set_zero_checked(bool zero_checked); |
twisti@2047 | 238 | }; |
twisti@2047 | 239 | |
twisti@2047 | 240 | class SharkPHIValue : public SharkNormalValue { |
twisti@2047 | 241 | friend class SharkValue; |
twisti@2047 | 242 | |
twisti@2047 | 243 | protected: |
twisti@2047 | 244 | SharkPHIValue(ciType* type, llvm::PHINode* phi, const SharkPHIValue *parent) |
twisti@2047 | 245 | : SharkNormalValue(type, phi, parent && parent->zero_checked()), |
twisti@2047 | 246 | _parent(parent), |
twisti@2047 | 247 | _all_incomers_zero_checked(true) {} |
twisti@2047 | 248 | |
twisti@2047 | 249 | private: |
twisti@2047 | 250 | const SharkPHIValue* _parent; |
twisti@2047 | 251 | bool _all_incomers_zero_checked; |
twisti@2047 | 252 | |
twisti@2047 | 253 | private: |
twisti@2047 | 254 | const SharkPHIValue* parent() const { |
twisti@2047 | 255 | return _parent; |
twisti@2047 | 256 | } |
twisti@2047 | 257 | bool is_clone() const { |
twisti@2047 | 258 | return parent() != NULL; |
twisti@2047 | 259 | } |
twisti@2047 | 260 | |
twisti@2047 | 261 | public: |
twisti@2047 | 262 | bool all_incomers_zero_checked() const { |
twisti@2047 | 263 | if (is_clone()) |
twisti@2047 | 264 | return parent()->all_incomers_zero_checked(); |
twisti@2047 | 265 | |
twisti@2047 | 266 | return _all_incomers_zero_checked; |
twisti@2047 | 267 | } |
twisti@2047 | 268 | |
twisti@2047 | 269 | // Cloning |
twisti@2047 | 270 | public: |
twisti@2047 | 271 | SharkValue* clone() const; |
twisti@2047 | 272 | |
twisti@2047 | 273 | // Casting |
twisti@2047 | 274 | public: |
twisti@2047 | 275 | bool is_phi() const; |
twisti@2047 | 276 | SharkPHIValue* as_phi(); |
twisti@2047 | 277 | |
twisti@2047 | 278 | // Phi-style stuff |
twisti@2047 | 279 | public: |
twisti@2047 | 280 | void addIncoming(SharkValue *value, llvm::BasicBlock* block); |
twisti@2047 | 281 | }; |
twisti@2047 | 282 | |
twisti@2047 | 283 | class SharkAddressValue : public SharkValue { |
twisti@2047 | 284 | friend class SharkValue; |
twisti@2047 | 285 | |
twisti@2047 | 286 | protected: |
twisti@2047 | 287 | SharkAddressValue(int bci) |
twisti@2047 | 288 | : _bci(bci) {} |
twisti@2047 | 289 | |
twisti@2047 | 290 | private: |
twisti@2047 | 291 | int _bci; |
twisti@2047 | 292 | |
twisti@2047 | 293 | // Cloning |
twisti@2047 | 294 | public: |
twisti@2047 | 295 | SharkValue* clone() const; |
twisti@2047 | 296 | |
twisti@2047 | 297 | // Comparison |
twisti@2047 | 298 | public: |
twisti@2047 | 299 | bool equal_to(SharkValue* other) const; |
twisti@2047 | 300 | |
twisti@2047 | 301 | // Type access |
twisti@2047 | 302 | public: |
twisti@2047 | 303 | BasicType basic_type() const; |
twisti@2047 | 304 | int size() const; |
twisti@2047 | 305 | bool is_address() const; |
twisti@2047 | 306 | |
twisti@2047 | 307 | // Typed conversion from SharkValues |
twisti@2047 | 308 | public: |
twisti@2047 | 309 | int address_value() const; |
twisti@2047 | 310 | |
twisti@2047 | 311 | // Type-losing conversion -- use with care! |
twisti@2047 | 312 | public: |
twisti@2047 | 313 | llvm::Value* generic_value() const; |
twisti@2047 | 314 | |
twisti@2047 | 315 | // Phi-style stuff |
twisti@2047 | 316 | public: |
twisti@2047 | 317 | void addIncoming(SharkValue *value, llvm::BasicBlock* block); |
twisti@2047 | 318 | SharkValue* merge(SharkBuilder* builder, |
twisti@2047 | 319 | SharkValue* other, |
twisti@2047 | 320 | llvm::BasicBlock* other_block, |
twisti@2047 | 321 | llvm::BasicBlock* this_block, |
twisti@2047 | 322 | const char* name); |
twisti@2047 | 323 | }; |
twisti@2047 | 324 | |
twisti@2047 | 325 | // SharkValue methods that can't be declared above |
twisti@2047 | 326 | |
twisti@2047 | 327 | inline SharkValue* SharkValue::create_generic(ciType* type, |
twisti@2047 | 328 | llvm::Value* value, |
twisti@2047 | 329 | bool zero_checked) { |
twisti@2047 | 330 | return new SharkNormalValue(type, value, zero_checked); |
twisti@2047 | 331 | } |
twisti@2047 | 332 | |
twisti@2047 | 333 | inline SharkValue* SharkValue::create_phi(ciType* type, |
twisti@2047 | 334 | llvm::PHINode* phi, |
twisti@2047 | 335 | const SharkPHIValue* parent) { |
twisti@2047 | 336 | return new SharkPHIValue(type, phi, parent); |
twisti@2047 | 337 | } |
twisti@2047 | 338 | |
twisti@2047 | 339 | inline SharkValue* SharkValue::address_constant(int bci) { |
twisti@2047 | 340 | return new SharkAddressValue(bci); |
twisti@2047 | 341 | } |
stefank@2314 | 342 | |
stefank@2314 | 343 | #endif // SHARE_VM_SHARK_SHARKVALUE_HPP |