From: David P G. <gr...@us...> - 2006-12-27 21:49:01
|
> > All seems fine up to this point. However when I run the > BootImageWriter I come across a problem. It seems that the > BootImageWriter writes out the values of static fields using the host > JDKs copy of classes. However the target rvm uses classpath libraries. > This is not a problem when the host and target vms use the same .class > file definitions. It is a problem when the host and target VMs have > static private fields with different semantics/value or type. > > I have just run across this problem with java.util.Stack. In the host > JVM there is a private static field RED that has a different type than > java.util.Stack.RED in classpath libraries. This of course makes the > whole process die. > > So what I am asking is what is the solution for this? One thing I can > think of is to *NEVER* set up any static data if it is part of java.* > or assigns the value of a field to something other than a > ConstantValue. Anything that does either of these two things is added > to a list of initializers that must run at boot. Another option is > mainting a list of classes that are never written out and/or another > list of classes where the initializers have to be re-run at boot. This is a general problem that we work around in one of four ways (roughly in this order): (1) Don't put the problem class in the bootimage; load it dynamically as part of VM booting. Often this doesn't apply, since we have to have the problem class in the bootimage in order to bootstrap (either directly, or because an instance of the class is reachable from a field of a class we do need to bootstrap). When this happens, we usually have to put the class in the bootimage and then fix the problem field's value later. (2) There's code in the BootImageWriter to handle some "well-known" static and instance fields where even though we can't use reflection to lookup the field's value in the host JVM, we know how to compute what the value is supposed to be for the GNU classpath libraries, so we just write out the right thing. (3) We run the class initializer of the class during VM booting. This fixes static fields, but doesn't help if the problem field is an instance field. (4) We write special-case code in the boot sequence that whacks the field to the proper value either at the Java level, or by using internal reflection (VM_Field.set*ValueUnchecked) if the field is final. This has only been done in a handful of cases when nothing else works (for example, only a subset of the static fields need to be reset and resetting them all is either undesirable or incorrect). One could also fine-tune the primordials list by intentionally chopping a dependency and not including some class A even though an instance of it is directly reachable from a static field of some class B that is being included in the bootimage. This forces you to load A dynamically and re-run B's static initializer during booting. Generally, this isn't the right thing to do since it slows down booting, but there have been a few cases in the past where we have done this because including A then forced the inclusion of C...Z and for one reason or another (usually another problematic static field) that wasn't desirable. I don't think we're currently doing this now, but I'm not positive that we aren't (one indication would be seeing what classes are dynamically loaded if you say 'rvm -verbose:class') -dave |