Changeset 245018 in webkit


Ignore:
Timestamp:
May 7, 2019 11:39:27 AM (5 years ago)
Author:
Tadeu Zagallo
Message:

tryCachePutByID should not crash if target offset changes
https://bugs.webkit.org/show_bug.cgi?id=197311
<rdar://problem/48033612>

Reviewed by Filip Pizlo.

JSTests:

Add a series of tests related tryCachePutByID. Two of these tests used to crash and were fixed
by this patch: cache-put-by-id-different-attributes.js and cache-put-by-id-different-offset.js

  • stress/cache-put-by-id-delete-prototype.js: Added.

(A.prototype.set y):
(A):
(B.prototype.set y):
(B):
(C):

  • stress/cache-put-by-id-different-proto.js: Added.

(A.prototype.set y):
(A):
(B1):
(B2.prototype.set y):
(B2):
(C):
(D):

  • stress/cache-put-by-id-different-attributes.js: Added.

(Foo):
(set x):

  • stress/cache-put-by-id-different-offset.js: Added.

(Foo):
(set x):

  • stress/cache-put-by-id-insert-prototype.js: Added.

(A.prototype.set y):
(A):
(C):

  • stress/cache-put-by-id-poly-proto.js: Added.

(Foo):
(set _):
(createBar.Bar):
(createBar):

Source/JavaScriptCore:

When tryCachePutID is called with a cacheable setter, if the target object where the setter was
found is still in the prototype chain and there's no poly protos in the chain, we use
generateConditionsForPrototypePropertyHit to validate that the target object remains the same.
It checks for the absence of the property in every object in the prototype chain from the base
down to the target object and checks that the property is still present in the target object. It
also bails if there are any uncacheable objects, proxies or dictionary objects in the prototype
chain. However, it does not consider two edge cases:

  • It asserts that the property should still be at the same offset in the target object, but this

assertion does not hold if the setter deletes properties of the object and causes the structure
to be flattened after the deletion. Instead of asserting, we just use the updated offset.

  • It does not check whether the new slot is also a setter, which leads to a crash in case it's not.
  • jit/Repatch.cpp:

(JSC::tryCachePutByID):

Location:
trunk
Files:
6 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r245017 r245018  
     12019-05-07  Tadeu Zagallo  <tzagallo@apple.com>
     2
     3        tryCachePutByID should not crash if target offset changes
     4        https://bugs.webkit.org/show_bug.cgi?id=197311
     5        <rdar://problem/48033612>
     6
     7        Reviewed by Filip Pizlo.
     8
     9        Add a series of tests related tryCachePutByID. Two of these tests used to crash and were fixed
     10        by this patch: `cache-put-by-id-different-attributes.js` and `cache-put-by-id-different-offset.js`
     11
     12        * stress/cache-put-by-id-delete-prototype.js: Added.
     13        (A.prototype.set y):
     14        (A):
     15        (B.prototype.set y):
     16        (B):
     17        (C):
     18        * stress/cache-put-by-id-different-__proto__.js: Added.
     19        (A.prototype.set y):
     20        (A):
     21        (B1):
     22        (B2.prototype.set y):
     23        (B2):
     24        (C):
     25        (D):
     26        * stress/cache-put-by-id-different-attributes.js: Added.
     27        (Foo):
     28        (set x):
     29        * stress/cache-put-by-id-different-offset.js: Added.
     30        (Foo):
     31        (set x):
     32        * stress/cache-put-by-id-insert-prototype.js: Added.
     33        (A.prototype.set y):
     34        (A):
     35        (C):
     36        * stress/cache-put-by-id-poly-proto.js: Added.
     37        (Foo):
     38        (set _):
     39        (createBar.Bar):
     40        (createBar):
     41
    1422019-05-07  Saam Barati  <sbarati@apple.com>
    243
  • trunk/Source/JavaScriptCore/ChangeLog

    r245017 r245018  
     12019-05-07  Tadeu Zagallo  <tzagallo@apple.com>
     2
     3        tryCachePutByID should not crash if target offset changes
     4        https://bugs.webkit.org/show_bug.cgi?id=197311
     5        <rdar://problem/48033612>
     6
     7        Reviewed by Filip Pizlo.
     8
     9        When tryCachePutID is called with a cacheable setter, if the target object where the setter was
     10        found is still in the prototype chain and there's no poly protos in the chain, we use
     11        generateConditionsForPrototypePropertyHit to validate that the target object remains the same.
     12        It checks for the absence of the property in every object in the prototype chain from the base
     13        down to the target object and checks that the property is still present in the target object. It
     14        also bails if there are any uncacheable objects, proxies or dictionary objects in the prototype
     15        chain. However, it does not consider two edge cases:
     16        - It asserts that the property should still be at the same offset in the target object, but this
     17        assertion does not hold if the setter deletes properties of the object and causes the structure
     18        to be flattened after the deletion. Instead of asserting, we just use the updated offset.
     19        - It does not check whether the new slot is also a setter, which leads to a crash in case it's not.
     20
     21        * jit/Repatch.cpp:
     22        (JSC::tryCachePutByID):
     23
    1242019-05-07  Saam Barati  <sbarati@apple.com>
    225
  • trunk/Source/JavaScriptCore/jit/Repatch.cpp

    r244764 r245018  
    577577                            return GiveUpOnCache;
    578578
    579                         PropertyOffset conditionSetOffset = conditionSet.slotBaseCondition().offset();
    580                         if (UNLIKELY(offset != conditionSetOffset))
    581                             CRASH_WITH_INFO(offset, conditionSetOffset, slot.base()->type(), baseCell->type(), conditionSet.size());
     579                        if (!(conditionSet.slotBaseCondition().attributes() & PropertyAttribute::Accessor))
     580                            return GiveUpOnCache;
     581
     582                        offset = conditionSet.slotBaseCondition().offset();
    582583                    }
    583584
Note: See TracChangeset for help on using the changeset viewer.