< prev index next >

src/share/vm/opto/valuetypenode.hpp

Print this page

        

@@ -28,39 +28,74 @@
 #include "opto/node.hpp"
 #include "opto/connode.hpp"
 
 class GraphKit;
 
+class ValueTypeBaseNode : public TypeNode {
+protected:
+  ValueTypeBaseNode(const Type* t, int nb_fields)
+    : TypeNode(t, nb_fields) {
+    init_class_id(Class_ValueTypeBase);
+  }
+
+  enum { Control,   // Control input
+         Oop,       // Oop of TypeValueTypePtr
+         Values     // Nodes corresponding to values of the value type's fields.
+                    // Nodes are connected in increasing order of the index of the field
+                    // they correspond to. Field indeces are defined in ciValueKlass::_field_index_map.
+  };
+
+  virtual const TypeValueTypePtr* value_type_ptr() const = 0;
+  // Get the klass defining the field layout of the value type
+
+  virtual ciValueKlass* value_klass() const = 0;
+public:
+  // Support for control flow merges
+  bool  has_phi_inputs(Node* region);
+  ValueTypeBaseNode* clone_with_phis(PhaseGVN* gvn, Node* region);
+  ValueTypeBaseNode* merge_with(PhaseGVN* gvn, const ValueTypeBaseNode* other, int pnum, bool transform);
+
+  // Get oop for heap allocated value type (may be TypePtr::NULL_PTR)
+  Node* get_oop() const    { return in(Oop); }
+  void  set_oop(Node* oop) { set_req(Oop, oop); }
+
+  // Value type fields
+  uint          field_count() const { return req() - Values; }
+  Node*         field_value(uint index) const;
+  Node*         field_value_by_offset(int offset, bool recursive = false) const;
+  void      set_field_value(uint index, Node* value);
+  int           field_offset(uint index) const;
+  ciType*       field_type(uint index) const;
+
+  int make_scalar_in_safepoint(SafePointNode* sfpt, Node* root, PhaseGVN* gvn);
+};
+
 //------------------------------ValueTypeNode-------------------------------------
 // Node representing a value type in C2 IR
-class ValueTypeNode : public TypeNode {
+class ValueTypeNode : public ValueTypeBaseNode {
+  friend class ValueTypeBaseNode;
 private:
   ValueTypeNode(const TypeValueType* t, Node* oop)
-    : TypeNode(t, Values + t->value_klass()->nof_declared_nonstatic_fields()) {
+    : ValueTypeBaseNode(t, Values + t->value_klass()->nof_declared_nonstatic_fields()) {
     init_class_id(Class_ValueType);
     init_req(Oop, oop);
   }
 
   ValueTypeNode(const TypeValueType* t, Node* oop, int field_count)
-    : TypeNode(t, Values + field_count) {
+    : ValueTypeBaseNode(t, Values + field_count) {
     init_class_id(Class_ValueType);
     init_req(Oop, oop);
   }
 
-  // Get the klass defining the field layout of the value type
-  ciValueKlass* value_klass() const { return type()->is_valuetype()->value_klass(); }
   // Initialize the value type by loading its field values from memory
   void load(PhaseGVN& gvn, Node* mem, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset = 0);
   // Checks if the value type is loaded from memory and if so returns the oop
   Node* is_loaded(PhaseGVN* phase, const TypeValueType* t, Node* base = NULL, int holder_offset = 0);
 
-  enum { Control,   // Control input
-         Oop,       // Oop of TypeValueTypePtr
-         Values     // Nodes corresponding to values of the value type's fields.
-                    // Nodes are connected in increasing order of the index of the field
-                    // they correspond to. Field indeces are defined in ciValueKlass::_field_index_map.
-  };
+  const TypeValueTypePtr* value_type_ptr() const { return TypeValueTypePtr::make(bottom_type()->isa_valuetype()); }
+  // Get the klass defining the field layout of the value type
+  ciValueKlass* value_klass() const { return type()->is_valuetype()->value_klass(); }
 
 public:
   // Create a new ValueTypeNode with uninitialized values
   static ValueTypeNode* make(PhaseGVN& gvn, ciValueKlass* klass);
   // Create a new ValueTypeNode with default values

@@ -68,35 +103,20 @@
   // Create a new ValueTypeNode and load its values from an oop
   static Node* make(PhaseGVN& gvn, Node* mem, Node* oop);
   // Create a new ValueTypeNode and load its values from a flattened value type field or array
   static Node* make(PhaseGVN& gvn, ciValueKlass* vk, Node* mem, Node* obj, Node* ptr, ciInstanceKlass* holder = NULL, int holder_offset = 0);
 
-  // Support for control flow merges
-  ValueTypeNode* clone_with_phis(PhaseGVN* gvn, Node* region);
-  bool  has_phi_inputs(Node* region);
-  ValueTypeNode* merge_with(PhaseGVN* gvn, const ValueTypeNode* other, int pnum, bool transform);
 
   // Store the value type as a flattened (headerless) representation
   void store_flattened(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder = NULL, int holder_offset = 0) const;
   // Store the field values to memory
   void store(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset = 0) const;
 
-  // Get oop for heap allocated value type (may be TypePtr::NULL_PTR)
-  Node* get_oop() const    { return in(Oop); }
-  void  set_oop(Node* oop) { set_req(Oop, oop); }
   // Allocates the value type (if not yet allocated) and returns the oop
   Node* allocate(GraphKit* kit);
   bool  is_allocated(PhaseGVN* phase) const;
 
-  // Value type fields
-  uint          field_count() const { return req() - Values; }
-  Node*         field_value(uint index) const;
-  Node*         field_value_by_offset(int offset, bool recursive = false) const;
-  void      set_field_value(uint index, Node* value);
-  int           field_offset(uint index) const;
-  ciType*       field_type(uint index) const;
-
   // Replace ValueTypeNodes in debug info at safepoints with SafePointScalarObjectNodes
   void make_scalar_in_safepoints(Compile* C);
   void pass_klass(Node* n, uint pos, const GraphKit& kit);
   uint pass_fields(Node* call, int base_input, const GraphKit& kit, ciValueKlass* base_vk = NULL, int base_offset = 0);
   void replace_call_results(Node* call, Compile* C);

@@ -110,6 +130,23 @@
 #ifndef PRODUCT
   virtual void dump_spec(outputStream* st) const;
 #endif
 };
 
+class ValueTypePtrNode : public ValueTypeBaseNode {
+private:
+  ciValueKlass* value_klass() const { return type()->is_valuetypeptr()->value_type()->value_klass(); }
+  const TypeValueTypePtr* value_type_ptr() const { return bottom_type()->isa_valuetypeptr(); }
+public:
+
+  ValueTypePtrNode(ValueTypeNode* vt, Node* oop)
+    : ValueTypeBaseNode(TypeValueTypePtr::make(vt->type()->is_valuetype())->cast_to_ptr_type(TypePtr::NotNull), vt->req()) {
+    for (uint i = Oop+1; i < vt->req(); i++) {
+      init_req(i, vt->in(i));
+    }
+    init_req(Oop, oop);
+  }
+
+  virtual int Opcode() const;
+};
+
 #endif // SHARE_VM_OPTO_VALUETYPENODE_HPP
< prev index next >