Giter VIP home page Giter VIP logo

Comments (16)

cyrille-artho avatar cyrille-artho commented on August 30, 2024

JPF has a different way of handling native code (with @MJI annotation and native peers). We currently have a native peer for MethodHandle but not MethodHandleNatives. Maybe we can resolve this by providing an empty stub in a native peer for MethodHandleNatives.
Try creating src/peers/gov/nasa/jpf/vm/JPF_java_lang_invoke_MethodHandleNatives.java with an empty stub for the (mangled) method representing registerNatives.

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024

Please review it too @cyrille-artho

from jpf-core.

cyrille-artho avatar cyrille-artho commented on August 30, 2024

You have made one PR that fixes one of the unit tests that previously failed. I have merged that PR. Is there something else to review? You can either share a branch or make a PR with draft status if you'd like us to review some work in progress.

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024
public class JPF_java_lang_invoke_MethodHandleNatives extends NativePeer {
    @MJI
    public static void registerNatives____V(MJIEnv env, int clsObjRef) {
        // empty stub
    }
}

And then new error StackTrace are :

====================================================== error 1
gov.nasa.jpf.vm.NoUncaughtExceptionsProperty
java.lang.UnsatisfiedLinkError: cannot find native java.lang.invoke.MethodHandleNatives.getNamedCon
	at java.lang.invoke.MethodHandleNatives.getNamedCon(gov.nasa.jpf.vm.JPF_java_lang_invoke_MethodHandleNatives)
	at java.lang.invoke.MethodHandleNatives.verifyConstants(MethodHandleNatives.java:228)
	at java.lang.invoke.MethodHandleNatives.<clinit>(MethodHandleNatives.java:251)
	at java.lang.invoke.MemberName$Factory.resolve(MemberName.java:1085)
	at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1114)
	at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:3641)
	at java.lang.invoke.MethodHandles$Lookup.findStaticVarHandle(MethodHandles.java:3241)
	at java.util.concurrent.ForkJoinPool.<clinit>(ForkJoinPool.java:3488)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
	at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435)
	at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)

And here is the details for above error :

private static native int getNamedCon(int which, Object[] name);
    static boolean verifyConstants() {
        Object[] box = { null };
        for (int i = 0; ; i++) {
            box[0] = null;
            int vmval = getNamedCon(i, box);
            if (box[0] == null)  break;
            String name = (String) box[0];
            try {
                Field con = Constants.class.getDeclaredField(name);
                int jval = con.getInt(null);
                if (jval == vmval)  continue;
                String err = (name+": JVM has "+vmval+" while Java has "+jval);
                if (name.equals("CONV_OP_LIMIT")) {
                    System.err.println("warning: "+err);
                    continue;
                }
                throw new InternalError(err);
            } catch (NoSuchFieldException | IllegalAccessException ex) {
                String err = (name+": JVM has "+vmval+" which Java does not define");
                // ignore exotic ops the JVM cares about; we just wont issue them
                //System.err.println("warning: "+err);
                continue;
            }
        }
        return true;
    }
    static {
        assert(verifyConstants());
    }

from jpf-core.

cyrille-artho avatar cyrille-artho commented on August 30, 2024

This is a non-public function in a package-private class, so it is difficult to implement something that works on JPF.
We can try to exploit the fact that box[0] is null before the function is called; it is expected to modify that value when further checking is needed, otherwise the loop exists with break.
So a stub that returns 0 should work in the sense that the function above exits (as box[0] remains null).

If we get a lot of further problems that we cannot resolve with empty stubs, we have to try adding a model class that intercepts a call earlier in the stack trace at the very top of this issue.

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024
@MJI
    public static int getNamedCon__I_3Ljava_lang_Object_2__I(MJIEnv env, int clsObjRef, int which, int nameArrayRef) {
        // empty stub, returning 0 or an appropriate value if needed
        return 0;
    }
====================================================== error 1
gov.nasa.jpf.vm.NoUncaughtExceptionsProperty
java.lang.ExceptionInInitializerError
	at java.util.concurrent.ForkJoinPool.<clinit>(ForkJoinPool.java:3490)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
	at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435)
	at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
Caused by: java.lang.IllegalAccessException: no such field: java.util.concurrent.ForkJoinPool.poolIds/int/getStatic
	at java.lang.invoke.MemberName.makeAccessException(MemberName.java:972)
	at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1117)
	at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:3641)
	at java.lang.invoke.MethodHandles$Lookup.findStaticVarHandle(MethodHandles.java:3241)
	at java.util.concurrent.ForkJoinPool.<clinit>(ForkJoinPool.java:3488)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
	at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435)
	at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
Caused by: java.lang.UnsatisfiedLinkError: cannot find native java.lang.invoke.MethodHandleNatives.resolve
	at java.lang.invoke.MethodHandleNatives.resolve(gov.nasa.jpf.vm.JPF_java_lang_invoke_MethodHandleNatives)
	at java.lang.invoke.MemberName$Factory.resolve(MemberName.java:1085)
	at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1114)
	at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:3641)
	at java.lang.invoke.MethodHandles$Lookup.findStaticVarHandle(MethodHandles.java:3241)
	at java.util.concurrent.ForkJoinPool.<clinit>(ForkJoinPool.java:3488)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
	at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435)
	at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)

from jpf-core.

cyrille-artho avatar cyrille-artho commented on August 30, 2024

It looks like the reflection operations need more support; similar to JPFFieldVarHandle and its peer, we have to provide key methods for method handles.
I think the best course of action is to create a very small test that uses reflection to obtain such a handle, run the example on the regular JVM to make sure it succeeds, and then start looking into JPF's data structures and how to use them in the MethodHandle API.

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024

It's a bit complex one understand the background here. I don't think I fully understand what you were saying about… Could you tell me a bit more?

Is it about providing key methods like java.lang.invoke.MethodHandleNatives.resolve() methods here ?

static native MemberName resolve(MemberName self, Class<?> caller, int lookupMode,
            boolean speculativeResolve) throws LinkageError, ClassNotFoundException;

from jpf-core.

cyrille-artho avatar cyrille-artho commented on August 30, 2024

Let's look at this during the meeting tomorrow. I think it's better to try to resolve the string encoding issue first (and if you get completely stuck, some compiler warnings).
The problem here is that it seems we have to support too many non-public classes if we try to support MethodHandleNatives. It looks like it's better to make the "cut" at MethodHandles and look at replacing java.lang.invoke.MethodHandles$Lookup.findStaticVarHandle.

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024

After issue #475, we have solved the major complexity of this problem. Thank You @cyrille-artho . Your bit by bit explanation made it.

Here is the next sort of error :

====================================================== error 1
gov.nasa.jpf.vm.NoUncaughtExceptionsProperty
java.lang.NoSuchMethodException: jdk.internal.access.SharedSecrets.setJavaSecurityAccess(Ljdk/internal/access/JavaSecurityAccess;)V
	at java.security.ProtectionDomain.<clinit>(ProtectionDomain.java:133)
	at java.util.concurrent.ForkJoinPool.contextWithPermissions(ForkJoinPool.java:764)
	at java.util.concurrent.ForkJoinPool$DefaultForkJoinWorkerThreadFactory.<clinit>(ForkJoinPool.java:804)
	at java.util.concurrent.ForkJoinPool.<clinit>(ForkJoinPool.java:3506)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
	at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435)
	at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)

From this, we clearly see that there is a missing method setJavaSecurityAccess(). This method is not a complex one, below is the code from OpenJDK to understand it.

...
private static JavaSecurityAccess javaSecurityAccess;
...
public static void setJavaSecurityAccess(JavaSecurityAccess jsa) {
        javaSecurityAccess = jsa;
    }

This method sets the value of JavaSecurityAccess javaSecurityAccess. So copied them to our own model class as it is.

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024

gov.nasa.jpf.test.java.concurrent.ExecutorServiceTest PASSED after above method implementation.

But for gov.nasa.jpf.test.java.concurrent.CountDownLatchTest, error trace is :

====================================================== error 1
gov.nasa.jpf.vm.NoUncaughtExceptionsProperty
java.lang.NoSuchMethodError: jdk.internal.misc.Unsafe.weakCompareAndSetReference(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$Node.casNext(AbstractQueuedSynchronizer.java:465)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.cleanQueue(AbstractQueuedSynchronizer.java:743)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.cancelAcquire(AbstractQueuedSynchronizer.java:776)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:725)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:958)
	at java.util.concurrent.locks.ReentrantLock$Sync.lockInterruptibly(ReentrantLock.java:161)
	at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:372)
	at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:432)
	at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)

Now we can see that we need method jdk.internal.misc.Unsafe.weakCompareAndSetReference(...).

Here is it's implementation in OpenJDK :

public final boolean weakCompareAndSetReference(Object o, long offset,
                                                    Object expected,
                                                    Object x) {
        return compareAndSetReference(o, offset, expected, x);
    }

In our model class jdk.internal.misc.Unsafe, we already have compareAndSetReference(...) method as a native method. So again just copied it (weakCompareAndSetReference).


Now BOTH Tests PASSES

from jpf-core.

cyrille-artho avatar cyrille-artho commented on August 30, 2024

Great! This is again one correct behavior that may ignore some subsequent possible behaviors, as we don't implement the full JMM semantics in this case.

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024

Should I create PR for this now ?

Also, do we have to keep those 6 tests ?

from jpf-core.

cyrille-artho avatar cyrille-artho commented on August 30, 2024

Yes, please create a PR for this. Which six tests are you referring to? The tests regarding var handles?
A PR should always pair a fix (or enhancement) with at least one test that shows what the fix achieved. So at least one new (or strengthened) test should show that the old version of the code failed in some way (at least one test should fail without the implementation changes), and the implementation changes fix all previously failing tests.
If you create a PR that supports the var handle functionality correctly, make sure you include the six new tests for that.

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024

"Which six tests are you referring to? The tests regarding var handles?" -----> Yes, those Tests we wrote for analysing instance and static variables.
testFindVarHandleInstanceField()
testFindVarHandleStaticField()
testFindVarHandleNoSuchField()
testFindStaticVarHandleInstanceField()
testFindStaticVarHandleStaticField()
testFindStaticVarHandleNoSuchField()

I am keeping these in PR as it will explain the situation more in future.

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024

PR #478

from jpf-core.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.