RE: Query on stacktrace management logic
Jeroen Frijters wrote: The reference implementation of VMClass will not have any instance members, but VMs might choose to add instance state. However, after thinking about it some more, I think it would be better to just add an instance member to Class, called vmState (or whatever) of type Object. That is more flexible (at the cost of additional downcasts). The only overhead for you is the unused vmState reference field in each Class instance. That sounds like a better general design. But to be frank we're not likely to use Class/VMClass in this way. Our Class already requires an opaque reference to a VM internal type mirror, and we chose our own strategy for populating the reflective information for a Class instance. On top of that there's the static initializer in Class that we can't have. Hence we'll most likely stick with providing our own version of java.lang.Class. David Holmes ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
RE: Query on stacktrace management logic
Jeroen Frijters wrote: The reference implementation of VMClass will not have any instance members, but VMs might choose to add instance state. However, after thinking about it some more, I think it would be better to just add an instance member to Class, called vmState (or whatever) of type Object. That is more flexible (at the cost of additional downcasts). The only overhead for you is the unused vmState reference field in each Class instance. This sounds like a reasonable approach to me too. Jikes RVM currently uses its own implementation of java.lang.Class, but we might be able to switch over to something like this. Having the vmstate be of type Object having VMClass be all static methods will be easier for us to migrate to than the current design. --dave___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Re: Query on stacktrace management logic
--On Sonntag, 7. März 2004 16:02 +0100 Chris Gray [EMAIL PROTECTED] wrote: On Thursday 04 March 2004 09:01, Jeroen Frijters wrote: David Holmes wrote: class Class is the first class that must be initialized [...] Given the wide variety of VMs that use Classpath, I'd be careful with statements like these. For almost every such assumption there will be a VM for which it isn't true. Amen. Wonka [doesn't use Classbath [yet], but] currently loads five other classes before java.lang.Class; java.lang.Object, java.lang.Cloneable, java.lang.Serializable, java.lang.Throwable, and the mysterious array class. You don't need java.lang.String from the beginning? Jaos is more exigent: * java.lang.Object * java.lang.String (also initialized) * java.lang.RuntimeException * java.lang.NullPointerException * java.lang.ClassCastException * java.lang.ArrayOutOfBoundariesException * java.lang.OutOfMemoryException * java.io.IOException * java.lang.AbstractMethodException * java.lang.Throwable (also initialized) * java.lang.StackTraceElement (also initialized) * java.lang.VMThrowable (also initialized) * java.lang.Thread (also initialized) * java.lang.ThreadGroup (also initialized) * java.lang.System (also initialized) And obviously, many other follow implicitly when a class is initialized. You may ask why so many classes? Well, there are mainly two reasons. First, I try to use as much java code as possible (I'm lazy), thus parts of the JVM rely on the code in the libraries. A beautiful example are threads, which rely on the Runnable interface: during the first implementation of Jaos, the Oberon language didn't have interfaces, thus the threads where started by invoking the Java code in java.lang.Thread; only later I did integrate Jaos interface support in the Oberon Kernel and added them to the language :-) . Of course, some functions must be duplicated for bootstrap purposes, because they are needed before they become available. Second, the exceptions are handled by Oberon's exception handler, which is not able to load classes. All Exceptions that are generated by the compiler or the CPU as interrupts must be already available in Throwable. And obviously Throwable, StackTraceElement, and VMThrowable. -Patrik ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Re: Query on stacktrace management logic
On Saturday 13 March 2004 10:13, Patrik Reali wrote: --On Sonntag, 7. März 2004 16:02 +0100 Chris Gray [EMAIL PROTECTED] wrote: On Thursday 04 March 2004 09:01, Jeroen Frijters wrote: David Holmes wrote: class Class is the first class that must be initialized [...] Given the wide variety of VMs that use Classpath, I'd be careful with statements like these. For almost every such assumption there will be a VM for which it isn't true. Amen. Wonka [doesn't use Classbath [yet], but] currently loads five other classes before java.lang.Class; java.lang.Object, java.lang.Cloneable, java.lang.Serializable, java.lang.Throwable, and the mysterious array class. You don't need java.lang.String from the beginning? No. Our java.lang.String is just a wrapper for a w_string, and the VM uses w_string's internally: e.g. a Utf8 Constant is stored as a pointer to a w_string. So java.lang.String currently gets loaded a bit later, as part of the core-classes.in code. (This code also generates a global variable(!) called clazzString, so that native code can very easily generate instances of String, etc.). Jaos is more exigent: * java.lang.Object * java.lang.String (also initialized) * java.lang.RuntimeException * java.lang.NullPointerException * java.lang.ClassCastException * java.lang.ArrayOutOfBoundariesException * java.lang.OutOfMemoryException * java.io.IOException * java.lang.AbstractMethodException * java.lang.Throwable (also initialized) * java.lang.StackTraceElement (also initialized) * java.lang.VMThrowable (also initialized) * java.lang.Thread (also initialized) * java.lang.ThreadGroup (also initialized) * java.lang.System (also initialized) And obviously, many other follow implicitly when a class is initialized. We also had rather a long list in the past, but the code was so ugly and so fragile that I set about reducing it. I prefer to keep special-case code to a minimum. You may ask why so many classes? Well, there are mainly two reasons. First, I try to use as much java code as possible (I'm lazy), thus parts of the JVM rely on the code in the libraries. A beautiful example are threads, which rely on the Runnable interface: during the first implementation of Jaos, the Oberon language didn't have interfaces, thus the threads where started by invoking the Java code in java.lang.Thread; only later I did integrate Jaos interface support in the Oberon Kernel and added them to the language :-) . Of course, some functions must be duplicated for bootstrap purposes, because they are needed before they become available. Yes, I like using Java code too. :) Currently we hack like hell to wrap up the first native thread in a java.lang.Thread, but the rest is fairly clean. This stuff will probably get a going-over soon when I do some work on JNI Activation, and I will be looking to use more Java not less. BTW there is another reason for duplicate code during bootstrap: you are often dealing with a more restricted case, and the execution time is reflected directly in the startup time for the VM. Initial class loading is a case in point. Second, the exceptions are handled by Oberon's exception handler, which is not able to load classes. All Exceptions that are generated by the compiler or the CPU as interrupts must be already available in Throwable. And obviously Throwable, StackTraceElement, and VMThrowable. We also used to pre-load all exception classes, once upon a time. But it was a helluva lot of stuff to be pre-loading, so now we only do it for a very few - basically the ones which can be thrown by the execution engine itself. So if the system class loader throws e.g. a FileNotFoundException we load that on the spot; if it also can't find FileNotFoundException.class then we just crash. :) What do you do if a class loaded by a user-defined class loader throws an exception which also has to be loaded by that user-defined class loader? Best wishes -- Chris Gray /k/ Embedded Java Solutions Embedded Mobile Java, OSGi http://www.kiffer.be/k/ [EMAIL PROTECTED] +32 3 216 0369 ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
RE: Query on stacktrace management logic
Since I seem to be the only one that actually wants a VMClass instance, maybe we can agree on a slightly different interface. How about keep a reference to a VMClass instance in Class, but not calling any instance methods on VMClass, but using static methods instead (always passing the Class reference along). I don't understand the purpose of holding a reference to an instance of a class that only has static methods invoked on it. What I don't want is to have a different VMClass instance per Class object. Cheers, David Holmes ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
RE: Query on stacktrace management logic
--On Samstag, 13. März 2004 01:57 +0100 Jeroen Frijters [EMAIL PROTECTED] wrote: David Holmes wrote: Since I seem to be the only one that actually wants a VMClass instance, maybe we can agree on a slightly different interface. How about keep a reference to a VMClass instance in Class, but not calling any instance methods on VMClass, but using static methods instead (always passing the Class reference along). I don't understand the purpose of holding a reference to an instance of a class that only has static methods invoked on it. The reference implementation of VMClass will not have any instance members, but VMs might choose to add instance state. However, after thinking about it some more, I think it would be better to just add an instance member to Class, called vmState (or whatever) of type Object. That is more flexible (at the cost of additional downcasts). The only overhead for you is the unused vmState reference field in each Class instance. This seems a sound idea to me. I think the downcasts are not a big problem, as those calls are mostly used by the reflection, thus not time-critical. -Patrik ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
RE: Query on stacktrace management logic
Patrik Reali wrote: --On Freitag, 5. März 2004 08:13 +1000 David Holmes [EMAIL PROTECTED] wrote: As previously mentioned I think VMClass would be better defined as a helper with static methods rather than a shadow object attached to each Class instance. From my own experience, I can only agree with this... (not much to say, but I really wanted to say it) Since I seem to be the only one that actually wants a VMClass instance, maybe we can agree on a slightly different interface. How about keep a reference to a VMClass instance in Class, but not calling any instance methods on VMClass, but using static methods instead (always passing the Class reference along). Does that make sense? Regards, Jeroen ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
RE: Query on stacktrace management logic
David Holmes wrote: Since I seem to be the only one that actually wants a VMClass instance, maybe we can agree on a slightly different interface. How about keep a reference to a VMClass instance in Class, but not calling any instance methods on VMClass, but using static methods instead (always passing the Class reference along). I don't understand the purpose of holding a reference to an instance of a class that only has static methods invoked on it. The reference implementation of VMClass will not have any instance members, but VMs might choose to add instance state. However, after thinking about it some more, I think it would be better to just add an instance member to Class, called vmState (or whatever) of type Object. That is more flexible (at the cost of additional downcasts). The only overhead for you is the unused vmState reference field in each Class instance. Regards, Jeroen ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Re: Query on stacktrace management logic
On Thursday 04 March 2004 23:13, David Holmes wrote: David Holmes wrote: class Class is the first class that must be initialized [...] Jeroen Frijters replied: Given the wide variety of VMs that use Classpath, I'd be careful with statements like these. For almost every such assumption there will be a VM for which it isn't true. I meant in a JLS sense. Before you can initialize any class you must have a Class instance. Before you can have an instance of any class the class must be initialized. Therefore before you can initialize any class you must have initialized class Class. Oops my bad - I confused initialisation with loading. Then I see that Wonka actually initialises both ThreadGroup and Thread before Class, but OTOH I also know that the initialisation of our ThreadGroup and Thread are subject to special restrictions (because at that moment there is no current Thread, and no Class instance can be created). So David's statement is probably pretty close to being true in a practical sense, as well as a JLS sense. -- Chris Gray /k/ Embedded Java Solutions Embedded Mobile Java, OSGi http://www.kiffer.be/k/ [EMAIL PROTECTED] +32 3 216 0369 ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
RE: Query on stacktrace management logic
Chris Gray wrote: Oops my bad - I confused initialisation with loading. Then I see that Wonka actually initialises both ThreadGroup and Thread before Class, but OTOH I also know that the initialisation of our ThreadGroup and Thread are subject to special restrictions (because at that moment there is no current Thread, and no Class instance can be created). So David's statement is probably pretty close to being true in a practical sense, as well as a JLS sense. I don't necessarily agree or disagree, but I think it is important to keep an open mind about these things. On IKVM, I don't have any of the usual bootstrapping issues, so static initialization basically just happens whenever it is needed. For example, here is what my initialization looks like for Hello, World!: C:\ikvm -Xmethodtrace:clinit -Xtrace:*=off hello [11:56:26.75996 main] java.lang.System.clinit()V [11:56:26.76998 main] java.lang.Runtime.clinit()V [11:56:26.76998 main] java.lang.VMRuntime.clinit()V [11:56:26.77999 main] java.lang.StringHelper.clinit()V [11:56:26.80002 main] java.io.FileDescriptor.clinit()V [11:56:26.80002 main] java.io.PrintWriter.clinit()V [11:56:26.81004 main] gnu.java.io.EncodingManager.clinit()V [11:56:26.81004 main] java.lang.Class.clinit()V [11:56:26.88014 main] gnu.java.io.decode.Decoder.clinit()V [11:56:26.88014 main] gnu.java.io.decode.Decoder8859_1.clinit()V [11:56:26.90016 main] gnu.java.io.encode.Encoder.clinit()V [11:56:26.90016 main] gnu.java.io.encode.Encoder8859_1.clinit()V [11:56:26.90016 main] java.lang.ClassLoader.clinit()V [11:56:26.95024 main] java.io.File.clinit()V [11:56:26.95024 main] gnu.java.io.PlatformHelper.clinit()V [11:56:26.95024 main] java.lang.Character.clinit()V [11:56:26.95024 main] java.net.URL.clinit()V [11:56:26.96025 main] java.util.Locale.clinit()V [11:56:27.00031 main] java.net.URLClassLoader.clinit()V [11:56:27.00031 main] java.security.Policy.clinit()V [11:56:27.00031 main] gnu.java.security.provider.DefaultPolicy.clinit()V [11:56:27.01032 main] java.lang.ExceptionHelper.clinit()V [11:56:27.01032 main] java.util.WeakHashMap.clinit()V [11:56:27.02034 main] java.io.FilePermission.clinit()V [11:56:27.05038 main] java.lang.Number.clinit()V [11:56:27.05038 main] java.lang.Integer.clinit()V [11:56:27.19058 main] java.lang.Void.clinit()V Hello, World! [11:56:27.20060 ] java.lang.Thread.clinit()V [11:56:27.20060 ] java.lang.VMThread.clinit()V [11:56:27.21061 ] java.lang.ThreadGroup.clinit()V [11:56:27.21061 ] java.lang.ThreadLocal.clinit()V [11:56:27.21061 ] java.lang.InheritableThreadLocal.clinit()V [11:56:27.21061 ] java.util.Collections.clinit()V (As an aside, I just noticed the incredibly lame static initializer we have in Thread (to initialize a field to zero) and the fact that I have a static initializer in VMRuntime that isn't really needed.) Now having said all that, I'm certainly not opposed to making the unknownProtectionDomain initialization in Class lazy. In fact, it looks like a good optimization. Regards, Jeroen ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
RE: Query on stacktrace management logic
--On Freitag, 5. März 2004 08:13 +1000 David Holmes [EMAIL PROTECTED] wrote: As previously mentioned I think VMClass would be better defined as a helper with static methods rather than a shadow object attached to each Class instance. From my own experience, I can only agree with this... (not much to say, but I really wanted to say it) -Patrik ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Re: Query on stacktrace management logic
On Thursday 04 March 2004 09:01, Jeroen Frijters wrote: David Holmes wrote: class Class is the first class that must be initialized [...] Given the wide variety of VMs that use Classpath, I'd be careful with statements like these. For almost every such assumption there will be a VM for which it isn't true. Amen. Wonka [doesn't use Classbath [yet], but] currently loads five other classes before java.lang.Class; java.lang.Object, java.lang.Cloneable, java.lang.Serializable, java.lang.Throwable, and the mysterious array class. -- Chris Gray /k/ Embedded Java Solutions Embedded Mobile Java, OSGi http://www.kiffer.be/k/ [EMAIL PROTECTED] +32 3 216 0369 ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
RE: Query on stacktrace management logic
Hi, Don't forget about the Thread/VMThread split introduced in Classpath 0.07! Moving from 0.04 through to 0.07 I've had the same dilemma -- change the VM to go along with the changes or modify the classes. In the end, I've decided to stick with the split, mainly because of future maintenance issues. Hopefully at some point the VMFoo/Foo interface will become stable. I can then be pretty confident that no matter what changes are made in Classpath it should still work. If I modified the classes, on every release I'd need to check if any changes had been made that breaks JamVM, and do a merge if they had. Obviously the Foo classes should stabalise anyway so maybe it's pointless - it was a close call. Rob. Original Message Follows From: David Holmes [EMAIL PROTECTED] To: Archie Cobbs [EMAIL PROTECTED] CC: classpath [EMAIL PROTECTED] Subject: RE: Query on stacktrace management logic Date: Wed, 3 Mar 2004 15:14:01 +1000 Archie Cobbs wrote: FYI, when I started working with Classpath I tried to respect the Foo-VMFoo split and not modify any Foo classes but eventually decided that it was too costly. E.g., every loaded class already has a Class object (I don't create them on-demand), but you double that number if you also have a VMClass object for each class. Ouch! I hadn't seen the VMClass split as we're still on 0.05. I have to agree there is no way I will use this version of things. Class is pretty much guaranteed to be VM specific. I can see the benefit of having the class initialization process spelt out in VMClass, but I'd be inclined to use VMClass as a helper, with static methods that take a Class instance, rather than having a VMClass shadow per Class object. (Just like VMClassloader is a helper and there is not a VMClassloader per Classloader). Whilst on the subject of class Class, I've mentioned before that it really should not have any static initialization in it. class Class is the first class that must be initialized and trying to set up protection domains as the first thing the VM does seems implausible to me. At a minimum you have defer processing of Class's clinit until later in the bootstrapping process. We moved that code into a method for lazy initialization later in the bootstrap process. Cheers, David Holmes ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath _ It's fast, it's easy and it's free. Get MSN Messenger today! http://www.msn.co.uk/messenger ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
RE: Query on stacktrace management logic
Robert Lougher wrote: Don't forget about the Thread/VMThread split introduced in Classpath 0.07! Moving from 0.04 through to 0.07 I've had the same dilemma -- change the VM to go along with the changes or modify the classes. And the Runtime/VMRuntime split. We have to use our own Thread for a number of reasons so I won't be utilising that split - but I'm also not concerned about future changes in the Thread class, so merging isn't an issue. The Runtime split probably mirrors a split we already had, so now I guess I'll just have to rename my local class (JavaVirtualMachine) to become VMRuntime otherwise there are too many levels of redirection. Though again I'm not concerned with merging in this case. The other problem with customising classes rather than using the Classpath version is remebering to delete them from the Classpath source tree so that things compile properly. :) Cheers, David Holmes ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Re: Query on stacktrace management logic
David Holmes wrote: Whilst on the subject of class Class, I've mentioned before that it really should not have any static initialization in it. class Class is the first It definitely makes things more interesting. FWIW here's how JC handles it.. http://jcvm.sourceforge.net/doc/jc.html#Bootstrap%20Process -Archie __ Archie Cobbs *CTO, Awarix* http://www.awarix.com ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
RE: Query on stacktrace management logic
Archie Cobbs wrote: FYI, when I started working with Classpath I tried to respect the Foo-VMFoo split and not modify any Foo classes but eventually decided that it was too costly. E.g., every loaded class already has a Class object (I don't create them on-demand), but you double that number if you also have a VMClass object for each class. Ouch! I hadn't seen the VMClass split as we're still on 0.05. I have to agree there is no way I will use this version of things. Class is pretty much guaranteed to be VM specific. I can see the benefit of having the class initialization process spelt out in VMClass, but I'd be inclined to use VMClass as a helper, with static methods that take a Class instance, rather than having a VMClass shadow per Class object. (Just like VMClassloader is a helper and there is not a VMClassloader per Classloader). Whilst on the subject of class Class, I've mentioned before that it really should not have any static initialization in it. class Class is the first class that must be initialized and trying to set up protection domains as the first thing the VM does seems implausible to me. At a minimum you have defer processing of Class's clinit until later in the bootstrapping process. We moved that code into a method for lazy initialization later in the bootstrap process. Cheers, David Holmes ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Re: Query on stacktrace management logic
David Holmes wrote: Chris Gray wrote: I found one gotcha with using a pre-allocated OutOfMemoryError : if several threads throw OOME at the same time, the stack traces can get mixed up. This is one of our issues too. Here's our approach: if (VM.debugOOM || Options.verbose = 5) VM.sysWriteln(triggerCollection(): About to try \new OutOfMemoryError()\); MM_Interface.emergencyGrowHeap(512 * (1 10)); // 512K should be plenty to make an exn OutOfMemoryError oome = new OutOfMemoryError(); MM_Interface.emergencyGrowHeap(- (512 * (1 10))); if (VM.debugOOM || Options.verbose = 5) VM.sysWriteln(triggerCollection(): Allocated the new OutOfMemoryError().); throw oome; Of course, we have the advantage of not targeting the embedded space. --Steve Augart -- Steven Augart Jikes RVM, open source Research Virtual Machine: http://oss.software.ibm.com/jikesrvm Office: +1 914/784-6743 T.J. Watson Research Center, IBM ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
RE: Query on stacktrace management logic
Steven Augart wrote: In Jikes RVM, we override a few of Classpath's implementations; we have our own Object.java and (relevant to your case) Throwable.java, for instance. Hope this helps. The biggest ugliness here is that the version the rest of Classpath sees is not the same one as will actually be loaded at run time. One day this will probably bite us when Classpath adds some new (Java 1.5 or 1.6?) method or field to a class we override before we do it ourselves, and some other Classpath class uses the new method or field. Right. We try to abide by the XXX vs. VMXXX split and not customise any class that isn't specifically listed as being VM-specific. So far we've only had to override System to change the initialization sequence, but the further we get the more classes we want to be able to customise outside the normal set. :( This isn't great from a maintenance perspective as I'd like to be able to just 'cvs up' the latest classpath and having everything just work. That said, our support of RTSJ will mandate a number of library changes to make more of the core classes async exception safe in the face of the potential memory access errors that the RTSJ scoped-memory and no-heap threads introduce. We do ensure that we compile all the classpath classes against our customised versions though, to ensure compatability. And I should point out that at present we only use a subset of Classpath. Cheers, David Holmes ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Re: Query on stacktrace management logic
On Monday 01 March 2004 23:38, David Holmes wrote: Chris Gray wrote: I found one gotcha with using a pre-allocated OutOfMemoryError : if several threads throw OOME at the same time, the stack traces can get mixed up. This is one of our issues too. With no stacktrace you can share an OOME instance with no problem and require no runtime allocation. With a stacktrace you need at least a per-thread OOME and pre-allocated stacktrace space. As it stands our OOME does have a stacktrace but its created at system startup when running out of memory is not an issue - but of course the stacktrace is meaningless for any actual circumstance where the OOME is thrown. We encounter OOME much more often than others might because we are dealing with RTSJ scoped memory areas - which introduces some added twists to things. :) On the bright side, it does make it more likely that the OOM problem will be confined to one thread. One OOME per thread, allocated at thread creation time, should be safe. Ensuring that one can always find memory somewhere to store a stack trace is left as an exercise for the reader (and the answer is likely to be VM-specific). Chris -- Chris Gray /k/ Embedded Java Solutions Embedded Mobile Java, OSGi http://www.kiffer.be/k/ [EMAIL PROTECTED] +32 3 216 0369 ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Re: Query on stacktrace management logic
Steven Augart wrote: I still need a hook to not get the stacktrace filled in for OutOfMemoryError - though perhaps I can do something without requiring allocation using a different approach. In Jikes RVM, we override a few of Classpath's implementations; we have our own Object.java and (relevant to your case) Throwable.java, for instance. Hope this helps. In JC I've taken the approach of keeping the last little bit of heap memory reserved for OOM exceptions. If an allocation fails, we set the out of memory flag for that thread, then throw an OOM. Subsequent allocations (while out of memory is set) are allowed to dip into the reserved memory. Once the exception is fully constructed, we reset the out of memory flag. Finally, there is one global stackless exception created at VM startup for each possible exception type that the VM itself throws. These are used as a last resort (this idea is from SableVM), where last resort means another exception of the same type is thrown while trying to create the first exception (i.e., recursively thrown). The biggest ugliness here is that the version the rest of Classpath sees is not the same one as will actually be loaded at run time. One day this will probably bite us when Classpath adds some new (Java 1.5 or 1.6?) method or field to a class we override before we do it ourselves, and some other Classpath class uses the new method or field. I've overridden a few of the non VMXXX classses and JC is installed as an overlay on top of a stock classpath installation. This means that the bootstrap classpath must always include jc.zip before glibj.zip, but on the positive side upgrading is easy. FYI, when I started working with Classpath I tried to respect the Foo-VMFoo split and not modify any Foo classes but eventually decided that it was too costly. E.g., every loaded class already has a Class object (I don't create them on-demand), but you double that number if you also have a VMClass object for each class. Fortunately with Classpath it's easy to go either way as things are pretty well documented. -Archie __ Archie Cobbs *CTO, Awarix* http://www.awarix.com ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Re: Query on stacktrace management logic
Hi, we also have a preallocated OutOfMemoryException with I think speace for about 20 stack frames in our internal representation. To throw this exception from the native code (where memory allocation ocurres) we use a function call that fills in the stack trace. Further we have the printStackTrace-Method overwritten to print the internal representation without further memory allocation. The resulting stack trace looks somewhat different than a regular stack trace, but it helps in many cases. ingo Robert Lougher wrote: Well, if it's of any interest, JamVM takes advantage of this. When VMThrowable.fillInStackTrace() is called I store the backtrace in a compact, internal format. Then, if and when getStackTrace() is called I convert this into StackTraceElements. Remember, unless you do something like printStackTrace in your catch block the StackTraceElements will never be needed. Creating them up front will greatly increase the cost of throwing/catching exceptions as Andrew stated. As to your point about out of memory. Surely you _want_ the stacktrace if it all possible? You may not be able to satisfy an allocation request but still be able to construct an OutOfMemoryException. If you use the scheme above, constructing the backtrace shouldn't use much memory. If the stacktrace is printed, _lots_ of memory will be required but by this stage it's been caught, (or more likely printed as an uncaught exception) so lots of frames have been popped, enabling lots of memory to be collected. If we can't construct an OutOfMemoryException, as a last resort, JamVM throws an empty OutOfMemoryException pre-allocated at VM startup. Hope this helps, Rob. P.S. What is your system? Original Message Follows From: David Holmes [EMAIL PROTECTED] To: Andrew Haley [EMAIL PROTECTED] CC: classpath [EMAIL PROTECTED] Subject: RE: Query on stacktrace management logic Date: Sat, 28 Feb 2004 10:59:01 +1000 Andrew Haley wrote: Well consider what happens in a VM. VMThrowable.fillInStackTrace() is very fast -- it's just a chain of addresses. VMThrowable.getStackTrace() is very slow, because it has to convert all those addresses into StackTraceElements. I suspect that you can get the trace for the whole stack in less time than it takes to create a single StackTraceElement. For this reason, the vmState is stored and lazily converted to a StackTraceElement[]. Thanks - I see now. Unfortunately in our system (at present) this is not the case. But now I have an idea of how to change that. I still need a hook to not get the stacktrace filled in for OutOfMemoryError - though perhaps I can do something without requiring allocation using a different approach. Thanks again. David Holmes ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath _ Express yourself with cool new emoticons http://www.msn.co.uk/specials/myemo ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Re: Query on stacktrace management logic
Hi all, I found one gotcha with using a pre-allocated OutOfMemoryError : if several threads throw OOME at the same time, the stack traces can get mixed up. So thread A creates a structure, thread B overwrites A's pointer, and then whatever happens next will be bad news. This situation is less improbable than you might think, since if one thread encounters an OOM situation, all other threads should encounter one too. With some forms of co-operative multi-threading you may get away with it, but in the general pre-emptive case you could be living dangerously. -- Chris Gray /k/ Embedded Java Solutions Embedded Mobile Java, OSGi http://www.kiffer.be/k/ [EMAIL PROTECTED] +32 3 216 0369 ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
RE: Query on stacktrace management logic
Chris Gray wrote: I found one gotcha with using a pre-allocated OutOfMemoryError : if several threads throw OOME at the same time, the stack traces can get mixed up. This is one of our issues too. With no stacktrace you can share an OOME instance with no problem and require no runtime allocation. With a stacktrace you need at least a per-thread OOME and pre-allocated stacktrace space. As it stands our OOME does have a stacktrace but its created at system startup when running out of memory is not an issue - but of course the stacktrace is meaningless for any actual circumstance where the OOME is thrown. We encounter OOME much more often than others might because we are dealing with RTSJ scoped memory areas - which introduces some added twists to things. :) David Holmes ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
RE: Query on stacktrace management logic
Well, if it's of any interest, JamVM takes advantage of this. When VMThrowable.fillInStackTrace() is called I store the backtrace in a compact, internal format. Then, if and when getStackTrace() is called I convert this into StackTraceElements. Remember, unless you do something like printStackTrace in your catch block the StackTraceElements will never be needed. Creating them up front will greatly increase the cost of throwing/catching exceptions as Andrew stated. As to your point about out of memory. Surely you _want_ the stacktrace if it all possible? You may not be able to satisfy an allocation request but still be able to construct an OutOfMemoryException. If you use the scheme above, constructing the backtrace shouldn't use much memory. If the stacktrace is printed, _lots_ of memory will be required but by this stage it's been caught, (or more likely printed as an uncaught exception) so lots of frames have been popped, enabling lots of memory to be collected. If we can't construct an OutOfMemoryException, as a last resort, JamVM throws an empty OutOfMemoryException pre-allocated at VM startup. Hope this helps, Rob. P.S. What is your system? Original Message Follows From: David Holmes [EMAIL PROTECTED] To: Andrew Haley [EMAIL PROTECTED] CC: classpath [EMAIL PROTECTED] Subject: RE: Query on stacktrace management logic Date: Sat, 28 Feb 2004 10:59:01 +1000 Andrew Haley wrote: Well consider what happens in a VM. VMThrowable.fillInStackTrace() is very fast -- it's just a chain of addresses. VMThrowable.getStackTrace() is very slow, because it has to convert all those addresses into StackTraceElements. I suspect that you can get the trace for the whole stack in less time than it takes to create a single StackTraceElement. For this reason, the vmState is stored and lazily converted to a StackTraceElement[]. Thanks - I see now. Unfortunately in our system (at present) this is not the case. But now I have an idea of how to change that. I still need a hook to not get the stacktrace filled in for OutOfMemoryError - though perhaps I can do something without requiring allocation using a different approach. Thanks again. David Holmes ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath _ Express yourself with cool new emoticons http://www.msn.co.uk/specials/myemo ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Query on stacktrace management logic
David Holmes writes: I'm somewhat baffled why Throwable's stacktrace management is implemented like this: private transient VMThrowable vmState; private StackTraceElement[] stackTrace; public Throwable fillInStackTrace() { vmState = VMThrowable.fillInStackTrace(this); stackTrace = null; // Should be regenerated when used. return this; } public StackTraceElement[] getStackTrace() { if (stackTrace == null) if (vmState == null) stackTrace = new StackTraceElement[0]; else { stackTrace = vmState.getStackTrace(this); vmState = null; // No longer needed } return stackTrace; } Rather than the much simpler: private StackTraceElement[] stackTrace; public Throwable fillInStackTrace() { stackTrace = VMThrowable.fillInStackTrace(this).getStackTrace(this); return this; } public StackTraceElement[] getStackTrace() { return stackTrace; } Well consider what happens in a VM. VMThrowable.fillInStackTrace() is very fast -- it's just a chain of addresses. VMThrowable.getStackTrace() is very slow, because it has to convert all those addresses into StackTraceElements. I suspect that you can get the trace for the whole stack in less time than it takes to create a single StackTraceElement. For this reason, the vmState is stored and lazily converted to a StackTraceElement[]. All this assumes a particular VM design, of course, but I don't think it's atypical. Andrew. ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
RE: Query on stacktrace management logic
Andrew Haley wrote: Well consider what happens in a VM. VMThrowable.fillInStackTrace() is very fast -- it's just a chain of addresses. VMThrowable.getStackTrace() is very slow, because it has to convert all those addresses into StackTraceElements. I suspect that you can get the trace for the whole stack in less time than it takes to create a single StackTraceElement. For this reason, the vmState is stored and lazily converted to a StackTraceElement[]. Thanks - I see now. Unfortunately in our system (at present) this is not the case. But now I have an idea of how to change that. I still need a hook to not get the stacktrace filled in for OutOfMemoryError - though perhaps I can do something without requiring allocation using a different approach. Thanks again. David Holmes ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Query on stacktrace management logic
Hello all, I'm somewhat baffled why Throwable's stacktrace management is implemented like this: private transient VMThrowable vmState; private StackTraceElement[] stackTrace; public Throwable fillInStackTrace() { vmState = VMThrowable.fillInStackTrace(this); stackTrace = null; // Should be regenerated when used. return this; } public StackTraceElement[] getStackTrace() { if (stackTrace == null) if (vmState == null) stackTrace = new StackTraceElement[0]; else { stackTrace = vmState.getStackTrace(this); vmState = null; // No longer needed } return stackTrace; } Rather than the much simpler: private StackTraceElement[] stackTrace; public Throwable fillInStackTrace() { stackTrace = VMThrowable.fillInStackTrace(this).getStackTrace(this); return this; } public StackTraceElement[] getStackTrace() { return stackTrace; } Give that VMThrowable guarantees to return a non-null array if there is no stack trace, and given that fillinStackTrace is called at construction, this would seem adequate. What did I miss? The reason this came up is that I'm looking for a way to construct throwables (specifically certain instances of OutOfMemoryError) without having the stacktrace filled in. I can obviously hack Throwable but I'd prefer to deal with this only through VMThrowable if possible - but it's not looking possible. I need to add a private constructor to Throwable that doesn't do fillInstackTrace by default, which I can then call from the VM. Any insights appreciated. :) Cheers, David Holmes ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath