< prev index next >

src/hotspot/share/opto/graphKit.hpp

Print this page
@@ -31,10 +31,11 @@
  #include "opto/addnode.hpp"
  #include "opto/callnode.hpp"
  #include "opto/cfgnode.hpp"
  #include "opto/compile.hpp"
  #include "opto/divnode.hpp"
+ #include "opto/inlinetypenode.hpp"
  #include "opto/mulnode.hpp"
  #include "opto/phaseX.hpp"
  #include "opto/subnode.hpp"
  #include "opto/type.hpp"
  #include "runtime/deoptimization.hpp"

@@ -64,10 +65,13 @@
    SafePointNode*    _map;       // Parser map from JVM to Nodes
    SafePointNode*    _exceptions;// Parser map(s) for exception state(s)
    int               _bci;       // JVM Bytecode Pointer
    ciMethod*         _method;    // JVM Current Method
    BarrierSetC2*     _barrier_set;
+ #ifdef ASSERT
+   uint              _worklist_size;
+ #endif
  
   private:
    int               _sp;        // JVM Expression Stack Pointer; don't modify directly!
  
   private:

@@ -76,27 +80,34 @@
      return _map;
    }
  
   public:
    GraphKit();                   // empty constructor
-   GraphKit(JVMState* jvms);     // the JVM state on which to operate
+   GraphKit(JVMState* jvms, PhaseGVN* gvn = nullptr);     // the JVM state on which to operate
  
  #ifdef ASSERT
    ~GraphKit() {
      assert(failing_internal() || !has_exceptions(),
             "unless compilation failed, user must call transfer_exceptions_into_jvms");
+ #if 0
+     // During incremental inlining, the Node_Array of the C->for_igvn() worklist and the IGVN
+     // worklist are shared but the _in_worklist VectorSet is not. To avoid inconsistencies,
+     // we should not add nodes to the _for_igvn worklist when using IGVN for the GraphKit.
+     assert((_gvn.is_IterGVN() == nullptr) || (_gvn.C->for_igvn()->size() == _worklist_size),
+            "GraphKit should not modify _for_igvn worklist after parsing");
+ #endif
    }
  #endif
  
    virtual Parse*          is_Parse()          const { return nullptr; }
    virtual LibraryCallKit* is_LibraryCallKit() const { return nullptr; }
  
    ciEnv*        env()               const { return _env; }
    PhaseGVN&     gvn()               const { return _gvn; }
    void*         barrier_set_state() const { return C->barrier_set_state(); }
  
-   void record_for_igvn(Node* n) const { C->record_for_igvn(n); }  // delegate to Compile
+   void record_for_igvn(Node* n) const { _gvn.record_for_igvn(n); }
    void remove_for_igvn(Node* n) const { C->remove_for_igvn(n); }
  
    // Handy well-known nodes:
    Node*         null()          const { return zerocon(T_OBJECT); }
    Node*         top()           const { return C->top(); }

@@ -352,11 +363,11 @@
    // (See macros ConvI2X, etc., in type.hpp for ConvI2X, etc.)
    Node* ConvI2L(Node* offset);
    Node* ConvI2UL(Node* offset);
    Node* ConvL2I(Node* offset);
    // Find out the klass of an object.
-   Node* load_object_klass(Node* object);
+   Node* load_object_klass(Node* object, bool fold_for_arrays = true);
    // Find out the length of an array.
    Node* load_array_length(Node* array);
    // Cast array allocation's length as narrow as possible.
    // If replace_length_in_map is true, replace length with CastIINode in map.
    // This method is invoked after creating/moving ArrayAllocationNode or in load_array_length

@@ -370,16 +381,16 @@
    // Return the value cast to not-null.
    // Be clever about equivalent dominating null checks.
    Node* null_check_common(Node* value, BasicType type,
                            bool assert_null = false,
                            Node* *null_control = nullptr,
-                           bool speculative = false);
+                           bool speculative = false,
+                           bool is_init_check = false);
    Node* null_check(Node* value, BasicType type = T_OBJECT) {
      return null_check_common(value, type, false, nullptr, !_gvn.type(value)->speculative_maybe_null());
    }
    Node* null_check_receiver() {
-     assert(argument(0)->bottom_type()->isa_ptr(), "must be");
      return null_check(argument(0));
    }
    Node* zero_check_int(Node* value) {
      assert(value->bottom_type()->basic_type() == T_INT,
             "wrong type: %s", type2name(value->bottom_type()->basic_type()));

@@ -447,10 +458,17 @@
                                  ciKlass* type,
                                  bool not_null = false);
  
    // Cast obj to not-null on this path
    Node* cast_not_null(Node* obj, bool do_replace_in_map = true);
+   // If a larval object appears multiple times in the JVMS and we encounter a loop, they will
+   // become multiple Phis and we cannot change all of them to non-larval when we invoke the
+   // constructor on one. The other case is that we don't know whether a parameter of an OSR
+   // compilation is larval or not. If such a maybe-larval object is passed into an operation that
+   // does not permit larval objects, we can be sure that it is not larval and scalarize it if it
+   // is a value object.
+   Node* cast_to_non_larval(Node* obj);
    // Replace all occurrences of one node by another.
    void replace_in_map(Node* old, Node* neww);
  
    Node* maybe_narrow_object_type(Node* obj, ciKlass* type);
  

@@ -577,18 +595,21 @@
                          Node* adr,   // actual address to store val at
                          const TypePtr* adr_type,
                          Node* val,
                          const Type* val_type,
                          BasicType bt,
-                         DecoratorSet decorators);
+                         DecoratorSet decorators,
+                         bool safe_for_replace = true,
+                         const InlineTypeNode* vt = nullptr);
  
    Node* access_load_at(Node* obj,   // containing obj
                         Node* adr,   // actual address to load val at
                         const TypePtr* adr_type,
                         const Type* val_type,
                         BasicType bt,
-                        DecoratorSet decorators);
+                        DecoratorSet decorators,
+                        Node* ctl = nullptr);
  
    Node* access_load(Node* adr,   // actual address to load val at
                      const Type* val_type,
                      BasicType bt,
                      DecoratorSet decorators);

@@ -637,10 +658,11 @@
    Node* array_element_address(Node* ary, Node* idx, BasicType elembt,
                                // Optional constraint on the array size:
                                const TypeInt* sizetype = nullptr,
                                // Optional control dependency (for example, on range check)
                                Node* ctrl = nullptr);
+   Node* cast_to_flat_array(Node* array, ciInlineKlass* elem_vk, bool is_null_free, bool is_not_null_free, bool is_atomic);
  
    // Return a load of array element at idx.
    Node* load_array_element(Node* ary, Node* idx, const TypeAryPtr* arytype, bool set_ctrl);
  
    //---------------- Dtrace support --------------------

@@ -676,11 +698,11 @@
      return n;
    }
  
    // Fill in argument edges for the call from argument(0), argument(1), ...
    // (The next step is to call set_edges_for_java_call.)
-   void  set_arguments_for_java_call(CallJavaNode* call);
+   void  set_arguments_for_java_call(CallJavaNode* call, bool is_late_inline = false);
  
    // Fill in non-argument edges for the call.
    // Transform the call, and update the basics: control, i_o, memory.
    // (The next step is usually to call set_results_for_java_call.)
    void set_edges_for_java_call(CallJavaNode* call,

@@ -806,20 +828,28 @@
    // and the reflective instance-of call.
    Node* gen_instanceof(Node *subobj, Node* superkls, bool safe_for_replace = false);
  
    // Generate a check-cast idiom.  Used by both the check-cast bytecode
    // and the array-store bytecode
-   Node* gen_checkcast( Node *subobj, Node* superkls,
-                        Node* *failure_control = nullptr );
+   Node* gen_checkcast(Node *subobj, Node* superkls, Node* *failure_control = nullptr, bool null_free = false, bool maybe_larval = false);
+ 
+   // Inline types
+   Node* mark_word_test(Node* obj, uintptr_t mask_val, bool eq, bool check_lock = true);
+   Node* inline_type_test(Node* obj, bool is_inline = true);
+   Node* flat_array_test(Node* array_or_klass, bool flat = true);
+   Node* null_free_array_test(Node* array, bool null_free = true);
+   Node* null_free_atomic_array_test(Node* array, ciInlineKlass* vk);
+   Node* inline_array_null_guard(Node* ary, Node* val, int nargs, bool safe_for_replace = false);
  
    Node* gen_subtype_check(Node* obj, Node* superklass);
  
    // Exact type check used for predicted calls and casts.
    // Rewrites (*casted_receiver) to be casted to the stronger type.
    // (Caller is responsible for doing replace_in_map.)
    Node* type_check_receiver(Node* receiver, ciKlass* klass, float prob,
                              Node* *casted_receiver);
+   Node* type_check(Node* recv_klass, const TypeKlassPtr* tklass, float prob);
  
    // Inexact type check used for predicted calls.
    Node* subtype_check_receiver(Node* receiver, ciKlass* klass,
                                 Node** casted_receiver);
  

@@ -829,14 +859,16 @@
                                    bool deoptimize_on_exception=false);
    Node* get_layout_helper(Node* klass_node, jint& constant_value);
    Node* new_instance(Node* klass_node,
                       Node* slow_test = nullptr,
                       Node* *return_size_val = nullptr,
-                      bool deoptimize_on_exception = false);
+                      bool deoptimize_on_exception = false,
+                      InlineTypeNode* inline_type_node = nullptr);
    Node* new_array(Node* klass_node, Node* count_val, int nargs,
                    Node* *return_size_val = nullptr,
-                   bool deoptimize_on_exception = false);
+                   bool deoptimize_on_exception = false,
+                   Node* init_val = nullptr);
  
    // java.lang.String helpers
    Node* load_String_length(Node* str, bool set_ctrl);
    Node* load_String_value(Node* str, bool set_ctrl);
    Node* load_String_coder(Node* str, bool set_ctrl);

@@ -866,10 +898,11 @@
  
    void add_parse_predicates(int nargs = 0);
    void add_parse_predicate(Deoptimization::DeoptReason reason, int nargs);
  
    Node* make_constant_from_field(ciField* field, Node* obj);
+   Node* load_mirror_from_klass(Node* klass);
  
    // Vector API support (implemented in vectorIntrinsics.cpp)
    Node* box_vector(Node* in, const TypeInstPtr* vbox_type, BasicType elem_bt, int num_elem, bool deoptimize_on_exception = false);
    Node* unbox_vector(Node* in, const TypeInstPtr* vbox_type, BasicType elem_bt, int num_elem);
    Node* vector_shift_count(Node* cnt, int shift_op, BasicType bt, int num_elem);
< prev index next >