Ignore:
Timestamp:
Jan 19, 2013, 1:47:45 PM (12 years ago)
Author:
[email protected]
Message:

Track inheritance structures in a side table, instead of using a private
name in each prototype
https://bugs.webkit.org/show_bug.cgi?id=107378

Reviewed by Sam Weinig and Phil Pizlo.

This is a step toward object size inference.

Using a side table frees us to use a more complex key (a pair of
prototype and expected inline capacity).

It also avoids ruining inline caches for prototypes. (Adding a new private
name for a new inline capacity would change the prototype's structure,
possibly firing watchpoints, making inline caches go polymorphic, and
generally causing us to have a bad time.)

  • CMakeLists.txt:
  • GNUmakefile.list.am:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Target.pri: Buildage.
  • runtime/ArrayPrototype.cpp:

(JSC::ArrayPrototype::finishCreation): Updated to use new side table API.

  • runtime/JSFunction.cpp:

(JSC::JSFunction::cacheInheritorID): Updated to use new side table API.

(JSC::JSFunction::visitChildren): Fixed a long-standing bug where JSFunction
forgot to visit one of its data members (m_cachedInheritorID). This
wasn't a user-visible problem before because JSFunction would always
visit its .prototype property, which visited its m_cachedInheritorID.
But now, function.prototype only weakly owns function.m_cachedInheritorID.

  • runtime/JSGlobalData.h:

(JSGlobalData): Added the map, taking care to make sure that its
destructor would run after the heap destructor.

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::reset): Updated to use new side table API.

  • runtime/JSObject.cpp:

(JSC::JSObject::notifyPresenceOfIndexedAccessors):
(JSC::JSObject::setPrototype):

  • runtime/JSObject.h:

(JSObject): Updated to use new side table API, and removed lots of code
that used to manage the per-object private name.

  • runtime/JSProxy.cpp:

(JSC::JSProxy::setTarget):

  • runtime/ObjectConstructor.cpp:

(JSC::objectConstructorCreate):

  • runtime/ObjectPrototype.cpp:

(JSC::ObjectPrototype::finishCreation): Updated to use new side table API.

  • runtime/PrototypeMap.cpp: Added.

(JSC):
(JSC::PrototypeMap::addPrototype):
(JSC::PrototypeMap::emptyObjectStructureForPrototype):

  • runtime/PrototypeMap.h: Added.

(PrototypeMap):
(JSC::PrototypeMap::isPrototype):
(JSC::PrototypeMap::clearEmptyObjectStructureForPrototype): New side table.
This is a simple weak map, mapping an object to the structure you should
use when inheriting from that object. (In future, inline capacity will
be a part of the mapping.)

I used two maps to preserve existing behavior that allowed us to speculate
about an object becoming a prototype, even if it wasn't one at the moment.
However, I suspect that behavior can be removed without harm.

  • runtime/WeakGCMap.h:

(JSC::WeakGCMap::contains):
(WeakGCMap): I would rate myself a 6 / 10 in C++.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/JSFunction.cpp

    r139541 r140259  
    109109Structure* JSFunction::cacheInheritorID(ExecState* exec)
    110110{
    111     JSValue prototype = get(exec, exec->globalData().propertyNames->prototype);
     111    JSGlobalData& globalData = exec->globalData();
     112    JSValue prototype = get(exec, globalData.propertyNames->prototype);
    112113    if (prototype.isObject())
    113         m_cachedInheritorID.set(exec->globalData(), this, asObject(prototype)->inheritorID(exec->globalData()));
     114        m_cachedInheritorID.set(globalData, this, globalData.prototypeMap.emptyObjectStructureForPrototype(asObject(prototype)));
    114115    else
    115         m_cachedInheritorID.set(exec->globalData(), this, globalObject()->emptyObjectStructure());
     116        m_cachedInheritorID.set(globalData, this, globalData.prototypeMap.emptyObjectStructureForPrototype(globalObject()->objectPrototype()));
    116117    return m_cachedInheritorID.get();
    117118}
     
    163164    visitor.append(&thisObject->m_scope);
    164165    visitor.append(&thisObject->m_executable);
     166    visitor.append(&thisObject->m_cachedInheritorID);
    165167}
    166168
Note: See TracChangeset for help on using the changeset viewer.