src/share/vm/opto/macroArrayCopy.cpp

Print this page

        

@@ -58,199 +58,10 @@
 
 Node* PhaseMacroExpand::ConvI2L(Node* offset) {
   return transform_later( new (C, 2) ConvI2LNode(offset));
 }
 
-//-------------------------------gen_subtype_check-----------------------------
-// Generate a subtyping check.  Takes as input the subtype and supertype.
-// Returns 2 values: sets the default control() to the true path and returns
-// the false path.  Only reads invariant memory; sets no (visible) memory.
-// The PartialSubtypeCheckNode sets the hidden 1-word cache in the encoding
-// but that's not exposed to the optimizer.  This call also doesn't take in an
-// Object; if you wish to check an Object you need to load the Object's class
-// prior to coming here.
-Node* PhaseMacroExpand::gen_subtype_check(Node** ctrl, MergeMemNode* mem, Node* subklass, Node* superklass) {
-  // Fast check for identical types, perhaps identical constants.
-  // The types can even be identical non-constants, in cases
-  // involving Array.newInstance, Object.clone, etc.
-  if (subklass == superklass)
-    return top();             // false path is dead; no test needed.
-
-  if (_igvn.type(superklass)->singleton()) {
-    ciKlass* superk = _igvn.type(superklass)->is_klassptr()->klass();
-    ciKlass* subk   = _igvn.type(subklass)->is_klassptr()->klass();
-
-    // In the common case of an exact superklass, try to fold up the
-    // test before generating code.  You may ask, why not just generate
-    // the code and then let it fold up?  The answer is that the generated
-    // code will necessarily include null checks, which do not always
-    // completely fold away.  If they are also needless, then they turn
-    // into a performance loss.  Example:
-    //    Foo[] fa = blah(); Foo x = fa[0]; fa[1] = x;
-    // Here, the type of 'fa' is often exact, so the store check
-    // of fa[1]=x will fold up, without testing the nullness of x.
-    switch (C->static_subtype_check(superk, subk)) {
-    case Compile::SSC_always_false:
-      {
-        Node* always_fail = *ctrl;
-        *ctrl = top();
-        return always_fail;
-      }
-    case Compile::SSC_always_true:
-      return top();
-    case Compile::SSC_easy_test:
-      {
-        // Just do a direct pointer compare and be done.
-        Node* cmp = new(C, 3) CmpPNode(subklass, superklass);
-        transform_later(cmp);
-        Node* bol = new(C, 2) BoolNode(cmp, BoolTest::eq);
-        transform_later(bol);
-        IfNode* iff = new (C, 2) IfNode(*ctrl, bol, PROB_STATIC_FREQUENT, COUNT_UNKNOWN);
-        transform_later(iff);
-        *ctrl = new(C, 1) IfTrueNode (iff);
-        transform_later(*ctrl);
-        Node* res = new(C, 1) IfFalseNode(iff);
-        transform_later(res);
-        return res;
-      }
-    case Compile::SSC_full_test:
-      break;
-    default:
-      ShouldNotReachHere();
-    }
-  }
-
-  // %%% Possible further optimization:  Even if the superklass is not exact,
-  // if the subklass is the unique subtype of the superklass, the check
-  // will always succeed.  We could leave a dependency behind to ensure this.
-
-  // First load the super-klass's check-offset
-  Node *p1 = basic_plus_adr( superklass, superklass, in_bytes(Klass::super_check_offset_offset()) );
-  Node* m = mem->memory_at(C->get_alias_index(_igvn.type(p1)->is_ptr()));
-  Node *chk_off = new (C, 3) LoadINode( NULL, m, p1, _igvn.type(p1)->is_ptr() );
-  transform_later(chk_off);
-  int cacheoff_con = in_bytes(Klass::secondary_super_cache_offset());
-  bool might_be_cache = (_igvn.find_int_con(chk_off, cacheoff_con) == cacheoff_con);
-
-  // Load from the sub-klass's super-class display list, or a 1-word cache of
-  // the secondary superclass list, or a failing value with a sentinel offset
-  // if the super-klass is an interface or exceptionally deep in the Java
-  // hierarchy and we have to scan the secondary superclass list the hard way.
-  // Worst-case type is a little odd: NULL is allowed as a result (usually
-  // klass loads can never produce a NULL).
-  Node *chk_off_X = ConvI2X(chk_off);
-  Node *p2 = new (C, 4) AddPNode(subklass,subklass,chk_off_X);
-  transform_later(p2);
-  // For some types like interfaces the following loadKlass is from a 1-word
-  // cache which is mutable so can't use immutable memory.  Other
-  // types load from the super-class display table which is immutable.
-  m = mem->memory_at(C->get_alias_index(_igvn.type(p2)->is_ptr()));
-  Node *kmem = might_be_cache ? m : C->immutable_memory();
-  Node *nkls = LoadKlassNode::make( _igvn, kmem, p2, _igvn.type(p2)->is_ptr(), TypeKlassPtr::OBJECT_OR_NULL );
-  transform_later(nkls);
-
-  // Compile speed common case: ARE a subtype and we canNOT fail
-  if( superklass == nkls )
-    return top();             // false path is dead; no test needed.
-
-  // See if we get an immediate positive hit.  Happens roughly 83% of the
-  // time.  Test to see if the value loaded just previously from the subklass
-  // is exactly the superklass.
-  Node *cmp1 = new (C, 3) CmpPNode( superklass, nkls );
-  transform_later(cmp1);
-  Node *bol1 = new (C, 2) BoolNode( cmp1, BoolTest::eq );
-  transform_later(bol1);
-  IfNode *iff1 = new (C, 2) IfNode(*ctrl, bol1, PROB_LIKELY(0.83f), COUNT_UNKNOWN );
-  transform_later(iff1);
-  Node *iftrue1 = new (C, 1) IfTrueNode ( iff1 );
-  transform_later(iftrue1);
-  *ctrl = new (C, 1) IfFalseNode( iff1 );
-  transform_later(*ctrl);
-
-  // Compile speed common case: Check for being deterministic right now.  If
-  // chk_off is a constant and not equal to cacheoff then we are NOT a
-  // subklass.  In this case we need exactly the 1 test above and we can
-  // return those results immediately.
-  if (!might_be_cache) {
-    Node* not_subtype_ctrl = *ctrl;
-    *ctrl = iftrue1; // We need exactly the 1 test above
-    return not_subtype_ctrl;
-  }
-
-  // Gather the various success & failures here
-  RegionNode *r_ok_subtype = new (C, 4) RegionNode(4);
-  transform_later(r_ok_subtype);
-  RegionNode *r_not_subtype = new (C, 3) RegionNode(3);
-  transform_later(r_not_subtype);
-
-  r_ok_subtype->init_req(1, iftrue1);
-
-  // Check for immediate negative hit.  Happens roughly 11% of the time (which
-  // is roughly 63% of the remaining cases).  Test to see if the loaded
-  // check-offset points into the subklass display list or the 1-element
-  // cache.  If it points to the display (and NOT the cache) and the display
-  // missed then it's not a subtype.
-  Node *cacheoff = _igvn.intcon(cacheoff_con);
-  Node *cmp2 = new (C, 3) CmpINode( chk_off, cacheoff );
-  transform_later(cmp2);
-  Node *bol2 = new (C, 2) BoolNode( cmp2, BoolTest::ne );
-  transform_later(bol2);
-  IfNode *iff2 = new (C, 2) IfNode( *ctrl, bol2, PROB_LIKELY(0.63f), COUNT_UNKNOWN );
-  transform_later(iff2);
-  r_not_subtype->init_req(1,  transform_later(new (C, 1) IfTrueNode (iff2)));
-  *ctrl =                     transform_later(new (C, 1) IfFalseNode(iff2));
-
-  // Check for self.  Very rare to get here, but it is taken 1/3 the time.
-  // No performance impact (too rare) but allows sharing of secondary arrays
-  // which has some footprint reduction.
-  Node *cmp3 = new (C, 3) CmpPNode( subklass, superklass );
-  transform_later(cmp3);
-  Node *bol3 = new (C, 2) BoolNode( cmp3, BoolTest::eq );
-  transform_later(bol3);
-  IfNode *iff3 = new (C, 2) IfNode( *ctrl, bol3, PROB_LIKELY(0.36f), COUNT_UNKNOWN );
-  transform_later(iff3);
-  r_ok_subtype->init_req(2,  transform_later(new (C, 1) IfTrueNode ( iff3 ) ) );
-  *ctrl =                    transform_later(new (C, 1) IfFalseNode( iff3 ) );
-
-  // -- Roads not taken here: --
-  // We could also have chosen to perform the self-check at the beginning
-  // of this code sequence, as the assembler does.  This would not pay off
-  // the same way, since the optimizer, unlike the assembler, can perform
-  // static type analysis to fold away many successful self-checks.
-  // Non-foldable self checks work better here in second position, because
-  // the initial primary superclass check subsumes a self-check for most
-  // types.  An exception would be a secondary type like array-of-interface,
-  // which does not appear in its own primary supertype display.
-  // Finally, we could have chosen to move the self-check into the
-  // PartialSubtypeCheckNode, and from there out-of-line in a platform
-  // dependent manner.  But it is worthwhile to have the check here,
-  // where it can be perhaps be optimized.  The cost in code space is
-  // small (register compare, branch).
-
-  // Now do a linear scan of the secondary super-klass array.  Again, no real
-  // performance impact (too rare) but it's gotta be done.
-  // Since the code is rarely used, there is no penalty for moving it
-  // out of line, and it can only improve I-cache density.
-  // The decision to inline or out-of-line this final check is platform
-  // dependent, and is found in the AD file definition of PartialSubtypeCheck.
-  Node* psc = new (C, 3) PartialSubtypeCheckNode(*ctrl, subklass, superklass);
-  transform_later(psc);
-
-  Node *cmp4 = new (C, 3) CmpPNode( psc, _igvn.zerocon(T_OBJECT) );
-  transform_later(cmp4);
-  Node *bol4 = new (C, 2) BoolNode( cmp4, BoolTest::ne );
-  transform_later(bol4);
-  IfNode *iff4 = new (C, 2) IfNode( *ctrl, bol4, PROB_FAIR, COUNT_UNKNOWN );
-  transform_later(iff4);
-  r_not_subtype->init_req(2, transform_later( new (C, 1) IfTrueNode (iff4) ) );
-  r_ok_subtype ->init_req(3, transform_later( new (C, 1) IfFalseNode(iff4) ) );
-
-  // Return false path; set default control to true path.
-  *ctrl = r_ok_subtype;
-  return r_not_subtype;
-}
-
 Node* PhaseMacroExpand::make_leaf_call(Node* ctrl, Node* mem,
                                        const TypeFunc* call_type, address call_addr,
                                        const char* call_name,
                                        const TypePtr* adr_type,
                                        Node* parm0, Node* parm1,

@@ -861,11 +672,11 @@
     // are correct at the source level.
     //
     // Test S[] against D[], not S against D, because (probably)
     // the secondary supertype cache is less busy for S[] than S.
     // This usually only matters when D is an interface.
-    Node* not_subtype_ctrl = ac->is_arraycopy_notest() ? top() : gen_subtype_check(ctrl, mem, src_klass, dest_klass);
+    Node* not_subtype_ctrl = ac->is_arraycopy_notest() ? top() : GraphKit::gen_subtype_check_any_phase(src_klass, dest_klass, ctrl, mem, &_igvn);
     // Plug failing path into checked_oop_disjoint_arraycopy
     if (not_subtype_ctrl != top()) {
       Node* local_ctrl = *ctrl;
       MergeMemNode* local_mem = MergeMemNode::make(C, mem);
       transform_later(local_mem);