⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 194400 in webkit


Ignore:
Timestamp:
Dec 23, 2015, 3:45:17 PM (11 years ago)
Author:
keith_miller@apple.com
Message:

[JSC] Bugfix for intrinsic getters with dictionary structures.
https://bugs.webkit.org/show_bug.cgi?id=152538

Reviewed by Mark Lam.

Intrinsic getters did not check if an object was a dictionary. This meant, if a property on
the prototype chain of a dictionary was an intrinsic getter we would IC it. Later, if a
property is added to the dictionary the IC would still return the result of the intrinsic.
The fix is to no longer IC intrinsic getters if the base object is a dictionary.

  • jit/Repatch.cpp:

(JSC::tryCacheGetByID):

  • tests/stress/typedarray-length-dictionary.js: Added.

(len):

Location:
trunk/Source/JavaScriptCore
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r194395 r194400  
     12015-12-23  Keith Miller  <keith_miller@apple.com>
     2
     3        [JSC] Bugfix for intrinsic getters with dictionary structures.
     4        https://bugs.webkit.org/show_bug.cgi?id=152538
     5
     6        Reviewed by Mark Lam.
     7
     8        Intrinsic getters did not check if an object was a dictionary. This meant, if a property on
     9        the prototype chain of a dictionary was an intrinsic getter we would IC it. Later, if a
     10        property is added to the dictionary the IC would still return the result of the intrinsic.
     11        The fix is to no longer IC intrinsic getters if the base object is a dictionary.
     12
     13        * jit/Repatch.cpp:
     14        (JSC::tryCacheGetByID):
     15        * tests/stress/typedarray-length-dictionary.js: Added.
     16        (len):
     17
    1182015-12-23  Andy VanWagoner  <andy@instructure.com>
    219
  • trunk/Source/JavaScriptCore/jit/Repatch.cpp

    r192693 r194400  
    225225
    226226    std::unique_ptr<AccessCase> newCase;
    227     JSFunction* getter = nullptr;
    228     ObjectPropertyConditionSet conditionSet;
    229     JSCell* baseCell = baseValue.asCell();
    230     Structure* structure = baseCell->structure(vm);
    231 
    232     if (slot.isCacheableGetter())
    233         getter = jsDynamicCast<JSFunction*>(slot.getterSetter()->getter());
    234227
    235228    if (isJSArray(baseValue) && propertyName == exec->propertyNames().length)
     
    237230    else if (isJSString(baseValue) && propertyName == exec->propertyNames().length)
    238231        newCase = AccessCase::getLength(vm, codeBlock, AccessCase::StringLength);
    239     else if (getter && AccessCase::canEmitIntrinsicGetter(getter, structure)) {
    240         if (slot.slotBase() != baseValue) {
    241             conditionSet = generateConditionsForPrototypePropertyHit(vm, codeBlock->ownerExecutable(), exec, structure, slot.slotBase(), propertyName.impl());
    242             if (!conditionSet.isValid())
    243                 return GiveUpOnCache;
    244         }
    245 
    246         newCase = AccessCase::getIntrinsic(vm, codeBlock, getter, slot.cachedOffset(), structure, conditionSet);
    247 
    248     } else {
     232    else {
    249233        if (!slot.isCacheable() && !slot.isUnset())
    250234            return GiveUpOnCache;
     235
     236        ObjectPropertyConditionSet conditionSet;
     237        JSCell* baseCell = baseValue.asCell();
     238        Structure* structure = baseCell->structure(vm);
    251239
    252240        bool loadTargetFromProxy = false;
     
    298286            if (!conditionSet.isValid())
    299287                return GiveUpOnCache;
    300            
     288
    301289            offset = slot.isUnset() ? invalidOffset : conditionSet.slotBaseCondition().offset();
    302290        }
    303291
    304         AccessCase::AccessType type;
    305         if (slot.isCacheableValue())
    306             type = AccessCase::Load;
    307         else if (slot.isUnset())
    308             type = AccessCase::Miss;
    309         else if (slot.isCacheableGetter())
    310             type = AccessCase::Getter;
    311         else
    312             type = AccessCase::CustomGetter;
    313 
    314         newCase = AccessCase::get(
    315             vm, codeBlock, type, offset, structure, conditionSet, loadTargetFromProxy,
    316             slot.watchpointSet(), slot.isCacheableCustom() ? slot.customGetter() : nullptr,
    317             slot.isCacheableCustom() ? slot.slotBase() : nullptr);
     292        JSFunction* getter = nullptr;
     293        if (slot.isCacheableGetter())
     294            getter = jsDynamicCast<JSFunction*>(slot.getterSetter()->getter());
     295
     296        if (!loadTargetFromProxy && getter && AccessCase::canEmitIntrinsicGetter(getter, structure))
     297            newCase = AccessCase::getIntrinsic(vm, codeBlock, getter, slot.cachedOffset(), structure, conditionSet);
     298        else {
     299            AccessCase::AccessType type;
     300            if (slot.isCacheableValue())
     301                type = AccessCase::Load;
     302            else if (slot.isUnset())
     303                type = AccessCase::Miss;
     304            else if (slot.isCacheableGetter())
     305                type = AccessCase::Getter;
     306            else
     307                type = AccessCase::CustomGetter;
     308
     309            newCase = AccessCase::get(
     310                vm, codeBlock, type, offset, structure, conditionSet, loadTargetFromProxy,
     311                slot.watchpointSet(), slot.isCacheableCustom() ? slot.customGetter() : nullptr,
     312                slot.isCacheableCustom() ? slot.slotBase() : nullptr);
     313        }
    318314    }
    319315
Note: See TracChangeset for help on using the changeset viewer.