for (re-)review (M): 6814659: separable cleanups and subroutines for 6655638
John Rose
John.Rose at Sun.COM
Fri Mar 13 19:43:21 PDT 2009
On Mar 12, 2009, at 5:19 PM, Vladimir Kozlov wrote:
> About next:
>
> > 3. 6812831 factor general subclass check (for 6655638)
> > http://cr.openjdk.java.net/~jrose/6813212/webrev.01/ (not yet
> integrated)
>
> Assembler code on x86 and sparc looks good for me.
Great.
It tests well on JPRT and CTW (all jars, several solaris configs in
x86/sparc c1/c2 32/64).
I am confident there are fewer bugs after the change than before,
despite the amount of touches.
> General question: why we do next check in enc_PartialSubtypeCheck()
>
> // Compare super with sub directly, since super is not in its own
> SSA.
> // The compiler used to emit this test, but we fold it in here,
> // to allow platform-specific tweaking on sparc.
> __ cmpptr(Rrax, Rrsi);
> __ jcc(Assembler::equal, hit);
>
> and in Sparc::partial_subtype_check()
>
> // Compare super with sub directly, since super is not in its
> own SSA.
> // The compiler used to emit this test, but we fold it in here,
> // to increase overall code density, with no real loss of speed.
> { Label L;
> __ cmp(O1, O2);
> __ brx(Assembler::notEqual, false, Assembler::pt, L);
> __ delayed()->nop();
> __ retl();
> __ delayed()->addcc(G0,0,O0); // set Z flags, zero result
> __ bind(L);
> }
>
> When in GraphKit::gen_subtype_check we have the check contrary to
> the above
> comments:
>
> // Check for self. Very rare to get here, but its taken 1/3 the
> time.
> // No performance impact (too rare) but allows sharing of secondary
> arrays
> // which has some footprint reduction.
> Node *cmp3 = _gvn.transform( new (C, 3) CmpPNode( subklass,
> superklass ) );
> Node *bol3 = _gvn.transform( new (C, 2) BoolNode( cmp3,
> BoolTest::eq ) );
> IfNode *iff3 = create_and_xform_if( control(), bol3,
> PROB_LIKELY(0.36f), COUNT_UNKNOWN );
> r_ok_subtype->init_req(2, _gvn.transform( new (C, 1) IfTrueNode
> ( iff3 ) ) );
> set_control( _gvn.transform( new (C, 1)
> IfFalseNode( iff3 ) ) );
It's an old piece of history, I guess, from when two engineers were
working on one chunk of code. Thanks for asking. The extra self-
check on the slow path apparently has been useless for years.
So, I have removed those extra checks, of course after checking all
the usages of PartialSubtypeCheck nodes on x86 and sparc.
I put in new comments in graphKit and assembler_<arch> explaining why
the self-check is there, and why it comes in a different order in C2
than elsewhere.
Nice!
> Next, why we keep generate_partial_subtype_check stub?
> The only place which calls it is sparc.ad:
>
> enc_class enc_PartialSubtypeCheck() %{
> MacroAssembler _masm(&cbuf);
> __ call(StubRoutines::Sparc::partial_subtype_check(),
> relocInfo::runtime_call_type);
> __ delayed()->nop();
> %}
>
> Is there a reason to keep the call instead of using your new
> macroassembler methods?
Code density. The sparc loop is much bigger than the x86 loop, so we
out-of-line it.
The graphKit.cpp comments mention the issue of code size, and I
improved them.
> assembler_x86.cpp check_klass_subtype_slow_path()
> Move next assert:
> + assert(secondary_supers_addr.base() != rax, "put sub_klass in
> another reg");
> (why not assert(sub_klass != rax, "put sub_klass in another reg") ?)
>
> before this code:
> + if (super_klass != rax || UseCompressedOops) {
> + if (!IS_A_TEMP(rax)) { push(rax); pushed_rax = true; }
> + mov(rax, super_klass);
> + }
>
> Also sub_klass != rcx since rcx is destroyed by debug counter code.
Good call. Done. I put the checks just before the instructions which
would kill sub_klass with a bad assignment, rather at the very top of
the function, where it would be hard to see why those restrictions
matter.
> You changed encode_heap_oop(rax) to encode_heap_oop_not_null(rax).
> Can you give guaranty that super_klass value is not NULL for all
> cases?
Yes, it would be fundamental system bug if we were to class-check
against a null klassOop. I put an explanatory comment near the calls
to encode_heap_oop_not_null.
> x86_64.ad, x86_32.ad
> You can remove the label 'cmiss' from enc_PartialSubtypeCheck.
Done. I also removed the label 'hit' everywhere, since it is not used
except by the self-checks, which I removed.
I've updated the webrev:
http://cr.openjdk.java.net/~jrose/6813212/webrev.02/
http://cr.openjdk.java.net/~jrose/6813212/01-to-02.patch.txt
> Thanks,
> Vladimir
Many thanks! I owe you a drink of your favorite beverage.
-- John
More information about the hotspot-compiler-dev
mailing list