#208 SUBCLASSES method does not work correclty

Lee Peedin
Classes (182)

In ooRexx 3.1.1 sending the SUBCLASSES message to a class object does not return its subclasses.


rexxtry say .relation~subclasses~items

returns 0 (has .bag as its subclass)


rexxtry say .object~subclasses~items

returns 0 (has quite a few direct subclasses)




  • Logged In: YES
    Originator: YES

    Will that be fixed for the refresh?

  • Lee Peedin
    Lee Peedin

    Logged In: YES
    Originator: NO

    Added Development List emails for retention in this tracker.

    Question posted by Lee Peedin to the list:
    Can someone possibly take a stab at explaining where the method "subclasses" comes from?

    Would I be correct in stating that "subclasses" returns an array of all classes that subclass the
    class in question?

    The code below shows that the .object class "honors" the method "subclasses". The documentation
    says: "The Object class is the root of the class hierarchy."; therefore, one would assume that is
    where the subclasses method would be defined.

    Bug 1603254 (2006-11-26) states the following:
    SUBCLASSES method does not work correclty Private: (?)
    In ooRexx 3.1.1 sending the SUBCLASSES message to a class object does not
    return its subclasses.


    rexxtry say .relation~subclasses~items

    returns 0 (has .bag as its subclass)


    rexxtry say .object~subclasses~items

    returns 0 (has quite a few direct subclasses)

    Obviously one part of this bug is no longer true (in 3.2) - .object reports 14 subclasses.

    What I am trying to do is:
    1) Determine where the subclasses method is defined
    2) Determine what it uses to report what classes subclass the class in question - is it simply some
    table that is not yet complete?.



    The Following Output Was Generated With ooRexxTry


    say .object~subclasses~items
    do i over .object~subclasses
    say i

    The EXECUTOR class
    The WindowObject class
    The VirtualKeyCodes class
    The WindowsClassesBase class
    The MessageExtensions class
    The DialogControl class
    The AdvancedControls class
    The DlgArea class
    The AnimatedButton class
    The WindowExtensions class
    The DialogExtensions class
    The DynamicDialog class
    The PlainBaseDialog class
    The WindowBase class


    Code Execution Complete

  • Lee Peedin
    Lee Peedin

    Logged In: YES
    Originator: NO

    Response by Rick McGuire:

    Ok, this one is going to be a seriously long winded explanation. The code to implement subclasses is in ClassClass.app, the getSubClasses() method. I sort of doubt you'll want to tackle trying to fix this one yourself once you learn why it doesn't work.

    The subclasses method is not completely broken...it's only partially broken. Your little experiment below returned 14 classes, but notice they're all ooDialog classes. Where's String, Array, Relation, etc? If you just run RexxTry without pulling in any other classes, you'll see that object initially reports 0 subclasses too.

    Implementing subclasses had some interesting wrinkles. Originally, the class objects just had a field containing an array of all the current subclasses of a class. Fairly simple, but it had one major flaw. Because the class object was maintaining a list of all of its subclasses, it meant that no class objects could ever be garbaged collected! They were getting pinned into memory by their immediate superclass. This created a huge memory leak, particularly for OS/2 where the workplace shell support kept the ooRexx interpreter perpetually active. Every time you ran a program that contained a class, that class would get added to the subclasses list, and when the program terminated, that class object would hang around. The next time you ran that program, a new copy of the class was loaded and added to the list. Eventually, you'd run out of memory, the interpreter would crash, and you generally had to reboot the system to clean things up.

    So, this problem was fixed by creating a special table in the garbage collector that got special treatment whenever a GC cycle was done. I gave Mark M a sort of lengthy explanation about how the mark-and-sweep mechanism worked last week, so I'll not repeat that now. The garbage collector gives the subclasses table special treatment when a GC cycle is run. During the initial mark phase of the GC cycle, the subclasses table is not included in the set of traced objects. Once the mark phase is complete, the subclasses table is scanned, and any objects stored in that table that were not marked as being live during the marking phase are now eligible for garbage collection. Those objects are removed from the table. This process allows classes to get garbage collected properly.

    Now for the reason this bug appears. During the build process, one of the build steps creates a file called "rexx.img". This is the ooRexx core image. When the image is created, the interpreter does a hand bootstrapping of all of the core classes, then essentially serializes ".environment", which saves all of the core classes to a file that can be quickly reloaded when the interpreter is in "normal" operation. Unfortunately, the subclasses table does not get saved as part of the serialization process. When the image gets reloaded, a fresh subclasses table gets built, and all additional classes that get loaded are included in the table, but the initial core classes do not.

    One approach to fixing this would be to have the image creation process also save the subclasses table. On the image restore, the new subclasses table would be initialized with a copy from the saved image. That would preserved the original subclasses information.

    In the 4.0 prototype, I came up with a different approach for this. Rather than rely on that special table, I created a more generalized solution by implementing a "WeakReference" class in the interpreter. This is similar to the Java WeakReference class. It allows you to get access to an item as long as some other object still contains a reference to it. The WeakReferences themselves do not mark objects as being referenced. This is essentially what the special subclasses table was doing, but the WeakReference approach has a lot more uses.

    Unfortunately, my WeakReference implementation didn't take into account the possibility that they might need to get saved in the ooRexx image, so I've got some thinking to do about how to solve that bit. I believe it's doable, but I wasn't planning on doing anything about that until I started pulling the WeakReference code back into trunk.


  • Rick McGuire
    Rick McGuire

    Logged In: YES
    Originator: NO

    Committed revision 1726.



Cancel   Add attachments