< prev index next >

src/hotspot/share/opto/graphKit.hpp

Print this page
@@ -1,7 +1,7 @@
  /*
-  * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved.
+  * Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.

@@ -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,11 +80,14 @@
      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
+ 
+   // Create a GraphKit from a debug state, useful for various kinds of macro expansion
+   GraphKit(const SafePointNode* sft, PhaseIterGVN& igvn);
  
  #ifdef ASSERT
    ~GraphKit() {
      assert(failing_internal() || !has_exceptions(),
             "unless compilation failed, user must call transfer_exceptions_into_jvms");

@@ -92,11 +99,11 @@
  
    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(); }

@@ -370,16 +377,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 null_marker_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()));

@@ -577,18 +584,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 +647,12 @@
    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);
+   Node* cast_to_flat_array_exact(Node* array, ciInlineKlass* elem_vk, bool is_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 +688,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,

@@ -809,20 +821,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);
  

@@ -832,14 +852,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);

@@ -869,10 +891,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 >