1 /*
  2  * Copyright (c) 1999, 2026, 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 protected:
 63   // Cache constant value lookups to ensure that consistent values are observed during compilation.
 64   class ConstantValue {
 65     private:
 66       ciConstant _value;
 67       int _off;
 68 
 69     public:
 70       ConstantValue() : _value(ciConstant()), _off(0) { }
 71       ConstantValue(int off, ciConstant value) : _value(value), _off(off) { }
 72 
 73       int off() const { return _off; }
 74       ciConstant value() const { return _value; }
 75   };
 76 
 77 private:
 78   GrowableArray<ConstantValue>* _constant_values = nullptr;
 79 
 80 protected:
 81   ciObject();
 82   ciObject(oop o);
 83   ciObject(Handle h);
 84   ciObject(ciKlass* klass);
 85 
 86   jobject      handle()  const { return _handle; }
 87   // Get the VM oop that this object holds.
 88   oop get_oop() const;
 89 
 90   // Virtual behavior of the print() method.
 91   virtual void print_impl(outputStream* st) {}
 92 
 93   virtual const char* type_string() { return "ciObject"; }
 94 
 95 public:
 96   // The klass of this ciObject.
 97   ciKlass* klass();
 98 
 99   // Are two ciObjects equal?
100   bool equals(ciObject* obj);
101 
102   // A hash value for the convenience of compilers.
103   uint hash();
104 
105   // Tells if this oop should be made a constant.
106   bool should_be_constant();
107 
108   // The address which the compiler should embed into the
109   // generated code to represent this oop.  This address
110   // is not the true address of the oop -- it will get patched
111   // during nmethod creation.
112   //
113   // Usage note: no address arithmetic allowed.  Oop must
114   // be registered with the oopRecorder.
115   jobject constant_encoding();
116 
117   // Access to the constant value cache
118   ciConstant check_constant_value_cache(int off, BasicType bt);
119   void add_to_constant_value_cache(int off, ciConstant val);
120 
121   virtual bool is_object() const            { return true; }
122 
123   // What kind of ciObject is this?
124   virtual bool is_null_object()       const { return false; }
125   virtual bool is_call_site()         const { return false; }
126   virtual bool is_instance()                { return false; }
127   virtual bool is_member_name()       const { return false; }
128   virtual bool is_method_handle()     const { return false; }
129   virtual bool is_method_type()       const { return false; }
130   virtual bool is_array()                   { return false; }
131   virtual bool is_obj_array()               { return false; }
132   virtual bool is_type_array()              { return false; }
133   virtual bool is_flat_array()        const { return false; }
134   virtual bool is_native_entry_point()const { return false; }
135 
136   // Is this a type or value which has no associated class?
137   // It is true of primitive types and null objects.
138   virtual bool is_classless() const         { return false; }
139   virtual void dump_replay_data(outputStream* st) { /* do nothing */ }
140 
141   // Note: some ciObjects refer to oops which have yet to be created.
142   // We refer to these as "unloaded".  Specifically, there are
143   // unloaded instances of java.lang.Class,
144   // java.lang.invoke.MethodHandle, and java.lang.invoke.MethodType.
145   // By convention the ciNullObject is considered loaded, and
146   // primitive types are considered loaded.
147   bool is_loaded() const {
148     return handle() != nullptr || is_classless();
149   }
150 
151   // Subclass casting with assertions.
152   ciNullObject* as_null_object() {
153     assert(is_null_object(), "bad cast");
154     return (ciNullObject*)this;
155   }
156   ciCallSite* as_call_site() {
157     assert(is_call_site(), "bad cast");
158     return (ciCallSite*)this;
159   }
160   ciInstance* as_instance() {
161     assert(is_instance(), "bad cast");
162     return (ciInstance*)this;
163   }
164   ciMemberName* as_member_name() {
165     assert(is_member_name(), "bad cast");
166     return (ciMemberName*)this;
167   }
168   ciMethodHandle* as_method_handle() {
169     assert(is_method_handle(), "bad cast");
170     return (ciMethodHandle*)this;
171   }
172   ciMethodType* as_method_type() {
173     assert(is_method_type(), "bad cast");
174     return (ciMethodType*)this;
175   }
176   ciArray* as_array() {
177     assert(is_array(), "bad cast");
178     return (ciArray*)this;
179   }
180   ciObjArray* as_obj_array() {
181     assert(is_obj_array(), "bad cast");
182     return (ciObjArray*)this;
183   }
184   ciTypeArray* as_type_array() {
185     assert(is_type_array(), "bad cast");
186     return (ciTypeArray*)this;
187   }
188   ciFlatArray* as_flat_array() {
189     assert(is_flat_array(), "bad cast");
190     return (ciFlatArray*)this;
191   }
192 
193   // Print debugging output about this ciObject.
194   void print(outputStream* st);
195   void print() { print(tty); }  // GDB cannot handle default arguments
196 
197   // Print debugging output about the oop this ciObject represents.
198   void print_oop(outputStream* st = tty);
199 };
200 
201 #endif // SHARE_CI_CIOBJECT_HPP