Getting ciObject from oop/jobject

Nick Williams nicholas+openjdk at nicholaswilliams.net
Thu Aug 1 18:28:58 PDT 2013


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/20130801/0aae4495/attachment.html 


More information about the hotspot-compiler-dev mailing list