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);