1 /*
  2  * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef SHARE_CI_CIOBJECT_HPP
 26 #define SHARE_CI_CIOBJECT_HPP
 27 
 28 #include "ci/ciBaseObject.hpp"
 29 #include "ci/ciClassList.hpp"
 30 #include "ci/ciConstant.hpp"
 31 #include "runtime/handles.hpp"
 32 #include "utilities/growableArray.hpp"
 33 
 34 // ciObject
 35 //
 36 // This class represents an oop in the HotSpot virtual machine.
 37 // Its subclasses are structured in a hierarchy which mirrors
 38 // an aggregate of the VM's oop and klass hierarchies (see
 39 // oopHierarchy.hpp).  Each instance of ciObject holds a handle
 40 // to a corresponding oop on the VM side and provides routines
 41 // for accessing the information in its oop.  By using the ciObject
 42 // hierarchy for accessing oops in the VM, the compiler ensures
 43 // that it is safe with respect to garbage collection; that is,
 44 // GC and compilation can proceed independently without
 45 // interference.
 46 //
 47 // Within the VM, the oop and klass hierarchies are separate.
 48 // The compiler interface does not preserve this separation --
 49 // the distinction between `Klass*' and `Klass' are not
 50 // reflected in the interface and instead the Klass hierarchy
 51 // is directly modeled as the subclasses of ciKlass.
 52 class ciObject : public ciBaseObject {
 53   CI_PACKAGE_ACCESS
 54   friend class ciEnv;
 55 
 56 private:
 57   // A JNI handle referring to an oop in the VM.  This
 58   // handle may, in a small set of cases, correctly be null.
 59   jobject  _handle;
 60   ciKlass* _klass;
 61 
 62   // Cache constant value lookups to ensure that consistent values are observed during compilation.
 63   class ConstantValue {
 64     private:
 65       ciConstant _value;
 66       int _off;
 67 
 68     public:
 69       ConstantValue() : _value(ciConstant()), _off(0) { }
 70       ConstantValue(int off, ciConstant value) : _value(value), _off(off) { }
 71 
 72       int off() const { return _off; }
 73       ciConstant value() const { return _value; }
 74   };
 75 
 76   GrowableArray<ConstantValue>* _constant_values = nullptr;
 77 
 78 protected:
 79   ciObject();
 80   ciObject(oop o);
 81   ciObject(Handle h);
 82   ciObject(ciKlass* klass);
 83 
 84   jobject      handle()  const { return _handle; }
 85   // Get the VM oop that this object holds.
 86   oop get_oop() const;
 87 
 88   // Virtual behavior of the print() method.
 89   virtual void print_impl(outputStream* st) {}
 90 
 91   virtual const char* type_string() { return "ciObject"; }
 92 
 93 public:
 94   // The klass of this ciObject.
 95   ciKlass* klass();
 96 
 97   // Are two ciObjects equal?
 98   bool equals(ciObject* obj);
 99 
100   // A hash value for the convenience of compilers.
101   uint hash();
102 
103   // Tells if this oop should be made a constant.
104   bool should_be_constant();
105 
106   // The address which the compiler should embed into the
107   // generated code to represent this oop.  This address
108   // is not the true address of the oop -- it will get patched
109   // during nmethod creation.
110   //
111   // Usage note: no address arithmetic allowed.  Oop must
112   // be registered with the oopRecorder.
113   jobject constant_encoding();
114 
115   // Access to the constant value cache
116   ciConstant check_constant_value_cache(int off, BasicType bt);
117   void add_to_constant_value_cache(int off, ciConstant val);
118 
119   virtual bool is_object() const            { return true; }
120 
121   // What kind of ciObject is this?
122   virtual bool is_null_object()       const { return false; }
123   virtual bool is_call_site()         const { return false; }
124   virtual bool is_instance()                { return false; }
125   virtual bool is_member_name()       const { return false; }
126   virtual bool is_method_handle()     const { return false; }
127   virtual bool is_method_type()       const { return false; }
128   virtual bool is_array()                   { return false; }
129   virtual bool is_obj_array()               { return false; }
130   virtual bool is_type_array()              { return false; }
131   virtual bool is_native_entry_point()const { return false; }
132 
133   // Is this a type or value which has no associated class?
134   // It is true of primitive types and null objects.
135   virtual bool is_classless() const         { return false; }
136   virtual void dump_replay_data(outputStream* st) { /* do nothing */ }
137 
138   // Note: some ciObjects refer to oops which have yet to be created.
139   // We refer to these as "unloaded".  Specifically, there are
140   // unloaded instances of java.lang.Class,
141   // java.lang.invoke.MethodHandle, and java.lang.invoke.MethodType.
142   // By convention the ciNullObject is considered loaded, and
143   // primitive types are considered loaded.
144   bool is_loaded() const {
145     return handle() != nullptr || is_classless();
146   }
147 
148   // Subclass casting with assertions.
149   ciNullObject* as_null_object() {
150     assert(is_null_object(), "bad cast");
151     return (ciNullObject*)this;
152   }
153   ciCallSite* as_call_site() {
154     assert(is_call_site(), "bad cast");
155     return (ciCallSite*)this;
156   }
157   ciInstance* as_instance() {
158     assert(is_instance(), "bad cast");
159     return (ciInstance*)this;
160   }
161   ciMemberName* as_member_name() {
162     assert(is_member_name(), "bad cast");
163     return (ciMemberName*)this;
164   }
165   ciMethodHandle* as_method_handle() {
166     assert(is_method_handle(), "bad cast");
167     return (ciMethodHandle*)this;
168   }
169   ciMethodType* as_method_type() {
170     assert(is_method_type(), "bad cast");
171     return (ciMethodType*)this;
172   }
173   ciArray* as_array() {
174     assert(is_array(), "bad cast");
175     return (ciArray*)this;
176   }
177   ciObjArray* as_obj_array() {
178     assert(is_obj_array(), "bad cast");
179     return (ciObjArray*)this;
180   }
181   ciTypeArray* as_type_array() {
182     assert(is_type_array(), "bad cast");
183     return (ciTypeArray*)this;
184   }
185 
186   // Print debugging output about this ciObject.
187   void print(outputStream* st);
188   void print() { print(tty); }  // GDB cannot handle default arguments
189 
190   // Print debugging output about the oop this ciObject represents.
191   void print_oop(outputStream* st = tty);
192 };
193 
194 #endif // SHARE_CI_CIOBJECT_HPP