You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@harmony.apache.org by Pavel Rebriy <pa...@gmail.com> on 2008/02/05 13:46:17 UTC

[drlvm][vmmagic] Thread.currentThread() helper creation ploblems

Hello,

Working on HARMONY-4555 [1] I've tried to create VMMagic helper for
Thread.currentThread() function but faced with some difficulties related to
VMMagic mechanism.
Missing detailed patch (you can see it in JIRA [1]) I'm going to show
problematic function. Here they are:

1. org.apache.harmony.drlvm.thread.ThreadHelper.getCurrentThreadAddr()

@Inline
public static Address getCurrentThreadAddr() {
        Address tlsThread = VMHelper.getTlsBaseAddress();
        Address javaObjectPtr = tlsThread.plus
(THREAD_JAVA_OBJECT_OFFSET).loadAddress();
        return javaObjectPtr.isZero() ? null : javaObjectPtr.loadAddress();
}

2. java.lang.VMThreadManager.currentThread()

static Thread currentThread() {
    if (VMHelper.isVMMagicPackageSupported()) {
         Address currentThreadAddr = ThreadHelper.getCurrentThreadAddr();
         if (currentThreadAddr.isZero()) {
             return null;
         } else {
             return
(Thread)currentThreadAddr.toObjectReference().toObject();
         }
     }
     return currentThreadNative();
}

As you can see the 1st function is inline and the 2nd calls the 1st. The 1st
function can return null in case if thread don't attached yet to VM (for
instance if you call Thread.currentThread() during execution of constructor
of current Java thread).

Tested test is the following:

public class CurrentThreadTest {
    public static void main(String[] args) {
        long st = System.currentTimeMillis();
        for(int i=0; i< 100000000; i++) {
            Thread.currentThread();
        }
        long res = System.currentTimeMillis()-st;
        System.out.println("res="+res);
    }
}

Helper implemented in such way causes to crash in JIT on it (see [1] to
detailed stack).

Question is: Is it incorrect implementation of helper function? Where is the
problem?

I've tried to another version of helper which is not so good as the first
try:

1. org.apache.harmony.drlvm.thread.ThreadHelper.getCurrentThreadAddr()

@Inline
public static Address getCurrentThreadAddr() {
public static Address getCurrentThreadAddr() {
     Address tlsThread = VMHelper.getTlsBaseAddress();
     Address javaObjectPtr = tlsThread.plus
(THREAD_JAVA_OBJECT_OFFSET).loadAddress();
     return javaObjectPtr.loadAddress();
}

2. java.lang.VMThreadManager.currentThread()

static Thread currentThread() {
     if (VMHelper.isVMMagicPackageSupported()) {
         try {
             return
(Thread)ThreadHelper.getCurrentThreadAddr().toObjectReference().toObject();
         } catch (NullPointerException e) {
             return null;
         }
     }
     return currentThreadNative();
}

Second helper doesn't lead to crash but throws NullPointerException in

<<<< return
(Thread)ThreadHelper.getCurrentThreadAddr().toObjectReference().toObject();
>>>>

line.

Question is: Why trap doesn't catch NullPointerException? Helper problems?

I've modified getCurrentThreadAddr() function to force throwing exception
case:

1. org.apache.harmony.drlvm.thread.ThreadHelper.getCurrentThreadAddr()

@Inline
public static Address getCurrentThreadAddr() {
     Address tlsThread = VMHelper.getTlsBaseAddress();
     Address javaObjectPtr = tlsThread.plus
(THREAD_JAVA_OBJECT_OFFSET).loadAddress();
     if (javaObjectPtr != null) {
         return javaObjectPtr.loadAddress();
     } else {
         throw new NullPointerException();
     }
}

After it the test passes.

Could any JIT experts help me to understand the root of the problems?

[1] http://issues.apache.org/jira/browse/HARMONY-4555

-- 
Best regards,
Pavel Rebriy

Re: [drlvm][vmmagic] Thread.currentThread() helper creation ploblems

Posted by Pavel Rebriy <pa...@gmail.com>.
Thank you, Mikhail, I've applied you recommendation to the patch.

The question about the second patch, why trap doesn't catch NPE?

On 05/02/2008, Mikhail Fursov <mi...@gmail.com> wrote:
>
> Pavel, I see 2 problems in your code:
>
> 1) Initialize class of the ThreadHelper before using it to avoid mix of
> lazy-resolution mode and vmmagics
> You can do it this way:
> Index:
>
> vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/VMHelper.java
> ===================================================================
> ---
>
> vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/VMHelper.java
> (revision 618229)
> +++
>
> vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/VMHelper.java
> (working copy)
> @@ -60,6 +60,8 @@
>
>      // preload @Inline vmmagic class
>      static final Class pragmaInline = org.vmmagic.pragma.Inline.class;
> +    static final Class threadHelper =
> org.apache.harmony.drlvm.thread.ThreadHelper.class;
> +    static final Class vmFastPathes =
> org.apache.harmony.drlvm.VMHelperFastPath.class;
>
>
> 2) Do not mix 'null' and Address in your code while using Jitrino.OPT. Use
> Address.zero() instead of managed 'null'.
>
> So, I propose changing ThreadHelper's method to this one:
>
> Index:
>
> vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/thread/ThreadHelper.java
> ===================================================================
> ---
>
> vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/thread/ThreadHelper.java
> (revision 618229)
> +++
>
> vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/thread/ThreadHelper.java
> (working copy)
> @@ -31,6 +31,7 @@
>
>      public static final int LOCK_WORD_OFFSET    = getLockWordOffset();
>      public static final int TLS_THREAD_ID_OFFSET= getThreadIdOffset();
> +    public static final int THREAD_JAVA_OBJECT_OFFSET =
> getThreadJavaObjectOffset();
>
>      @Inline
>      static int getThreadId() {
> @@ -40,6 +41,16 @@
>      }
>
>      @Inline
> +    public static Thread getCurrentThread() {
> +        Address tlsThread = VMHelper.getTlsBaseAddress();
>
> +        Address javaObjectPtr = tlsThread.plus
> (THREAD_JAVA_OBJECT_OFFSET).loadAddress();
>
> +        if (javaObjectPtr.isZero()) {
> +            return null;
> +        }
> +        return
> (Thread)javaObjectPtr.loadAddress().toObjectReference().toObject();
> +    }
>
>
>
> Tell me if you have more problems.
>
>
> On Feb 5, 2008 6:46 PM, Pavel Rebriy <pa...@gmail.com> wrote:
>
> > Hello,
> >
> > Working on HARMONY-4555 [1] I've tried to create VMMagic helper for
> > Thread.currentThread() function but faced with some difficulties related
> > to
> > VMMagic mechanism.
> > Missing detailed patch (you can see it in JIRA [1]) I'm going to show
> > problematic function. Here they are:
> >
> > 1. org.apache.harmony.drlvm.thread.ThreadHelper.getCurrentThreadAddr()
> >
> > @Inline
> > public static Address getCurrentThreadAddr() {
> >        Address tlsThread = VMHelper.getTlsBaseAddress();
> >        Address javaObjectPtr = tlsThread.plus
> > (THREAD_JAVA_OBJECT_OFFSET).loadAddress();
> >        return javaObjectPtr.isZero() ? null : javaObjectPtr.loadAddress
> ();
> > }
> >
> > 2. java.lang.VMThreadManager.currentThread()
> >
> > static Thread currentThread() {
> >    if (VMHelper.isVMMagicPackageSupported()) {
> >         Address currentThreadAddr = ThreadHelper.getCurrentThreadAddr();
> >         if (currentThreadAddr.isZero()) {
> >             return null;
> >         } else {
> >             return
> > (Thread)currentThreadAddr.toObjectReference().toObject();
> >         }
> >     }
> >     return currentThreadNative();
> > }
> >
> > As you can see the 1st function is inline and the 2nd calls the 1st. The
> > 1st
> > function can return null in case if thread don't attached yet to VM (for
> > instance if you call Thread.currentThread() during execution of
> > constructor
> > of current Java thread).
> >
> > Tested test is the following:
> >
> > public class CurrentThreadTest {
> >    public static void main(String[] args) {
> >        long st = System.currentTimeMillis();
> >        for(int i=0; i< 100000000; i++) {
> >            Thread.currentThread();
> >        }
> >        long res = System.currentTimeMillis()-st;
> >        System.out.println("res="+res);
> >    }
> > }
> >
> > Helper implemented in such way causes to crash in JIT on it (see [1] to
> > detailed stack).
> >
> > Question is: Is it incorrect implementation of helper function? Where is
> > the
> > problem?
> >
> > I've tried to another version of helper which is not so good as the
> first
> > try:
> >
> > 1. org.apache.harmony.drlvm.thread.ThreadHelper.getCurrentThreadAddr()
> >
> > @Inline
> > public static Address getCurrentThreadAddr() {
> > public static Address getCurrentThreadAddr() {
> >     Address tlsThread = VMHelper.getTlsBaseAddress();
> >     Address javaObjectPtr = tlsThread.plus
> > (THREAD_JAVA_OBJECT_OFFSET).loadAddress();
> >     return javaObjectPtr.loadAddress();
> > }
> >
> > 2. java.lang.VMThreadManager.currentThread()
> >
> > static Thread currentThread() {
> >     if (VMHelper.isVMMagicPackageSupported()) {
> >         try {
> >             return
> >
> >
> (Thread)ThreadHelper.getCurrentThreadAddr().toObjectReference().toObject();
> >         } catch (NullPointerException e) {
> >             return null;
> >         }
> >     }
> >     return currentThreadNative();
> > }
> >
> > Second helper doesn't lead to crash but throws NullPointerException in
> >
> > <<<< return
> >
> >
> (Thread)ThreadHelper.getCurrentThreadAddr().toObjectReference().toObject();
> > >>>>
> >
> > line.
> >
> > Question is: Why trap doesn't catch NullPointerException? Helper
> problems?
> >
> > I've modified getCurrentThreadAddr() function to force throwing
> exception
> > case:
> >
> > 1. org.apache.harmony.drlvm.thread.ThreadHelper.getCurrentThreadAddr()
> >
> > @Inline
> > public static Address getCurrentThreadAddr() {
> >     Address tlsThread = VMHelper.getTlsBaseAddress();
> >     Address javaObjectPtr = tlsThread.plus
> > (THREAD_JAVA_OBJECT_OFFSET).loadAddress();
> >     if (javaObjectPtr != null) {
> >         return javaObjectPtr.loadAddress();
> >     } else {
> >         throw new NullPointerException();
> >     }
> > }
> >
> > After it the test passes.
> >
> > Could any JIT experts help me to understand the root of the problems?
> >
> > [1] http://issues.apache.org/jira/browse/HARMONY-4555
> >
> > --
> > Best regards,
> > Pavel Rebriy
> >
>
>
>
>
> --
>
> Mikhail Fursov
>



-- 
Best regards,
Pavel Rebriy

Re: [drlvm][vmmagic] Thread.currentThread() helper creation ploblems

Posted by Mikhail Fursov <mi...@gmail.com>.
Pavel, I see 2 problems in your code:

1) Initialize class of the ThreadHelper before using it to avoid mix of
lazy-resolution mode and vmmagics
You can do it this way:
Index:
vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/VMHelper.java
===================================================================
---
vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/VMHelper.java
(revision 618229)
+++
vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/VMHelper.java
(working copy)
@@ -60,6 +60,8 @@

     // preload @Inline vmmagic class
     static final Class pragmaInline = org.vmmagic.pragma.Inline.class;
+    static final Class threadHelper =
org.apache.harmony.drlvm.thread.ThreadHelper.class;
+    static final Class vmFastPathes =
org.apache.harmony.drlvm.VMHelperFastPath.class;


2) Do not mix 'null' and Address in your code while using Jitrino.OPT. Use
Address.zero() instead of managed 'null'.

So, I propose changing ThreadHelper's method to this one:

Index:
vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/thread/ThreadHelper.java
===================================================================
---
vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/thread/ThreadHelper.java
(revision 618229)
+++
vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/thread/ThreadHelper.java
(working copy)
@@ -31,6 +31,7 @@

     public static final int LOCK_WORD_OFFSET    = getLockWordOffset();
     public static final int TLS_THREAD_ID_OFFSET= getThreadIdOffset();
+    public static final int THREAD_JAVA_OBJECT_OFFSET =
getThreadJavaObjectOffset();

     @Inline
     static int getThreadId() {
@@ -40,6 +41,16 @@
     }

     @Inline
+    public static Thread getCurrentThread() {
+        Address tlsThread = VMHelper.getTlsBaseAddress();
+        Address javaObjectPtr = tlsThread.plus
(THREAD_JAVA_OBJECT_OFFSET).loadAddress();
+        if (javaObjectPtr.isZero()) {
+            return null;
+        }
+        return
(Thread)javaObjectPtr.loadAddress().toObjectReference().toObject();
+    }



Tell me if you have more problems.

On Feb 5, 2008 6:46 PM, Pavel Rebriy <pa...@gmail.com> wrote:

> Hello,
>
> Working on HARMONY-4555 [1] I've tried to create VMMagic helper for
> Thread.currentThread() function but faced with some difficulties related
> to
> VMMagic mechanism.
> Missing detailed patch (you can see it in JIRA [1]) I'm going to show
> problematic function. Here they are:
>
> 1. org.apache.harmony.drlvm.thread.ThreadHelper.getCurrentThreadAddr()
>
> @Inline
> public static Address getCurrentThreadAddr() {
>        Address tlsThread = VMHelper.getTlsBaseAddress();
>        Address javaObjectPtr = tlsThread.plus
> (THREAD_JAVA_OBJECT_OFFSET).loadAddress();
>        return javaObjectPtr.isZero() ? null : javaObjectPtr.loadAddress();
> }
>
> 2. java.lang.VMThreadManager.currentThread()
>
> static Thread currentThread() {
>    if (VMHelper.isVMMagicPackageSupported()) {
>         Address currentThreadAddr = ThreadHelper.getCurrentThreadAddr();
>         if (currentThreadAddr.isZero()) {
>             return null;
>         } else {
>             return
> (Thread)currentThreadAddr.toObjectReference().toObject();
>         }
>     }
>     return currentThreadNative();
> }
>
> As you can see the 1st function is inline and the 2nd calls the 1st. The
> 1st
> function can return null in case if thread don't attached yet to VM (for
> instance if you call Thread.currentThread() during execution of
> constructor
> of current Java thread).
>
> Tested test is the following:
>
> public class CurrentThreadTest {
>    public static void main(String[] args) {
>        long st = System.currentTimeMillis();
>        for(int i=0; i< 100000000; i++) {
>            Thread.currentThread();
>        }
>        long res = System.currentTimeMillis()-st;
>        System.out.println("res="+res);
>    }
> }
>
> Helper implemented in such way causes to crash in JIT on it (see [1] to
> detailed stack).
>
> Question is: Is it incorrect implementation of helper function? Where is
> the
> problem?
>
> I've tried to another version of helper which is not so good as the first
> try:
>
> 1. org.apache.harmony.drlvm.thread.ThreadHelper.getCurrentThreadAddr()
>
> @Inline
> public static Address getCurrentThreadAddr() {
> public static Address getCurrentThreadAddr() {
>     Address tlsThread = VMHelper.getTlsBaseAddress();
>     Address javaObjectPtr = tlsThread.plus
> (THREAD_JAVA_OBJECT_OFFSET).loadAddress();
>     return javaObjectPtr.loadAddress();
> }
>
> 2. java.lang.VMThreadManager.currentThread()
>
> static Thread currentThread() {
>     if (VMHelper.isVMMagicPackageSupported()) {
>         try {
>             return
>
> (Thread)ThreadHelper.getCurrentThreadAddr().toObjectReference().toObject();
>         } catch (NullPointerException e) {
>             return null;
>         }
>     }
>     return currentThreadNative();
> }
>
> Second helper doesn't lead to crash but throws NullPointerException in
>
> <<<< return
>
> (Thread)ThreadHelper.getCurrentThreadAddr().toObjectReference().toObject();
> >>>>
>
> line.
>
> Question is: Why trap doesn't catch NullPointerException? Helper problems?
>
> I've modified getCurrentThreadAddr() function to force throwing exception
> case:
>
> 1. org.apache.harmony.drlvm.thread.ThreadHelper.getCurrentThreadAddr()
>
> @Inline
> public static Address getCurrentThreadAddr() {
>     Address tlsThread = VMHelper.getTlsBaseAddress();
>     Address javaObjectPtr = tlsThread.plus
> (THREAD_JAVA_OBJECT_OFFSET).loadAddress();
>     if (javaObjectPtr != null) {
>         return javaObjectPtr.loadAddress();
>     } else {
>         throw new NullPointerException();
>     }
> }
>
> After it the test passes.
>
> Could any JIT experts help me to understand the root of the problems?
>
> [1] http://issues.apache.org/jira/browse/HARMONY-4555
>
> --
> Best regards,
> Pavel Rebriy
>



-- 
Mikhail Fursov