Getting ciObject from oop/jobject

Krystal Mok rednaxelafx at gmail.com
Thu Aug 1 19:19:43 PDT 2013


On Fri, Aug 2, 2013 at 10:15 AM, Nick Williams <
nicholas+openjdk at nicholaswilliams.net> wrote:

>
> On Aug 1, 2013, at 9:07 PM, Krystal Mok wrote:
>
> Hi Nick,
>
> All right, that explains everything. My take on this:
>
> In HotSpot VM, the compiler threads shouldn't manipulate the Java object
> graph; in other words, although the compilers have access to certain Java
> objects through the Compiler Interface, it should only be "reading", but
> not "writing" or creating new Java objects.
>
> In your case, calling java_lang_StackTraceFrame::create() from compiler
> code creates a new object, and that's probably not the right way.
> You're trying to embed a pointer to a StackTraceFrame object in the
> generated code, as a constant. You don't have to do that. It might work if
> you embed the Method* (as a TypeMetadataPtr), and generate a runtime call
> to java_lang_StackTraceFrame::create() with that pointer, instead of
> calling it at compile time.
>
>
> Sounds good, but I'm not exactly sure how to do it. Do you mind assisting
> a bit? Remember that "ciMethod* m" is the executing method on the stack
> frame we're interested in. "Method* method" is the same thing, just in a
> different form. It sounds like I need to actually embed a runtime call to
> java_lang_StackTraceFrame::create()? I may be missing something. :-)
>
> Sure. I can give it a shot and see if it works.
Do you have a full patch that I can use as a base, or would you just like
to see a demo of doing a runtime call passing an embedded pointer constant?

- Kris


> Nick
>
>
> HTH,
> Kris
>
>
> On Fri, Aug 2, 2013 at 9:28 AM, Nick Williams <
> nicholas+openjdk at nicholaswilliams.net> wrote:
>
>> Well let me explain what I'm trying to do, and maybe someone can point me
>> in the right direction.
>>
>> On the core-libs-dev mailing list, I proposed a public API replacement
>> for the sun.reflect.Reflection#getCallerClass(int) of old and
>> the sun.reflect.Reflection#getCallerClass() of now. The new class,
>> java.lang.StackTraceFrame, has the following four methods that are relevant
>> to this discussion:
>>
>> @CallerSensitive
>> public native Class<?> getCallerClass();
>> public native Class<?> getCallerClass(int);
>> @CallerSensitive
>> public native StackTraceFrame getCallerFrame();
>> public native StackTraceFrame getCallerFrame(int);
>>
>> There is code in library_call.cpp that inlines
>> Reflection.getCallerClass(), and I took advantage of that code to also
>> inline StackTraceFrame.getCallerClass(). I also recreated (with changes
>> necessary due to new way of doing things in library_call.cpp) the inline
>> code for Reflection.getCallerClass(int) from the jdk7 source code. All of
>> that works perfectly. Code is inlined as expected, and all is well.
>>
>> Now I want to inline getCallerFrame() and getCallerFrame(int) as well. If
>> the Class<?> versions can be inlined, I see no reason that the
>> StackTraceFrame versions can't be inlined, but that may be my first wrong
>> assumption. If these methods aren't eligible for inlining for some reason,
>> please let me know and I can move on.
>>
>> So the code that gets the Class<?> and sets it as an inline constant
>> replacing the method call works like this (where m is a ciMethod*):
>>
>>           // Acquire method holder as java.lang.Class and push as
>> constant.
>>           ciInstanceKlass* caller_klass = m->holder();
>>           ciInstance* caller_mirror = caller_klass->java_mirror();
>>           set_result(makecon(TypeInstPtr::make(caller_mirror)));
>>
>> In javaClasses.cpp, I already have a method that can create a
>> StackTraceFrame from a Method* (not ciMethod*), method version (int), and
>> bci (int):
>>
>> oop java_lang_StackTraceFrame::create(Method* method, int version, int
>> bci, TRAPS);
>>
>> I tried calling that to create the StackTraceFrame, but it appears I
>> can't actually set it to the result. First I tried this:
>>
>>           // Acquire java.lang.StackTraceFrame and push as constant
>>           Method* method = (Method*)m->constant_encoding();
>>           oop stFrame = java_lang_StackTraceFrame::create(method,
>> method->constants()->version(), caller_jvms->bci(), NULL);
>>           set_result(makecon(TypeInstPtr::make(oop)));
>>
>> But this obviously didn't work because there is no TypeInstPtr::make()
>> method that takes an oopDesc&. So I looked around trying to figure out how
>> to convert an oop (or jobject, which I can get from an oop)  to a ciObject.
>> I discovered that ciObject actually holds a jobject internally, so I
>> figured surely this is possible. I found a few methods that appear to do
>> it. ciObjectFactory has a ciObject* get(oop) method, but I can't figure out
>> how to get the ciObjectFactory. ciEnv has a ciObject* get_object(oop)
>> method which I tried to use, only to discover that it was private:
>>
>>           // Acquire java.lang.StackTraceFrame and push as constant
>>           Method* method = (Method*)m->constant_encoding();
>>           oop stFrame = java_lang_StackTraceFrame::create(method,
>> method->constants()->version(), caller_jvms->bci(), NULL);
>>           ciObject* stfObject = ciEnv::current()->get_object(stFrame);
>>           set_result(makecon(TypeInstPtr::make(stfObject)));
>>
>> So that obviously doesn't work either. I'll admit, I'm a little out of my
>> league here. I was pretty confident working in javaClasses.hpp/cpp and
>> jvm.h/cpp, but this inlining/compiler stuff is pretty over my head.
>> Hopefully one of the knowledgeable people on this list can help me out with
>> this. I want my code to perform as well as possible and also be
>> stable--more likely to get accepted that way. :-)
>>
>> Thanks,
>>
>> Nick
>>
>> On Aug 1, 2013, at 8:16 AM, Krystal Mok wrote:
>>
>> Hi Nick,
>>
>> This topic is related to HotSpot Server Compiler instead of the Java core
>> library, so I'm cc'ing this email to hotspot-compiler-dev and dropping
>> core-libs-dev.
>>
>> As you already know, HotSpot compilers are shielded from VM runtime
>> implementation details via the Compiler Interface (CI). That's why you
>> shouldn't be getting raw oops in C2 code.
>>
>> Where are you getting the oopInstance from? If it can be found from some
>> known "roots", e.g. "well-known classes", fields of "well-known classes",
>> or the holder class of the method to be compiled, etc., then it's already
>> available through CI.
>>
>> - Kris
>>
>>
>> On Thu, Aug 1, 2013 at 3:17 AM, Nick Williams <
>> nicholas+openjdk at nicholaswilliams.net> wrote:
>>
>>> In native code (library_call.cpp), if I have an oop (which I can convert
>>> to a jobject if need be), how do I get a ciObject? I see that ciEnv has a
>>> ciObject* get_object(oop) method, but it's private. And ciObjectFactory has
>>> a ciObject* get(oop) method, but I can't figure out how to get the
>>> ciObjectFactory instance.
>>>
>>> I know that ciObject keeps a jobject internally, and I know that
>>> ciObject has a ciObject(oop) constructor, but it's protected (for good
>>> reason).
>>>
>>> If it helps, I'm trying to inline a method and need to
>>> set_result(makecon(TypeInstPtr::make(oopInstance))). I may be going down
>>> the wrong path.
>>>
>>> Thanks in advance for any help,
>>>
>>> Nick
>>
>>
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20130802/2e318136/attachment-0001.html 


More information about the hotspot-compiler-dev mailing list