Title: [194400] trunk/Source/_javascript_Core
Revision
194400
Author
[email protected]
Date
2015-12-23 15:45:17 -0800 (Wed, 23 Dec 2015)

Log 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):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (194399 => 194400)


--- trunk/Source/_javascript_Core/ChangeLog	2015-12-23 23:31:44 UTC (rev 194399)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-12-23 23:45:17 UTC (rev 194400)
@@ -1,3 +1,20 @@
+2015-12-23  Keith Miller  <[email protected]>
+
+        [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):
+
 2015-12-23  Andy VanWagoner  <[email protected]>
 
         [INTL] Implement DateTime Format Functions

Modified: trunk/Source/_javascript_Core/jit/Repatch.cpp (194399 => 194400)


--- trunk/Source/_javascript_Core/jit/Repatch.cpp	2015-12-23 23:31:44 UTC (rev 194399)
+++ trunk/Source/_javascript_Core/jit/Repatch.cpp	2015-12-23 23:45:17 UTC (rev 194400)
@@ -224,31 +224,19 @@
     VM& vm = exec->vm();
 
     std::unique_ptr<AccessCase> newCase;
-    JSFunction* getter = nullptr;
-    ObjectPropertyConditionSet conditionSet;
-    JSCell* baseCell = baseValue.asCell();
-    Structure* structure = baseCell->structure(vm);
 
-    if (slot.isCacheableGetter())
-        getter = jsDynamicCast<JSFunction*>(slot.getterSetter()->getter());
-
     if (isJSArray(baseValue) && propertyName == exec->propertyNames().length)
         newCase = AccessCase::getLength(vm, codeBlock, AccessCase::ArrayLength);
     else if (isJSString(baseValue) && propertyName == exec->propertyNames().length)
         newCase = AccessCase::getLength(vm, codeBlock, AccessCase::StringLength);
-    else if (getter && AccessCase::canEmitIntrinsicGetter(getter, structure)) {
-        if (slot.slotBase() != baseValue) {
-            conditionSet = generateConditionsForPrototypePropertyHit(vm, codeBlock->ownerExecutable(), exec, structure, slot.slotBase(), propertyName.impl());
-            if (!conditionSet.isValid())
-                return GiveUpOnCache;
-        }
-
-        newCase = AccessCase::getIntrinsic(vm, codeBlock, getter, slot.cachedOffset(), structure, conditionSet);
-
-    } else {
+    else {
         if (!slot.isCacheable() && !slot.isUnset())
             return GiveUpOnCache;
 
+        ObjectPropertyConditionSet conditionSet;
+        JSCell* baseCell = baseValue.asCell();
+        Structure* structure = baseCell->structure(vm);
+
         bool loadTargetFromProxy = false;
         if (baseCell->type() == PureForwardingProxyType) {
             baseValue = jsCast<JSProxy*>(baseCell)->target();
@@ -297,24 +285,32 @@
             
             if (!conditionSet.isValid())
                 return GiveUpOnCache;
-            
+
             offset = slot.isUnset() ? invalidOffset : conditionSet.slotBaseCondition().offset();
         }
 
-        AccessCase::AccessType type;
-        if (slot.isCacheableValue())
-            type = AccessCase::Load;
-        else if (slot.isUnset())
-            type = AccessCase::Miss;
-        else if (slot.isCacheableGetter())
-            type = AccessCase::Getter;
-        else
-            type = AccessCase::CustomGetter;
+        JSFunction* getter = nullptr;
+        if (slot.isCacheableGetter())
+            getter = jsDynamicCast<JSFunction*>(slot.getterSetter()->getter());
 
-        newCase = AccessCase::get(
-            vm, codeBlock, type, offset, structure, conditionSet, loadTargetFromProxy,
-            slot.watchpointSet(), slot.isCacheableCustom() ? slot.customGetter() : nullptr,
-            slot.isCacheableCustom() ? slot.slotBase() : nullptr);
+        if (!loadTargetFromProxy && getter && AccessCase::canEmitIntrinsicGetter(getter, structure))
+            newCase = AccessCase::getIntrinsic(vm, codeBlock, getter, slot.cachedOffset(), structure, conditionSet);
+        else {
+            AccessCase::AccessType type;
+            if (slot.isCacheableValue())
+                type = AccessCase::Load;
+            else if (slot.isUnset())
+                type = AccessCase::Miss;
+            else if (slot.isCacheableGetter())
+                type = AccessCase::Getter;
+            else
+                type = AccessCase::CustomGetter;
+
+            newCase = AccessCase::get(
+                vm, codeBlock, type, offset, structure, conditionSet, loadTargetFromProxy,
+                slot.watchpointSet(), slot.isCacheableCustom() ? slot.customGetter() : nullptr,
+                slot.isCacheableCustom() ? slot.slotBase() : nullptr);
+        }
     }
 
     MacroAssemblerCodePtr codePtr =

Added: trunk/Source/_javascript_Core/tests/stress/typedarray-length-dictionary.js (0 => 194400)


--- trunk/Source/_javascript_Core/tests/stress/typedarray-length-dictionary.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/typedarray-length-dictionary.js	2015-12-23 23:45:17 UTC (rev 194400)
@@ -0,0 +1,19 @@
+// This tests that we do not inline cache intrinsic getters when the base structure is a dictionary.
+
+foo = new Int32Array(10);
+
+function len() {
+    return foo.length;
+}
+noInline(len);
+
+foo.bar = 1;
+foo.baz = 2;
+delete foo.bar;
+
+for (i = 0; i < 1000; i++)
+    len()
+
+Object.defineProperty(foo, "length", { value: 1 });
+if (len() !== 1)
+    throw "bad result";
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to