On Tuesday 19 June 2007 09:53, Andrew Haley wrote: > Andrew Haley writes: > > Andrew John Hughes writes: > > > Hi everyone, > > > > > > I've recently been trying to build JikesRVM on a Free platform (using > > > CACAO and some hacked up tools from OpenJDK in the form of IcePick). > > > I've got it just about there now, but I've been let down by a missing > > > native method. > > > > > > Within the java.util.concurrent framework, the class AtomicLong has a > > > native method, VMSupportsCS8 which CACAO at least doesn't provide. > > > It's basically just a check method to find out whether the VM > > > supports lockless compare-set operations on longs. > > > > > > >From java.util.concurrent.atomic.AtomicLong: > > > > > > /** > > > * Records whether the underlying JVM supports lockless > > > * CompareAndSet for longs. While the unsafe.CompareAndSetLong > > > * method works in either case, some constructions should be > > > * handled at Java level to avoid locking user-visible locks. > > > */ > > > static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8(); > > > > > > /** > > > * Returns whether underlying JVM supports lockless CompareAndSet > > > * for longs. Called only once and cached in > > > VM_SUPPORTS_LONG_CAS. */ > > > private static native boolean VMSupportsCS8(); > > > > > > Has anyone implemented this so far? So near, but yet so far! > > > > Yes, it's in libgcj, of course. > > > > jboolean > > java::util::concurrent::atomic::AtomicLong::VMSupportsCS8 () > > { > > // FIXME > > return false; > > } > > Actually, I didn't quite tell you the *whole* truth: VMSupportsCS8 is > also a gcj builtin. The code in libgcj is a fallback that gets called > only if libgcj is built with no optimization. > > Andrew. I've tried gcj this weekend (from svn), after finding that it has both VMSupportsCS8 (as aph mentions above) and annotation support (which is where cacao fell down pretty finally, after twisti patched up the VMSupportsCS8 hole). I get an interesting failure from this, which perhaps others may be able to enlighten me on. It seems a bit less straightforward than a simple missing method or feature... [echo] java.lang.NoClassDefFoundError: java.util.Collections$CheckedMap$CheckedEntrySet$1 [echo] at org.jikesrvm.classloader.VM_BootstrapClassLoader.loadVMClass(VM_BootstrapClassLoader.java:132) [echo] at org.jikesrvm.classloader.VM_TypeReference.resolveInternal(VM_TypeReference.java:745) [echo] at org.jikesrvm.classloader.VM_TypeReference.resolve(VM_TypeReference.java:719) [echo] at BootImageWriter.createBootImageObjects(BootImageWriter.java:1018) [echo] at BootImageWriter.main(BootImageWriter.java:614) [echo] Caused by: java.lang.IncompatibleClassChangeError: java.util.Collections$CheckedMap$CheckedEntrySet$1 [echo] at java.lang.VMClassLoader.defineClass(natVMClassLoader.cc:83) [echo] at java.lang.ClassLoader.defineClass(ClassLoader.java:573) [echo] at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:85) [echo] at java.net.URLClassLoader.findClass(URLClassLoader.java:616) [echo] at java.lang.ClassLoader.loadClass(ClassLoader.java:442) [echo] at java.lang.ClassLoader.loadClass(ClassLoader.java:377) [echo] at java.lang.Class.forName(natClass.cc:105) [echo] at org.jikesrvm.classloader.VM_Type.createClassForType(VM_Type.java:506) The problem is the java.lang.IncompatibleClassChangeError caused by trying to create a Class object for java.util.Collections$CheckedMap$CheckedEntrySet$1. This is thrown in _Jv_DefineClass (part of defineclass.c which is called by natVMClassLoader.cc above). I narrowed this down using gdb to the method checkExtends((jclass sub = "java.util.Collections$CheckedMap$CheckedEntrySet$1", jclass super = "java.util.Collections$CheckedIterator") and the failure of if (sub->loader != super->loader) for a non-public class (this anonymous class is a CheckedIterator implementation using by the CheckedEntrySet). You can mimic this simply with: public class TestClassLoading { public static void main(String[] args) throws Exception { System.out.println(Class.forName("java.util.Collections$CheckedMap$CheckedEntrySet$1")); } } The class isn't in gcj, which I think may be the problem. The example works fine with jamvm and cacao which has that class. Putting either Classpath from my local copy or the JikesRVM build on the classpath causes the error. Otherwise, it's a ClassNotFoundException. Adding a line beforehand to try for CheckedIterator succeeds, so clearly the problem is that gcj has its own CheckedIterator but is loading this class from the jar file, so that the class loaders don't match. This seems like a legitimate gcj error in that case, but that doesn't help with this corner case. The code for the class is in the gcj libraries, so maybe it is being optimised out or something...? Any help much appreciated, Cheers, -- Andrew :-) Help end the Java Trap! Contribute to GNU Classpath and the OpenJDK http://www.gnu.org/software/classpath http://openjdk.java.net
Attachment:
pgpp5jeiYtvzx.pgp
Description: PGP signature