< prev index next >

src/share/vm/opto/escape.cpp

Print this page

        

@@ -368,10 +368,21 @@
       if ((n->as_Call()->returns_pointer() &&
            n->as_Call()->proj_out(TypeFunc::Parms) != NULL) ||
           (n->is_CallStaticJava() &&
            n->as_CallStaticJava()->is_boxing_method())) {
         add_call_node(n->as_Call());
+      } else if (n->as_Call()->tf()->returns_value_type_as_fields()) {
+        bool returns_oop = false;
+        for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax && !returns_oop; i++) {
+          ProjNode* pn = n->fast_out(i)->as_Proj();
+          if (pn->_con >= TypeFunc::Parms && pn->bottom_type()->isa_oopptr()) {
+            returns_oop = true;
+          }
+        }
+        if (returns_oop) {
+          add_call_node(n->as_Call());
+        }
       }
     }
     return;
   }
   // Put this check here to process call arguments since some call nodes

@@ -472,12 +483,14 @@
       }
       break;
     }
     case Op_Proj: {
       // we are only interested in the oop result projection from a call
-      if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() &&
-          n->in(0)->as_Call()->returns_pointer()) {
+      if (n->as_Proj()->_con >= TypeFunc::Parms && n->in(0)->is_Call() &&
+          (n->in(0)->as_Call()->returns_pointer() || n->bottom_type()->isa_oopptr())) {
+        assert((n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->as_Call()->returns_pointer()) ||
+               n->in(0)->as_Call()->tf()->returns_value_type_as_fields(), "what kind of oop return is it?");
         add_local_var_and_edge(n, PointsToNode::NoEscape,
                                n->in(0), delayed_worklist);
       }
       break;
     }

@@ -679,12 +692,14 @@
       }
       ELSE_FAIL("Op_Phi");
     }
     case Op_Proj: {
       // we are only interested in the oop result projection from a call
-      if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() &&
-          n->in(0)->as_Call()->returns_pointer()) {
+      if (n->as_Proj()->_con >= TypeFunc::Parms && n->in(0)->is_Call() &&
+          (n->in(0)->as_Call()->returns_pointer()|| n->bottom_type()->isa_oopptr())) {
+        assert((n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->as_Call()->returns_pointer()) ||
+               n->in(0)->as_Call()->tf()->returns_value_type_as_fields(), "what kind of oop return is it?");
         add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(0), NULL);
         break;
       }
       ELSE_FAIL("Op_Proj");
     }

@@ -795,11 +810,11 @@
   }
   return;
 }
 
 void ConnectionGraph::add_call_node(CallNode* call) {
-  assert(call->returns_pointer(), "only for call which returns pointer");
+  assert(call->returns_pointer() || call->tf()->returns_value_type_as_fields(), "only for call which returns pointer");
   uint call_idx = call->_idx;
   if (call->is_Allocate()) {
     Node* k = call->in(AllocateNode::KlassNode);
     const TypeKlassPtr* kt = k->bottom_type()->isa_klassptr();
     assert(kt != NULL, "TypeKlassPtr  required.");
< prev index next >