Ignore:
Timestamp:
Jun 11, 2014, 11:40:13 AM (11 years ago)
Author:
[email protected]
Message:

Some JSValue::get() micro-optimzations.
<https://webkit.org/b/133739>

Tighten some of the property lookup code to improve performance of the
eagerly reified prototype attributes:

  • Instead of converting the property name to an integer at every step in the prototype chain, move that to a separate pass at the end since it should be a rare case.
  • Cache the StructureIDTable in a local instead of fetching it from the Heap on every step.
  • Make fillCustomGetterPropertySlot inline. It was out-of-lined based on the assumption that clients would mostly be cacheable GetByIds, and it gets pretty hot (~1%) in GetByVal.
  • Pass the Structure directly to fillCustomGetterPropertySlot instead of refetching it from the StructureIDTable.

Reviewed by Geoff Garen.

  • runtime/JSObject.cpp:

(JSC::JSObject::fillCustomGetterPropertySlot): Deleted.

  • runtime/JSObject.h:

(JSC::JSObject::inlineGetOwnPropertySlot):
(JSC::JSObject::fillCustomGetterPropertySlot):
(JSC::JSObject::getOwnPropertySlot):
(JSC::JSObject::fastGetOwnPropertySlot):
(JSC::JSObject::getPropertySlot):
(JSC::JSObject::getOwnPropertySlotSlow): Deleted.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r169703 r169815  
    3232#include "CommonIdentifiers.h"
    3333#include "CopyWriteBarrier.h"
     34#include "CustomGetterSetter.h"
    3435#include "DeferGC.h"
    3536#include "Heap.h"
     
    958959    bool putDirectInternal(VM&, PropertyName, JSValue, unsigned attr, PutPropertySlot&, JSCell*);
    959960
    960     bool inlineGetOwnPropertySlot(ExecState*, VM&, Structure&, PropertyName, PropertySlot&);
     961    bool inlineGetOwnPropertySlot(VM&, Structure&, PropertyName, PropertySlot&);
    961962    JS_EXPORT_PRIVATE void fillGetterPropertySlot(PropertySlot&, JSValue, unsigned, PropertyOffset);
    962     JS_EXPORT_PRIVATE void fillCustomGetterPropertySlot(PropertySlot&, JSValue, unsigned);
     963    void fillCustomGetterPropertySlot(PropertySlot&, JSValue, unsigned, Structure&);
    963964
    964965    const HashTableValue* findPropertyHashEntry(VM&, PropertyName) const;
     
    973974    unsigned getNewVectorLength(unsigned desiredLength);
    974975
    975     bool getOwnPropertySlotSlow(ExecState*, PropertyName, PropertySlot&);
    976        
    977976    ArrayStorage* constructConvertedArrayStorageWithoutCopyingElements(VM&, unsigned neededLength);
    978977       
     
    12131212}
    12141213
    1215 ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, VM& vm, Structure& structure, PropertyName propertyName, PropertySlot& slot)
     1214ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(VM& vm, Structure& structure, PropertyName propertyName, PropertySlot& slot)
    12161215{
    12171216    unsigned attributes;
    12181217    JSCell* specific;
    12191218    PropertyOffset offset = structure.get(vm, propertyName, attributes, specific);
    1220     if (LIKELY(isValidOffset(offset))) {
    1221         JSValue value = getDirect(offset);
    1222         if (structure.hasGetterSetterProperties() && value.isGetterSetter())
    1223             fillGetterPropertySlot(slot, value, attributes, offset);
    1224         else if (structure.hasCustomGetterSetterProperties() && value.isCustomGetterSetter())
    1225             fillCustomGetterPropertySlot(slot, value, attributes);
    1226         else
    1227             slot.setValue(this, attributes, value, offset);
    1228         return true;
    1229     }
    1230 
    1231     return getOwnPropertySlotSlow(exec, propertyName, slot);
    1232 }
    1233 
    1234 inline bool JSObject::getOwnPropertySlotSlow(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
    1235 {
    1236     unsigned i = propertyName.asIndex();
    1237     if (i != PropertyName::NotAnIndex)
    1238         return getOwnPropertySlotByIndex(this, exec, i, slot);
    1239     return false;
     1219    if (!isValidOffset(offset))
     1220        return false;
     1221
     1222    JSValue value = getDirect(offset);
     1223    if (structure.hasGetterSetterProperties() && value.isGetterSetter())
     1224        fillGetterPropertySlot(slot, value, attributes, offset);
     1225    else if (structure.hasCustomGetterSetterProperties() && value.isCustomGetterSetter())
     1226        fillCustomGetterPropertySlot(slot, value, attributes, structure);
     1227    else
     1228        slot.setValue(this, attributes, value, offset);
     1229
     1230    return true;
     1231}
     1232
     1233ALWAYS_INLINE void JSObject::fillCustomGetterPropertySlot(PropertySlot& slot, JSValue customGetterSetter, unsigned attributes, Structure& structure)
     1234{
     1235    if (structure.isDictionary()) {
     1236        slot.setCustom(this, attributes, jsCast<CustomGetterSetter*>(customGetterSetter)->getter());
     1237        return;
     1238    }
     1239    slot.setCacheableCustom(this, attributes, jsCast<CustomGetterSetter*>(customGetterSetter)->getter());
    12401240}
    12411241
     
    12471247    VM& vm = exec->vm();
    12481248    Structure& structure = *object->structure(vm);
    1249     return object->inlineGetOwnPropertySlot(exec, vm, structure, propertyName, slot);
     1249    if (object->inlineGetOwnPropertySlot(vm, structure, propertyName, slot))
     1250        return true;
     1251    unsigned index = propertyName.asIndex();
     1252    if (index != PropertyName::NotAnIndex)
     1253        return getOwnPropertySlotByIndex(object, exec, index, slot);
     1254    return false;
    12501255}
    12511256
     
    12531258{
    12541259    if (!TypeInfo::overridesGetOwnPropertySlot(inlineTypeFlags()))
    1255         return asObject(this)->inlineGetOwnPropertySlot(exec, vm, structure, propertyName, slot);
     1260        return asObject(this)->inlineGetOwnPropertySlot(vm, structure, propertyName, slot);
    12561261    return structure.classInfo()->methodTable.getOwnPropertySlot(this, exec, propertyName, slot);
    12571262}
     
    12621267{
    12631268    VM& vm = exec->vm();
     1269    auto& structureIDTable = vm.heap.structureIDTable();
    12641270    JSObject* object = this;
    12651271    while (true) {
    1266         Structure& structure = *object->structure(vm);
     1272        Structure& structure = *structureIDTable.get(object->structureID());
    12671273        if (object->fastGetOwnPropertySlot(exec, vm, structure, propertyName, slot))
    12681274            return true;
    12691275        JSValue prototype = structure.storedPrototype();
    12701276        if (!prototype.isObject())
    1271             return false;
     1277            break;
    12721278        object = asObject(prototype);
    12731279    }
     1280
     1281    unsigned index = propertyName.asIndex();
     1282    if (index != PropertyName::NotAnIndex)
     1283        return getPropertySlot(exec, index, slot);
     1284    return false;
    12741285}
    12751286
     
    12771288{
    12781289    VM& vm = exec->vm();
     1290    auto& structureIDTable = vm.heap.structureIDTable();
    12791291    JSObject* object = this;
    12801292    while (true) {
    1281         Structure& structure = *object->structure(vm);
     1293        Structure& structure = *structureIDTable.get(object->structureID());
    12821294        if (structure.classInfo()->methodTable.getOwnPropertySlotByIndex(object, exec, propertyName, slot))
    12831295            return true;
Note: See TracChangeset for help on using the changeset viewer.