intrinsic that makes runtime choice whether to revert to java
Deneau, Tom
tom.deneau at amd.com
Thu Jul 12 08:03:56 PDT 2012
Vladimir --
Thanks for the explanation. Just trying to make sure I understand this...
I think you're saying that when the C2 compiler decided to compile this
particular invocation of CipherBlockChaining.encrypt, it "knows" that
the embeddedCipher will be AESCrypt type, so the instanceof check
I am doing at runtime will always be true.
But if I had a test case that switched back and forth between say DESCrypt and AESCrypt, then
when we compiled that particular invocation, we would get a real conditional in the predicated path.
I think we're also saying here that if by the time something gets
hot enough to compile and AESCrypt class has never even been loaded, we should
just forget about ever taking the intrinsic for this invocation and always
take the java path. And if later it turns out that later AESCrypt does
actually get loaded, maybe things will get recompiled and if not it will
still be functionally correct?
-- Tom
-----Original Message-----
From: Vladimir Kozlov [mailto:vladimir.kozlov at oracle.com]
Sent: Wednesday, July 11, 2012 11:35 PM
To: Deneau, Tom
Subject: Re: intrinsic that makes runtime choice whether to revert to java
C2 is very smart :)
It uses unique subclass instead of abstract class. In your case AESCrypt is
unique implementor of SymmetricCipher abstract class and that is why the
predicate is always true in your case:
[t at 40 l at 40]: print field_klass->print()
<ciInstanceKlass name=com/sun/crypto/provider/SymmetricCipher loader=0xc5432720
loaded=true initialized=true finalized=false subklass=true size=17
flags=DEFAULT_ACCESS,super,abstract ident=762 PERM address=0x715a728>
5617 const Type *type = TypeOopPtr::make_from_klass(field_klass->as_klass());
[t at 40 l at 40]: next
[t at 40 l at 40]: print type->dump()
com/sun/crypto/provider/AESCrypt:exact *
You don't need Region node. Use next code for dead fast path - then
kit.stopped() will be true:
if (!klass_AESCrypt->is_loaded()) {
set_control(top()); // no regular fast path
return NULL;
}
Your new check (slow_ctl != NULL) in generate() is correct.
Also change flag methods in class PredictedIntrinsicGenerator:
< virtual bool is_virtual() const { return _intrinsic->is_virtual(); }
< virtual bool is_inlined() const { return true; }
--
> virtual bool is_virtual() const { return true; }
> virtual bool is_inline() const { return true; }
Vladimir
Deneau, Tom wrote:
> Vladimir --
>
>
>
> Ah, that's good to hear. I hope you had a good vacation..
>
>
>
> I made a few changes so things are not crashing now but I still don't think
>
> it is really correct. The webrev at
> http://cr.openjdk.java.net/~tdeneau/predicated-problem/webrev/ has been
> updated accordingly.
>
>
>
> The changes I made were:
>
>
>
> 1) As mentioned before, the code that is generating the predicate (shown
> here) is
>
> always creating a NULL node from generate_guard, which as I
> understand it means the instanceof conditional
>
> will never be false? This doesn't seem right.
>
>
>
> I think we wanted to reserve a NULL node to mean we could not
> generate the predicate.
>
> So I constructed a Region node with the single NULL node as input,
> which again doesn't
>
> seem right but at least has a non-NULL node to return.
>
>
>
> ciKlass* klass_AESCrypt = tinst->klass()->as_instance_klass()
>
>
> ->find_klass(ciSymbol::make("com/sun/crypto/provider/AESCrypt"));
>
> if (!klass_AESCrypt->is_loaded()) return NULL;
>
>
>
> ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass();
>
>
>
> _sp += nargs; // gen_instanceof might do an uncommon trap
>
> Node* instof = gen_instanceof(embeddedCipherObj,
> makecon(TypeKlassPtr::make(instklass_AESCrypt)));
>
> _sp -= nargs;
>
> Node* cmp_instof = _gvn.transform(new (C, 3) CmpINode(instof,
> intcon(1)));
>
> Node* bool_instof = _gvn.transform(new (C, 2) BoolNode(cmp_instof,
> BoolTest::ne));
>
>
>
> Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN);
>
> //instanceOf == true, fallthrough
>
>
>
>
>
> // I added the following so we wouldn't return a NULL node.
>
> RegionNode* region = new(C, 2) RegionNode(2);
>
> region->init_req(1, instof_false);
>
> record_for_igvn(region);
>
> return _gvn.transform(region);
>
>
More information about the hotspot-compiler-dev
mailing list