resolveConstants

Date view Thread view Subject view Author view

From: Godmar Back (gback@marker.cs.utah.edu)
Date: Tue Nov 17 1998 - 22:51:31 EST


 Alright, here's another issue. I'm sure all of you have noticed that
Kaffe is a lot more eager as far as the loading of classes is concerned.
The reason is that we call getClass on all classes in the constant pool
if a class is brought to the CSTATE_OK state, even if some classes are
never referenced. This means, for instance, that hotjava now fails
with a NoClassDefFoundError because of some javax/security/...X509 class. (*)

Here's the code:

--------------------------------------------------------------------------
/*
 * Initialise the constants.
 * First we make sure all the constant strings are converted to java strings.
 */
static
bool
resolveConstants(Hjava_lang_Class* class, errorInfo *einfo)
{
        int idx;
        constants* pool;
        bool success = true;
                
        lockMutex(class->centry);
                
        /* Scan constant pool and convert any constant strings into true
         * java strings.
         */
        pool = CLASS_CONSTANTS (class);
        for (idx = 0; idx < pool->size; idx++) {
                switch (pool->tags[idx]) {
                case CONSTANT_String:
                        pool->data[idx] = (ConstSlot)Utf8Const2JavaString(WORD2U
TF(pool->data[idx]));
                        pool->tags[idx] = CONSTANT_ResolvedString;
                        break;
                
? case CONSTANT_Class:
? if (getClass(idx, class, einfo) == 0) {
? success = false;
? goto done;
? }
? break;
?
                }
        }

done:
        unlockMutex(class->centry);
        return (success);
}
--------------------------------------------------------------------------

My question: is this really necessary/a good idea?
I tried omitting it, and things still seem to work just fine.
I believe it is not necessary because getClass will be invoked
once the class is actually needed.

What do you think?

        - Godmar

ps: as an aside, in Edouard's testcase, where you have

class Third extends DontExists
{
        static {
                new DontExists();
        }
}

(and there's no DontExists.class), what should Class.forName("Third")
throw? Sun throws "NoClassDefFoundError: DontExists."

This is what we throw if and only if we resolve eagerly in resolveConstants.
Otherwise, we throw ExceptionInInitializerError because the lack of
DontExists isn't noticed before the static initializer is invoked.
I believe this is correct (i.e., Sun is wrong).

Let's play this game some more.
What if the missing class sits in a path of code that's not taken?

class Third extends DontExists
{
        static {
                if ("X".equals("Y")) {
                        new DontExists();
                }
        }
}

In this case, Sun's correct in not complaining about anything.
Kaffe's interpreter, when not loading eagerly, will also do
just fine. Kaffe's jitter, unfortunately, will want to see the
class when jitting the NEW instruction.

The way to fix this is by emitting a soft_noclassdeffounderror
if the class is not found as opposed to throwing a error when jitting ---
just like soft_nosuchmethoderror is used. I guess we should put this
on the todo list.

(*) Note that earlier, when I wrongly threw ClassNotFoundException instead
of NoClassDefFoundError, this exception was simply caught, and hotjava
proceeded -- now it's an error and hotjava bails.


Date view Thread view Subject view Author view

This archive was generated by hypermail 2b29 : Sat Sep 23 2000 - 19:57:03 EDT