< prev index next >

src/hotspot/share/opto/doCall.cpp

Print this page
@@ -32,10 +32,11 @@
  #include "interpreter/linkResolver.hpp"
  #include "opto/addnode.hpp"
  #include "opto/callGenerator.hpp"
  #include "opto/castnode.hpp"
  #include "opto/cfgnode.hpp"
+ #include "opto/inlinetypenode.hpp"
  #include "opto/mulnode.hpp"
  #include "opto/parse.hpp"
  #include "opto/rootnode.hpp"
  #include "opto/runtime.hpp"
  #include "opto/subnode.hpp"

@@ -582,11 +583,11 @@
      speculative_receiver_type = receiver_type != nullptr ? receiver_type->speculative_type() : nullptr;
    }
  
    // Additional receiver subtype checks for interface calls via invokespecial or invokeinterface.
    ciKlass* receiver_constraint = nullptr;
-   if (iter().cur_bc_raw() == Bytecodes::_invokespecial && !orig_callee->is_object_initializer()) {
+   if (iter().cur_bc_raw() == Bytecodes::_invokespecial && !orig_callee->is_object_constructor()) {
      ciInstanceKlass* calling_klass = method()->holder();
      ciInstanceKlass* sender_klass = calling_klass;
      if (sender_klass->is_interface()) {
        receiver_constraint = sender_klass;
      }

@@ -712,11 +713,11 @@
        // Be careful here with return types.
        if (ctype != rtype) {
          BasicType rt = rtype->basic_type();
          BasicType ct = ctype->basic_type();
          if (ct == T_VOID) {
-           // It's OK for a method  to return a value that is discarded.
+           // It's OK for a method to return a value that is discarded.
            // The discarding does not require any special action from the caller.
            // The Java code knows this, at VerifyType.isNullConversion.
            pop_node(rt);  // whatever it was, pop it
          } else if (rt == T_INT || is_subword_type(rt)) {
            // Nothing.  These cases are handled in lambda form bytecode.

@@ -724,10 +725,13 @@
          } else if (is_reference_type(rt)) {
            assert(is_reference_type(ct), "rt=%s, ct=%s", type2name(rt), type2name(ct));
            if (ctype->is_loaded()) {
              const TypeOopPtr* arg_type = TypeOopPtr::make_from_klass(rtype->as_klass());
              const Type*       sig_type = TypeOopPtr::make_from_klass(ctype->as_klass());
+             if (declared_signature->returns_null_free_inline_type()) {
+               sig_type = sig_type->join_speculative(TypePtr::NOTNULL);
+             }
              if (arg_type != nullptr && !arg_type->higher_equal(sig_type)) {
                Node* retnode = pop();
                Node* cast_obj = _gvn.transform(new CheckCastPPNode(control(), retnode, sig_type));
                push(cast_obj);
              }

@@ -770,10 +774,15 @@
      }
      BasicType ct = ctype->basic_type();
      if (is_reference_type(ct)) {
        record_profiled_return_for_speculation();
      }
+     if (rtype->is_inlinetype() && !peek()->is_InlineType()) {
+       Node* retnode = pop();
+       retnode = InlineTypeNode::make_from_oop(this, retnode, rtype->as_inline_klass(), !gvn().type(retnode)->maybe_null());
+       push_node(T_PRIMITIVE_OBJECT, retnode);
+     }
    }
  
    // Restart record of parsing work after possible inlining of call
  #ifndef PRODUCT
    parse_histogram()->set_initial_state(bc());
< prev index next >