> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]]On Behalf Of
> Chris Toshok
>
> John Keiser wrote:
> >
> > First off, something fishy is going on ... I'm not getting this
> message on
> > the Japhar list, just Classpath.  Am I still on that list,
> after the recent
> > list changes?
> >
>
> hmm.. i got the message twice..  i'll ask vern if he's noticing anything
> funky.
>

Petter sent it from an unsubscribed address.  It took Vern a while to post
it, that's all.

>
> There is a way to get around having to load both libs in
> DLL_loadSystemLibraries (something I'd like to avoid as well.)  Japhar
> can load the classpath lib for the VM-independent portion of lang (or
> whichever package.)  static initializers in this package would get a
> property from java.lang.System (java.vm, which the JVM would initialize
> - 'japhar' for Japhar, and 'kaffe' for Kaffe.)  The VM independent
> portion would build up some lib name and load the additional native libs
> there (in the static initializers.)
>

I can deal with this.  I'll have to look into it for chicken-egg problems,
but at first glance it makes sense.  It means we'll have to formalize the
order in which classes get loaded.

> That way, we only have to make a minimal change to the
> DLL_loadSystemLibraries (if any) and classpath gets more flexibility for
> free.
>

There will still have to be changes to DLL_loadSystemLibraries(), though;
there are a lot less relevant libnative libs for Classpath than there are
for Sun.  Basically, there will have to be a big #ifndef FOR_CLASSPATH that
comments out unused libs that could conflict with Classpath's.  Not to
mention that they won't even be built when you use --enable-classpath.

> >
> > > Could Classpath change name on the following variables, to keep them
> > > the same as JDK?
> > >
> > >  java.lang.Class      declaringClass  -> clazz
> > >  java.lang.String     len             -> count
> > >                       str             -> value
> > >  java.lang.Throwable  message         -> detailMessage
> > >  java.lang.Thread     privateInfo     -> PrivateInfo
> > >
> >
> > I am wary of making any changes deliberately to give compatibility with
> > private and package-protected members and/or classes from Sun.  It is an
> > explicit step away from cleanroom.  I am not a lawyer, though.
> I think we
> > should defer to Paul and his FSF buddies on this one, or anyone
> who really
> > knows the law on this.
>
> i seriously doubt that you'll have any problem.  lesstif uses a much
> more aggressive strategy, and we have yet to have any problems with it.
>

OK.  I'll make the changes.  If we find a legal reason not to make them,
we'll back them out and go from there.

> > > BTW: One checks for NULL pointers _before_, not after it is used.
> > > Have a look at objects.c:cache_fields() and try again. :-)
> > >
> >
> > static void cache_fields(JNIEnv * env) {
> >   int i;
> >   class_clazzfile = find_class(env, "java/lang/Class");
> >   for(i=0;i<class_clazzfile->num_fields;i++) {
> >     if(!strcmp(class_clazzfile->fields[i]->name, "private_data"))
> >       private_data_field = (jfieldID)class_clazzfile->fields[i];
> >     else if(!strcmp(class_clazzfile->fields[i]->name, "superclass"))
> >       superclass_field = (jfieldID)class_clazzfile->fields[i];
> >     else if(!strcmp(class_clazzfile->fields[i]->name, "name"))
> >       name_field = (jfieldID)class_clazzfile->fields[i];
> >     else if(!strcmp(class_clazzfile->fields[i]->name, "signers"))
> >       signers_field = (jfieldID)class_clazzfile->fields[i];
> >   }
> >   assert(class_clazzfile != 0);
> >   assert(private_data_field != 0);
> >   assert(superclass_field != 0);
> >   assert(name_field != 0);
> >   assert(signers_field != 0);
> > }
> >
> > If you look in the caller: "if(private_data_field == NULL)
> > { cache_fields(); }".  The check happens in the caller, not the callee.
> > It's a silly optimization to avoid the method call.  I spent
> too much time
> > with my head in assembly code a few years back.  If you think
> it's better to
> > put it into the method, be my guest :)
>
> I think what petter is pointing out is the assert(class_clazzfile != 0);
> after many lines with "class_classfile->"
>

Well, if you look at the code, that's the only place it makes any sense.
The null check is there to make sure we actually found the field.  If you
did it anywhere inside the for loop, it wouldn't be done finding the field
yet.  That for loop is there because I couldn't find an internal
find_field(ClazzFile*,char*) function.  If there is one, I'd be happy to use
it instead, and it would look a little more like you expect.

> > > Why do you do the caching in objects.c, and are you sure it is save to
> > > cache this info?
> > >
> >
> > Well, it'd be best to cache it wherever you guys are caching
> the ClazzFile *
> > for Class, String and Object.  I just don't know where that is.
>  All field
> > and methodIDs that are used by the core should be cached somewhere.
>
> I agree with this, I just don't think they should be cached in the JVM.
>

(Before I talk about any of this, I'll make one thing clear: this is your
call.  If you don't want to cache the fields, don't cache the fields.  I am
just arguing for caching and a faster JVM.  Proper caching doesn't affect
functionality at all.  Whether this is proper caching is a definite possible
source of debate.)

The core I'm talking about *is* the JVM.  libruntime in particular, and
maybe jnistr.  The JVM sometimes has to use these methods and fields, as you
know.

The JVM needs to be as fast as possible at the core without sacrificing
robustness.  Caching is a part of that speed.  You don't really need to give
in to it now, but sometime you will have to, if only to be able to pass the
Sieve test :)

> > I do the caching because searching for these fields is very
> slow (a total of
> > 10 string compares) and I want speed in the JVM.  I don't mind
> if you want
> > to use find_class every time, I just think it's a waste of taxpayer CPU
> > cycles :)  It would also involve monitors, another thing I like
> to minimize,
> > for the same performance reasons.  Caching it with class,
> string and object
> > would be best.
>
> find_class is one thing - I don't have any problem with caching classes
> that have been loaded.  Checking for particular field names is another
> matter entirely.  Japhar doesn't do this (except in the fake array
> classes we generate and the fake Class field we create since we know
> what the offsets are.)
>

I don't understand: aren't the field offsets fixed for a particular class?
If it is safe to cache the class, then it should be safe to cache the field.
A jfieldID is supposed to work with the class and all its subclasses, so
there's no problem with using subclasses ... what could possibly be the
problem?

> I don't expect core classes to be changing all that often, but I would
> really like it if the same version of japhar could be used with multiple
> versions of classpath just by replacing the .zip and .so's.
>

How does caching them prevent this?  They get re-cached every time the VM
runs, so if the order changes, you're still fine.

If you're talking about minimizing the impact of field name changes, which
is a separate issue, one way to do that is by introducing private
constructors into Classpath, such as Class().

The other way you can minimize those changes is to add the ability to
associate native data with a class.  That will get rid of dependencies on
the names of fields in Class, Thread, Throwable (which will become a VM
interface class in the next rev), Field, Method and Constructor.  It will
also allow Japhar+Classpath to support >64bit machines.

String is the only one where there are strong dependencies on internal
structure.  You can probably get around these, but these are *strings*,
probably the most-used class in Java (except for Object itself), and you
need all the speed you can get.

> Japhar really shouldn't have to worry about field names in given classes
> -- all that should be dealt with in either java or native code within
> classpath.  There are perhaps a few sticky examples, but I'd really like
> to minimize the changes to japhar necessary to get classpath running.
>

I changed only those places where it's necessary.  Anyplace I could, I
removed the need for field names altogether, but there aren't many places
where I could.  The VM is dependent on the internal structure of the classes
in vm/reference.  Once you get to the point where you allow freeform native
pointers to be associated with some classes, you will be much less dependent
on internal structure.

I agree, Japhar *shouldn't* have to worry about field names in given
classes--but it's the sad fact of the matter.  I've minimized it any way I
can.

I am writing a document detailing the hooks between the VM and Classpath.
It is ready as a preliminary draft, but needs to be more compliant with
texinfo syntax before I'll put it up on the web.  There are a lot of places
where there just is no avoiding an non-public, non-protected dependency.
These places *increase* rather than decrease in 1.2, as my investigations
have been finding.

> Also, since the JDK1.2 apparently errors out when creating the second
> (or later VM's), caching fields in static variables inside native libs
> is legal (and, I suppose, desirable - I'm finally breaking down :)  This
> should obviate the need for the caching of fields in the VM.
>

The other factor that makes it legal to cache fields and classes is that a
native lib in 1.2 can only be loaded by a single ClassLoader, guaranteeing
that the classes will also be loaded by that same classloader.  With the
earlier restriction of only one VM, you're guaranteed that only one
VM+ClassLoader combination will be using the code, which is what you want.

--John Keiser

Reply via email to