JavaScriptCore:
authormjs@apple.com <mjs@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 23 Sep 2008 07:46:55 +0000 (07:46 +0000)
committermjs@apple.com <mjs@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 23 Sep 2008 07:46:55 +0000 (07:46 +0000)
2008-09-23  Maciej Stachowiak  <mjs@apple.com>

        Reviewed by Darin.

        - speed up instanceof some more
        https://bugs.webkit.org/show_bug.cgi?id=20818

        ~2% speedup on EarleyBoyer

        The idea here is to record in the StructureID whether the class
        needs a special hasInstance or if it can use the normal logic from
        JSObject.

        Based on this I inlined the real work directly into
        cti_op_instanceof and put the fastest checks up front and the
        error handling at the end (so it should be fairly straightforward
        to split off the beginning to be inlined if desired).

        I only did this for CTI, not the bytecode interpreter.

        * API/JSCallbackObject.h:
        (JSC::JSCallbackObject::createStructureID):
        * ChangeLog:
        * VM/Machine.cpp:
        (JSC::Machine::cti_op_instanceof):
        * kjs/JSImmediate.h:
        (JSC::JSImmediate::isAnyImmediate):
        * kjs/TypeInfo.h:
        (JSC::TypeInfo::overridesHasInstance):
        (JSC::TypeInfo::flags):

WebCore:

2008-09-23  Maciej Stachowiak  <mjs@apple.com>

        Reviewed by Darin.

        - speed up instanceof some more
        https://bugs.webkit.org/show_bug.cgi?id=20818

        ~2% speedup on EarleyBoyer

        (WebCore updates.)

        * bindings/js/JSQuarantinedObjectWrapper.h:
        (WebCore::JSQuarantinedObjectWrapper::createStructureID):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@36802 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/API/JSCallbackObject.h
JavaScriptCore/ChangeLog
JavaScriptCore/VM/Machine.cpp
JavaScriptCore/kjs/JSImmediate.h
JavaScriptCore/kjs/TypeInfo.h
WebCore/ChangeLog
WebCore/bindings/js/JSQuarantinedObjectWrapper.h

index bc035f803abe5590d826b49eeb027b5914cb15e3..7f52c5fd1f761c8229a3228d5e2262472ccaa1a0 100644 (file)
@@ -50,7 +50,7 @@ public:
 
     static PassRefPtr<StructureID> createStructureID(JSValue* proto) 
     { 
-        return StructureID::create(proto, TypeInfo(ObjectType, ImplementsHasInstance)); 
+        return StructureID::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | OverridesHasInstance)); 
     }
 
 private:
index a47c25429d29edb59d0c51938b87342d6fa6f278..542deca74c1da24d343de78aae9dedab5bf9f687 100644 (file)
@@ -1,3 +1,34 @@
+2008-09-23  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Darin.
+
+        - speed up instanceof some more
+        https://bugs.webkit.org/show_bug.cgi?id=20818
+        
+        ~2% speedup on EarleyBoyer
+
+        The idea here is to record in the StructureID whether the class
+        needs a special hasInstance or if it can use the normal logic from
+        JSObject. 
+        
+        Based on this I inlined the real work directly into
+        cti_op_instanceof and put the fastest checks up front and the
+        error handling at the end (so it should be fairly straightforward
+        to split off the beginning to be inlined if desired).
+
+        I only did this for CTI, not the bytecode interpreter.
+        
+        * API/JSCallbackObject.h:
+        (JSC::JSCallbackObject::createStructureID):
+        * ChangeLog:
+        * VM/Machine.cpp:
+        (JSC::Machine::cti_op_instanceof):
+        * kjs/JSImmediate.h:
+        (JSC::JSImmediate::isAnyImmediate):
+        * kjs/TypeInfo.h:
+        (JSC::TypeInfo::overridesHasInstance):
+        (JSC::TypeInfo::flags):
+
 2008-09-22  Darin Adler  <darin@apple.com>
 
         Reviewed by Sam Weinig.
index 4f43f439d7562676e4731e31ad1bc382f7089537..7662fdddc257185d100c89385bf028cb69e0195c 100644 (file)
@@ -4292,8 +4292,37 @@ JSValue* Machine::cti_op_get_by_id_fail(CTI_ARGS)
 JSValue* Machine::cti_op_instanceof(CTI_ARGS)
 {
     ExecState* exec = ARG_exec;
+    JSValue* value = ARG_src1;
     JSValue* baseVal = ARG_src2;
+    JSValue* proto = ARG_src3;
 
+    if (UNLIKELY(JSImmediate::isAnyImmediate(value, baseVal, proto)))
+        goto slow_cases;
+
+    JSCell* valueCell = static_cast<JSCell*>(value);
+    JSCell* baseCell = static_cast<JSCell*>(baseVal);
+    JSCell* protoCell = static_cast<JSCell*>(proto);
+
+    if (UNLIKELY(!valueCell->isObject() | !baseCell->isObject() | !protoCell->isObject()))
+        goto slow_cases;
+
+    if (UNLIKELY((baseCell->structureID()->typeInfo().flags() & (ImplementsHasInstance | OverridesHasInstance)) != ImplementsHasInstance))
+        goto slow_cases;
+
+    JSObject* testPrototype = static_cast<JSObject*>(static_cast<JSObject*>(valueCell)->prototype());
+
+    if (testPrototype == proto)
+        return jsBoolean(true);
+
+    while (testPrototype != jsNull()) {
+        testPrototype = static_cast<JSObject*>(testPrototype->prototype());
+        if (testPrototype == proto)
+            return jsBoolean(true);
+    }
+
+    return jsBoolean(false);
+
+ slow_cases:     
     if (!baseVal->isObject()) {
         CodeBlock* codeBlock = ARG_codeBlock;
         ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(CTI_RETURN_ADDRESS));
@@ -4302,10 +4331,23 @@ JSValue* Machine::cti_op_instanceof(CTI_ARGS)
         VM_CHECK_EXCEPTION(JSValue*);
     }
 
-    JSObject* baseObj = static_cast<JSObject*>(baseVal);
-    JSValue* basePrototype = ARG_src3;
-    JSValue* result = jsBoolean(baseObj->structureID()->typeInfo().implementsHasInstance() ? baseObj->hasInstance(exec,  ARG_src1, basePrototype) : false);
+    baseCell = static_cast<JSCell*>(baseVal);
+    if (!baseCell->structureID()->typeInfo().implementsHasInstance())
+        return jsBoolean(false);
+
+    if (!proto->isObject()) {
+        throwError(exec, TypeError, "instanceof called on an object with an invalid prototype property.");
+        VM_CHECK_EXCEPTION(JSValue*);
+    }
+        
+    if (!value->isObject())
+        return jsBoolean(false);
+
+    ASSERT(baseCell->structureID()->typeInfo().implementsHasInstance());
+
+    JSValue* result = jsBoolean(static_cast<JSObject*>(baseCell)->hasInstance(exec, value, proto));
     VM_CHECK_EXCEPTION_AT_END();
+
     return result;
 }
 
index aabf2a0a5567d7b9055ebaaaf8030712aea2def0..23201d8f26394ee31d1d3e266b21a9bb3fccced5 100644 (file)
@@ -154,6 +154,11 @@ namespace JSC {
             return (reinterpret_cast<uintptr_t>(v1) | reinterpret_cast<uintptr_t>(v2)) & TagMask;
         }
 
+        static ALWAYS_INLINE bool isAnyImmediate(const JSValue* v1, const JSValue* v2, JSValue* v3)
+        {
+            return (reinterpret_cast<uintptr_t>(v1) | reinterpret_cast<uintptr_t>(v2) | reinterpret_cast<uintptr_t>(v3)) & TagMask;
+        }
+
         static ALWAYS_INLINE bool areBothImmediate(const JSValue* v1, const JSValue* v2)
         {
             return isImmediate(v1) & isImmediate(v2);
index 319daa089d9bbbfec9e213c2d11d47ee7d91178b..ac86d9dc374341a8ae741d2c8e6952fb40e1dfd6 100644 (file)
@@ -32,8 +32,9 @@
 namespace JSC {
 
     // WebCore uses this to make document.all and style.filter undetectable.
-    static const unsigned MasqueradesAsUndefined = 0x1;
-    static const unsigned ImplementsHasInstance = 0x2;
+    static const unsigned MasqueradesAsUndefined = 1;
+    static const unsigned ImplementsHasInstance = 1 << 1;
+    static const unsigned OverridesHasInstance = 1 << 2;
 
     class TypeInfo {
         friend class CTI;
@@ -44,7 +45,9 @@ namespace JSC {
 
         bool masqueradesAsUndefined() const { return m_flags & MasqueradesAsUndefined; }
         bool implementsHasInstance() const { return m_flags & ImplementsHasInstance; }
+        bool overridesHasInstance() const { return m_flags & OverridesHasInstance; }
 
+        unsigned flags() const { return m_flags; }
     private:
         JSType m_type;
         unsigned m_flags;
index d099ebc3ac859de4c33229ec9c697ffb90544474..0be3e39660278e2070d5c4813a4e122d483d5c31 100644 (file)
@@ -1,3 +1,17 @@
+2008-09-23  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Darin.
+
+        - speed up instanceof some more
+        https://bugs.webkit.org/show_bug.cgi?id=20818
+
+        ~2% speedup on EarleyBoyer
+
+        (WebCore updates.)
+        
+        * bindings/js/JSQuarantinedObjectWrapper.h:
+        (WebCore::JSQuarantinedObjectWrapper::createStructureID):
+
 2008-09-22  Darin Adler  <darin@apple.com>
 
         Reviewed by Oliver Hunt.
index c76ca0d2c5330f9d9cd281926a2f3eb0c5037b73..82ae489d3e9ed344a023cf0a216b1cbc3a07051b 100644 (file)
@@ -46,7 +46,7 @@ namespace WebCore {
 
         static PassRefPtr<JSC::StructureID> createStructureID(JSC::JSValue* proto) 
         { 
-            return JSC::StructureID::create(proto, JSC::TypeInfo(JSC::ObjectType, JSC::ImplementsHasInstance)); 
+            return JSC::StructureID::create(proto, JSC::TypeInfo(JSC::ObjectType, JSC::ImplementsHasInstance | JSC::OverridesHasInstance)); 
         }
 
     protected: