--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkValue.hpp Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// Items on the stack and in local variables are tracked using
+// SharkValue objects.
+//
+// All SharkValues are one of two core types, SharkNormalValue
+// and SharkAddressValue, but no code outside this file should
+// ever refer to those directly. The split is because of the
+// way JSRs are handled: the typeflow pass expands them into
+// multiple copies, so the return addresses pushed by jsr and
+// popped by ret only exist at compile time. Having separate
+// classes for these allows us to check that our jsr handling
+// is correct, via assertions.
+//
+// There is one more type, SharkPHIValue, which is a subclass
+// of SharkNormalValue with a couple of extra methods. Use of
+// SharkPHIValue outside of this file is acceptable, so long
+// as it is obtained via SharkValue::as_phi().
+
+class SharkBuilder;
+class SharkPHIValue;
+
+class SharkValue : public ResourceObj {
+ protected:
+ SharkValue() {}
+
+ // Cloning
+ public:
+ virtual SharkValue* clone() const = 0;
+
+ // Casting
+ public:
+ virtual bool is_phi() const;
+ virtual SharkPHIValue* as_phi();
+
+ // Comparison
+ public:
+ virtual bool equal_to(SharkValue* other) const = 0;
+
+ // Type access
+ public:
+ virtual BasicType basic_type() const = 0;
+ virtual ciType* type() const;
+
+ virtual bool is_jint() const;
+ virtual bool is_jlong() const;
+ virtual bool is_jfloat() const;
+ virtual bool is_jdouble() const;
+ virtual bool is_jobject() const;
+ virtual bool is_jarray() const;
+ virtual bool is_address() const;
+
+ virtual int size() const = 0;
+
+ bool is_one_word() const {
+ return size() == 1;
+ }
+ bool is_two_word() const {
+ return size() == 2;
+ }
+
+ // Typed conversion from SharkValues
+ public:
+ virtual llvm::Value* jint_value() const;
+ virtual llvm::Value* jlong_value() const;
+ virtual llvm::Value* jfloat_value() const;
+ virtual llvm::Value* jdouble_value() const;
+ virtual llvm::Value* jobject_value() const;
+ virtual llvm::Value* jarray_value() const;
+ virtual int address_value() const;
+
+ // Typed conversion to SharkValues
+ public:
+ static SharkValue* create_jint(llvm::Value* value, bool zero_checked) {
+ assert(value->getType() == SharkType::jint_type(), "should be");
+ return create_generic(ciType::make(T_INT), value, zero_checked);
+ }
+ static SharkValue* create_jlong(llvm::Value* value, bool zero_checked) {
+ assert(value->getType() == SharkType::jlong_type(), "should be");
+ return create_generic(ciType::make(T_LONG), value, zero_checked);
+ }
+ static SharkValue* create_jfloat(llvm::Value* value) {
+ assert(value->getType() == SharkType::jfloat_type(), "should be");
+ return create_generic(ciType::make(T_FLOAT), value, false);
+ }
+ static SharkValue* create_jdouble(llvm::Value* value) {
+ assert(value->getType() == SharkType::jdouble_type(), "should be");
+ return create_generic(ciType::make(T_DOUBLE), value, false);
+ }
+ static SharkValue* create_jobject(llvm::Value* value, bool zero_checked) {
+ assert(value->getType() == SharkType::oop_type(), "should be");
+ return create_generic(ciType::make(T_OBJECT), value, zero_checked);
+ }
+
+ // Typed conversion from constants of various types
+ public:
+ static SharkValue* jint_constant(jint value) {
+ return create_jint(LLVMValue::jint_constant(value), value != 0);
+ }
+ static SharkValue* jlong_constant(jlong value) {
+ return create_jlong(LLVMValue::jlong_constant(value), value != 0);
+ }
+ static SharkValue* jfloat_constant(jfloat value) {
+ return create_jfloat(LLVMValue::jfloat_constant(value));
+ }
+ static SharkValue* jdouble_constant(jdouble value) {
+ return create_jdouble(LLVMValue::jdouble_constant(value));
+ }
+ static SharkValue* null() {
+ return create_jobject(LLVMValue::null(), false);
+ }
+ static inline SharkValue* address_constant(int bci);
+
+ // Type-losing conversions -- use with care!
+ public:
+ virtual llvm::Value* generic_value() const = 0;
+ virtual llvm::Value* intptr_value(SharkBuilder* builder) const;
+
+ static inline SharkValue* create_generic(ciType* type,
+ llvm::Value* value,
+ bool zero_checked);
+ static inline SharkValue* create_phi(ciType* type,
+ llvm::PHINode* phi,
+ const SharkPHIValue* parent = NULL);
+
+ // Phi-style stuff
+ public:
+ virtual void addIncoming(SharkValue* value, llvm::BasicBlock* block);
+ virtual SharkValue* merge(SharkBuilder* builder,
+ SharkValue* other,
+ llvm::BasicBlock* other_block,
+ llvm::BasicBlock* this_block,
+ const char* name) = 0;
+
+ // Repeated null and divide-by-zero check removal
+ public:
+ virtual bool zero_checked() const;
+ virtual void set_zero_checked(bool zero_checked);
+};
+
+class SharkNormalValue : public SharkValue {
+ friend class SharkValue;
+
+ protected:
+ SharkNormalValue(ciType* type, llvm::Value* value, bool zero_checked)
+ : _type(type), _llvm_value(value), _zero_checked(zero_checked) {}
+
+ private:
+ ciType* _type;
+ llvm::Value* _llvm_value;
+ bool _zero_checked;
+
+ private:
+ llvm::Value* llvm_value() const {
+ return _llvm_value;
+ }
+
+ // Cloning
+ public:
+ SharkValue* clone() const;
+
+ // Comparison
+ public:
+ bool equal_to(SharkValue* other) const;
+
+ // Type access
+ public:
+ ciType* type() const;
+ BasicType basic_type() const;
+ int size() const;
+
+ public:
+ bool is_jint() const;
+ bool is_jlong() const;
+ bool is_jfloat() const;
+ bool is_jdouble() const;
+ bool is_jobject() const;
+ bool is_jarray() const;
+
+ // Typed conversions to LLVM values
+ public:
+ llvm::Value* jint_value() const;
+ llvm::Value* jlong_value() const;
+ llvm::Value* jfloat_value() const;
+ llvm::Value* jdouble_value() const;
+ llvm::Value* jobject_value() const;
+ llvm::Value* jarray_value() const;
+
+ // Type-losing conversions, use with care
+ public:
+ llvm::Value* generic_value() const;
+ llvm::Value* intptr_value(SharkBuilder* builder) const;
+
+ // Phi-style stuff
+ public:
+ SharkValue* merge(SharkBuilder* builder,
+ SharkValue* other,
+ llvm::BasicBlock* other_block,
+ llvm::BasicBlock* this_block,
+ const char* name);
+
+ // Repeated null and divide-by-zero check removal
+ public:
+ bool zero_checked() const;
+ void set_zero_checked(bool zero_checked);
+};
+
+class SharkPHIValue : public SharkNormalValue {
+ friend class SharkValue;
+
+ protected:
+ SharkPHIValue(ciType* type, llvm::PHINode* phi, const SharkPHIValue *parent)
+ : SharkNormalValue(type, phi, parent && parent->zero_checked()),
+ _parent(parent),
+ _all_incomers_zero_checked(true) {}
+
+ private:
+ const SharkPHIValue* _parent;
+ bool _all_incomers_zero_checked;
+
+ private:
+ const SharkPHIValue* parent() const {
+ return _parent;
+ }
+ bool is_clone() const {
+ return parent() != NULL;
+ }
+
+ public:
+ bool all_incomers_zero_checked() const {
+ if (is_clone())
+ return parent()->all_incomers_zero_checked();
+
+ return _all_incomers_zero_checked;
+ }
+
+ // Cloning
+ public:
+ SharkValue* clone() const;
+
+ // Casting
+ public:
+ bool is_phi() const;
+ SharkPHIValue* as_phi();
+
+ // Phi-style stuff
+ public:
+ void addIncoming(SharkValue *value, llvm::BasicBlock* block);
+};
+
+class SharkAddressValue : public SharkValue {
+ friend class SharkValue;
+
+ protected:
+ SharkAddressValue(int bci)
+ : _bci(bci) {}
+
+ private:
+ int _bci;
+
+ // Cloning
+ public:
+ SharkValue* clone() const;
+
+ // Comparison
+ public:
+ bool equal_to(SharkValue* other) const;
+
+ // Type access
+ public:
+ BasicType basic_type() const;
+ int size() const;
+ bool is_address() const;
+
+ // Typed conversion from SharkValues
+ public:
+ int address_value() const;
+
+ // Type-losing conversion -- use with care!
+ public:
+ llvm::Value* generic_value() const;
+
+ // Phi-style stuff
+ public:
+ void addIncoming(SharkValue *value, llvm::BasicBlock* block);
+ SharkValue* merge(SharkBuilder* builder,
+ SharkValue* other,
+ llvm::BasicBlock* other_block,
+ llvm::BasicBlock* this_block,
+ const char* name);
+};
+
+// SharkValue methods that can't be declared above
+
+inline SharkValue* SharkValue::create_generic(ciType* type,
+ llvm::Value* value,
+ bool zero_checked) {
+ return new SharkNormalValue(type, value, zero_checked);
+}
+
+inline SharkValue* SharkValue::create_phi(ciType* type,
+ llvm::PHINode* phi,
+ const SharkPHIValue* parent) {
+ return new SharkPHIValue(type, phi, parent);
+}
+
+inline SharkValue* SharkValue::address_constant(int bci) {
+ return new SharkAddressValue(bci);
+}