src/share/vm/shark/sharkValue.hpp

Mon, 04 Apr 2011 03:02:00 -0700

author
twisti
date
Mon, 04 Apr 2011 03:02:00 -0700
changeset 2729
e863062e521d
parent 2314
f95d63e2154a
child 6876
710a3c8b516e
permissions
-rw-r--r--

7032458: Zero and Shark fixes
Reviewed-by: twisti
Contributed-by: Gary Benson <gbenson@redhat.com>

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

mercurial