intrinsic that makes runtime choice whether to revert to java
Vladimir Kozlov
vladimir.kozlov at oracle.com
Thu Jul 5 14:54:49 PDT 2012
Deneau, Tom wrote:
> Vladimir --
>
> The code you provided helps a lot, thank you.
> I am still testing it, but it seems to work for the basic cases.
>
> A couple of questions based on my not having done much with GraphKit:
>
> 1) I want to do a test at compile time (or maybe even earlier at
> stub generation time) as to whether a certain library class is a
> version that has a certain field. This would fail if are
> mistakenly using the old library with a new JVM, which would
> indicate we cannot use the intrinsics. I suspect this is done
> using the class from the systemDictionary but I'm not sure.
Look on usage of find_local_field() method in thread.cpp and other places.
>
> 2) At compile time, when generating the code for the fast path, I
> want to generate a Node* to load a certain field from the
> embeddedCipher object (since we have made it past the predicate,
> we know that the embeddedCipher object is an instance of the
> class we expect). I need to do this so that I can pass the
> field to the stub. But at compile time, the particular instance
> that triggered compilation might not have an embeddedCipher
> object of the proper type. Still I want to generate a Node*
> that will load a field from the embeddedCipher object as if it
> were the proper type. And I am not sure how to do that. (My
> current code failes to generate the intrinsic unless the
> particular instance that triggered compilation is the correct
> type). I hope this question makes sense.
I assume by the "fast path" you mean the intrinsic for whole encrypt() method.
Right? You need to cast field object's type to AESCrypt if I understand your
question correctly:
const TypeKlassPtr* aklass = TypeKlassPtr::make(klass_AESCrypt);
_sp += nargs; // gen_instanceof might do an uncommon trap
Node* instof = gen_instanceof(embeddedCipherObj, makecon(aklass));
_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);
// fall through if the instance exactly matches the desired type
const TypeOopPtr* xtype = aklass->as_instance_type();
Node* cast = new(C, 2) CheckCastPPNode(control(), embeddedCipherObj, xtype);
cast = _gvn.transform(cast);
_gvn.replace_in_map(embeddedCipherObj, cast);
Node* k_len = get_key_len_from_aescrypt_object(cast);
>
> 3) If I want my predicate to be based on two Boolean tests,
> similar to the following java code
>
> if ((obj instanceof XXXClass) && ((XXXClass)(obj).field == SomeConstant))
>
> and I want to of course skip the second test if the first test fails.
> Is it something like the following?
You need Region node to merge 2 false paths:
RegionNode* region = new(C, 3) RegionNode(3);
...
region->init_req(1, instof_false);
...
region->init_req(2, klen_false);
record_for_igvn(region);
return _gvn.transform(region);
>
> _sp += nargs; // gen_instanceof might do an uncommon trap
> Node* instof = gen_instanceof(embeddedCipherObj, makecon(TypeKlassPtr::make(klass_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
>
> Node* k_len = get_key_len_from_aescrypt_object(embeddedCipherObj);
> Node* cmp_klen = _gvn.transform(new (C, 3) CmpINode(k_len, intcon(44))); // corresponds to keys we can handle
> Node* bool_klen = _gvn.transform(new (C, 2) BoolNode(cmp_klen, BoolTest::ne));
Why exact 44 and not <= ?
Vladimir
> Node* klen_false = generate_guard(bool_klen, NULL, PROB_MIN);
> return klen_false;
>
> -- Tom
>
> -----Original Message-----
> From: Vladimir Kozlov [mailto:vladimir.kozlov at oracle.com]
> Sent: Monday, July 02, 2012 9:57 PM
> To: Deneau, Tom
> Cc: hotspot-compiler-dev at openjdk.java.net
> Subject: Re: intrinsic that makes runtime choice whether to revert to java
>
> I finally had time today to look on this. Here is code:
>
> http://cr.openjdk.java.net/~kvn/pred_intr/webrev
>
> But I did not test or optimize it (part of new code in callGenerator.cpp should
> be shared with PredictedCallGenerator from which it was cloned).
>
> Vladimir
>
> Deneau, Tom wrote:
>> Hi all --
>>
>> I am writing a hotspot intrinsic but I want it to make a runtime
>> choice whether to execute the intrinsic code or to execute the regular
>> java code.
>>
>> I got the suggestion below from Vladimir but I am not experienced
>> enough with the graphkit functionality to see how to do this. Would
>> someone be able to provide the code skeleton for this? I can generate
>> the region to actually do my intrinsic and I believe I can generate the
>> BoolNode which determines which path to take.
>>
>> The other choice would be to modify the actual JDK library routine to
>> do the runtime tests and call a new routine which the intrinsic would
>> hook into. I have done this for testing but I am assuming this is more
>> intrusive since on some architectures the intrinsic will not even be generated.
>>
>> -- Tom Deneau
>>
>>> We don't have such mechanism currently. But it is not difficult to implement.
>>> Look on the code in doCall.cpp and callGenerator files. Instead of calling
>>> find_intrinsic() you need to do something special for your case. Like code for
>>> CallGenerator::for_method_handle_call() where you will generate class check and
>>> on one path you will get intrinsic (by calling find_intrinsic()) and on other
>>> path is regular CallGenerator::for_inline().
>>
>
>
More information about the hotspot-compiler-dev
mailing list