Skip to content
  • Philip Chimento's avatar
    object: Split ObjectPrototype from ObjectInstance · 4413e30d
    Philip Chimento authored
    This creates two separate classes, ObjectPrototype and ObjectInstance, so
    that we don't have to have a copy of prototype-only data in each
    ObjectInstance. This should save a lot of memory.
    
    There is one element common to both classes: a list of GClosures (for
    prototypes, these are vfuncs, and for instances, connected signals.)
    Since we can only create a JSClass with one private type, we use a common
    base class ObjectBase for that type. ObjectBase contains the list of
    closures and a means of distinguishing whether a particular ObjectBase
    pointer holds an ObjectInstance or ObjectPrototype. For this we use an
    ObjectPrototype pointer, which is null in ObjectPrototypes, and in
    ObjectInstances points to the associated prototype. (This scheme is
    similar to what we do in fundamental.cpp.)
    
    Both ObjectInstance and ObjectPrototype have an associated GObjectInfo
    and GType, but now these are stored only on the prototype.
    
    Note that we do not use RTTI and dynamic_cast<> because SpiderMonkey
    supports compiling both with and without RTTI. That's the reason for this
    unusual scheme with the ObjectPrototype pointer and the to_prototype() /
    to_instance() methods. dynamic_cast<> would certainly be cleaner and more
    readable, so that might be something to investigate in the future.
    
    This also allows moving the PropertyCache and FieldCache into
    ObjectPrototype, instead of keeping them as qdata on the GType.
    
    We now define separate memory counters for ObjectPrototype and
    ObjectInstance.
    
    On x86_64 with Clang, ObjectInstance was previously 128 bytes and is now
    112. ObjectPrototype was effectively 288 bytes (128 for ObjectInstance,
    plus 160 hidden bytes for the PropertyCache and FieldCache stored on the
    GType) and is now 208 bytes.
    
    Closes: #165
    4413e30d