Title: [168335] trunk/Source/_javascript_Core
Revision
168335
Author
[email protected]
Date
2014-05-05 17:53:29 -0700 (Mon, 05 May 2014)

Log Message

Optimize GetByVal when subscript is a rope string.
<https://webkit.org/b/132590>

Use JSString::toIdentifier() in the various GetByVal implementations
to try and avoid allocating extra strings.

Added canUseFastGetOwnProperty() and wrap calls to fastGetOwnProperty()
in that, to avoid calling JSString::value() which always resolves ropes
into new strings and de-optimizes subsequent toIdentifier() calls.

My iMac says ~9% progression on Dromaeo/dom-attr.html

Reviewed by Phil Pizlo.

* dfg/DFGOperations.cpp:
* jit/JITOperations.cpp:
(JSC::getByVal):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::getByVal):
* runtime/JSCell.h:
* runtime/JSCellInlines.h:
(JSC::JSCell::fastGetOwnProperty):
(JSC::JSCell::canUseFastGetOwnProperty):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (168334 => 168335)


--- trunk/Source/_javascript_Core/ChangeLog	2014-05-06 00:47:33 UTC (rev 168334)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-05-06 00:53:29 UTC (rev 168335)
@@ -1,5 +1,31 @@
 2014-05-05  Andreas Kling  <[email protected]>
 
+        Optimize GetByVal when subscript is a rope string.
+        <https://webkit.org/b/132590>
+
+        Use JSString::toIdentifier() in the various GetByVal implementations
+        to try and avoid allocating extra strings.
+
+        Added canUseFastGetOwnProperty() and wrap calls to fastGetOwnProperty()
+        in that, to avoid calling JSString::value() which always resolves ropes
+        into new strings and de-optimizes subsequent toIdentifier() calls.
+
+        My iMac says ~9% progression on Dromaeo/dom-attr.html
+
+        Reviewed by Phil Pizlo.
+
+        * dfg/DFGOperations.cpp:
+        * jit/JITOperations.cpp:
+        (JSC::getByVal):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::getByVal):
+        * runtime/JSCell.h:
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::fastGetOwnProperty):
+        (JSC::JSCell::canUseFastGetOwnProperty):
+
+2014-05-05  Andreas Kling  <[email protected]>
+
         REGRESSION (r168256): ASSERTION FAILED: (buffer + m_length) == position loading vanityfair.com article.
         <https://webkit.org/b/168256>
         <rdar://problem/16816316>

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (168334 => 168335)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2014-05-06 00:47:33 UTC (rev 168334)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2014-05-06 00:53:29 UTC (rev 168335)
@@ -295,15 +295,18 @@
             if (propertyAsUInt32 == propertyAsDouble)
                 return getByVal(exec, base, propertyAsUInt32);
         } else if (property.isString()) {
-            if (JSValue result = base->fastGetOwnProperty(vm, asString(property)->value(exec)))
-                return JSValue::encode(result);
+            Structure& structure = *base->structure(vm);
+            if (JSCell::canUseFastGetOwnProperty(structure)) {
+                if (JSValue result = base->fastGetOwnProperty(vm, structure, asString(property)->value(exec)))
+                    return JSValue::encode(result);
+            }
         }
     }
 
     if (isName(property))
         return JSValue::encode(baseValue.get(exec, jsCast<NameInstance*>(property.asCell())->privateName()));
 
-    Identifier ident(exec, property.toString(exec)->value(exec));
+    Identifier ident = property.toString(exec)->toIdentifier(exec);
     return JSValue::encode(baseValue.get(exec, ident));
 }
 
@@ -322,14 +325,17 @@
         if (propertyAsUInt32 == propertyAsDouble)
             return getByVal(exec, base, propertyAsUInt32);
     } else if (property.isString()) {
-        if (JSValue result = base->fastGetOwnProperty(vm, asString(property)->value(exec)))
-            return JSValue::encode(result);
+        Structure& structure = *base->structure(vm);
+        if (JSCell::canUseFastGetOwnProperty(structure)) {
+            if (JSValue result = base->fastGetOwnProperty(vm, structure, asString(property)->value(exec)))
+                return JSValue::encode(result);
+        }
     }
 
     if (isName(property))
         return JSValue::encode(JSValue(base).get(exec, jsCast<NameInstance*>(property.asCell())->privateName()));
 
-    Identifier ident(exec, property.toString(exec)->value(exec));
+    Identifier ident = property.toString(exec)->toIdentifier(exec);
     return JSValue::encode(JSValue(base).get(exec, ident));
 }
 

Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (168334 => 168335)


--- trunk/Source/_javascript_Core/jit/JITOperations.cpp	2014-05-06 00:47:33 UTC (rev 168334)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp	2014-05-06 00:53:29 UTC (rev 168335)
@@ -1420,8 +1420,12 @@
 static JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript, ReturnAddressPtr returnAddress)
 {
     if (LIKELY(baseValue.isCell() && subscript.isString())) {
-        if (JSValue result = baseValue.asCell()->fastGetOwnProperty(exec->vm(), asString(subscript)->value(exec)))
-            return result;
+        VM& vm = exec->vm();
+        Structure& structure = *baseValue.asCell()->structure(vm);
+        if (JSCell::canUseFastGetOwnProperty(structure)) {
+            if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, asString(subscript)->value(exec)))
+                return result;
+        }
     }
 
     if (subscript.isUInt32()) {
@@ -1436,7 +1440,7 @@
     if (isName(subscript))
         return baseValue.get(exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
 
-    Identifier property(exec, subscript.toString(exec)->value(exec));
+    Identifier property = subscript.toString(exec)->toIdentifier(exec);
     return baseValue.get(exec, property);
 }
 
@@ -1518,7 +1522,7 @@
     } else if (isName(subscript))
         result = baseValue.get(exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
     else {
-        Identifier property(exec, subscript.toString(exec)->value(exec));
+        Identifier property = subscript.toString(exec)->toIdentifier(exec);
         result = baseValue.get(exec, property);
     }
 

Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (168334 => 168335)


--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp	2014-05-06 00:47:33 UTC (rev 168334)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp	2014-05-06 00:53:29 UTC (rev 168335)
@@ -715,8 +715,12 @@
 inline JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript)
 {
     if (LIKELY(baseValue.isCell() && subscript.isString())) {
-        if (JSValue result = baseValue.asCell()->fastGetOwnProperty(exec->vm(), asString(subscript)->value(exec)))
-            return result;
+        VM& vm = exec->vm();
+        Structure& structure = *baseValue.asCell()->structure(vm);
+        if (JSCell::canUseFastGetOwnProperty(structure)) {
+            if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, asString(subscript)->value(exec)))
+                return result;
+        }
     }
     
     if (subscript.isUInt32()) {
@@ -730,7 +734,7 @@
     if (isName(subscript))
         return baseValue.get(exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
     
-    Identifier property(exec, subscript.toString(exec)->value(exec));
+    Identifier property = subscript.toString(exec)->toIdentifier(exec);
     return baseValue.get(exec, property);
 }
 

Modified: trunk/Source/_javascript_Core/runtime/JSCell.h (168334 => 168335)


--- trunk/Source/_javascript_Core/runtime/JSCell.h	2014-05-06 00:47:33 UTC (rev 168334)
+++ trunk/Source/_javascript_Core/runtime/JSCell.h	2014-05-06 00:53:29 UTC (rev 168335)
@@ -144,7 +144,8 @@
     void zap() { *reinterpret_cast<uintptr_t**>(this) = 0; }
     bool isZapped() const { return !*reinterpret_cast<uintptr_t* const*>(this); }
 
-    JSValue fastGetOwnProperty(VM&, const String&);
+    static bool canUseFastGetOwnProperty(const Structure&);
+    JSValue fastGetOwnProperty(VM&, Structure&, const String&);
 
     enum GCData : uint8_t {
         Marked = 0,

Modified: trunk/Source/_javascript_Core/runtime/JSCellInlines.h (168334 => 168335)


--- trunk/Source/_javascript_Core/runtime/JSCellInlines.h	2014-05-06 00:47:33 UTC (rev 168334)
+++ trunk/Source/_javascript_Core/runtime/JSCellInlines.h	2014-05-06 00:53:29 UTC (rev 168335)
@@ -213,19 +213,22 @@
 // identifier. The first time we perform a property access with a given string, try
 // performing the property map lookup without forming an identifier. We detect this
 // case by checking whether the hash has yet been set for this string.
-ALWAYS_INLINE JSValue JSCell::fastGetOwnProperty(VM& vm, const String& name)
+ALWAYS_INLINE JSValue JSCell::fastGetOwnProperty(VM& vm, Structure& structure, const String& name)
 {
-    Structure& structure = *this->structure(vm);
-    if (!structure.typeInfo().overridesGetOwnPropertySlot() && !structure.hasGetterSetterProperties()) {
-        PropertyOffset offset = name.impl()->hasHash()
-            ? structure.get(vm, Identifier(&vm, name))
-            : structure.get(vm, name);
-        if (offset != invalidOffset)
-            return asObject(this)->locationForOffset(offset)->get();
-    }
+    ASSERT(canUseFastGetOwnProperty(vm));
+    PropertyOffset offset = name.impl()->hasHash()
+        ? structure.get(vm, Identifier(&vm, name))
+        : structure.get(vm, name);
+    if (offset != invalidOffset)
+        return asObject(this)->locationForOffset(offset)->get();
     return JSValue();
 }
 
+inline bool JSCell::canUseFastGetOwnProperty(const Structure& structure)
+{
+    return !structure.hasGetterSetterProperties() && !structure.typeInfo().overridesGetOwnPropertySlot();
+}
+
 inline bool JSCell::toBoolean(ExecState* exec) const
 {
     if (isString()) 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to