Title: [206354] trunk/Source/WebCore
Revision
206354
Author
[email protected]
Date
2016-09-24 17:43:38 -0700 (Sat, 24 Sep 2016)

Log Message

[Binding] setDOMException should be inlined and fall to the slow path if exception occurs
https://bugs.webkit.org/show_bug.cgi?id=162503

Reviewed by Saam Barati.

Binding code emits setDOMException in critical paths. However, it is not inlined.
Since exception less frequently occurs, we should have inlined setDOMException that
early returns if it does not need to raise an exception. And it should call the exception
raising code as slow path case. This tiny optimization can offer improvement if
the DOM function is tiny and DOM binding occupies large part of it. Combined with r206338,
it offers 5% improvement in Dromaeo dom-attr getAttribute / setAttribute tests.

* bindings/js/JSDOMBinding.cpp:
(WebCore::throwDOMException): Extract the actual exception raising code.
(WebCore::setDOMExceptionSlow): Call throwDOMException and keep it not inlined.
(WebCore::setDOMException):
* bindings/js/JSDOMBinding.h:
(WebCore::setDOMException): Use ThrowScope& to check `scope.exception()`.
And it has a path for normal case that allows early returning.
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateImplementation):
(GenerateImplementationFunctionCall):
(GenerateConstructorDefinition):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (206353 => 206354)


--- trunk/Source/WebCore/ChangeLog	2016-09-24 21:53:48 UTC (rev 206353)
+++ trunk/Source/WebCore/ChangeLog	2016-09-25 00:43:38 UTC (rev 206354)
@@ -1,3 +1,29 @@
+2016-09-24  Yusuke Suzuki  <[email protected]>
+
+        [Binding] setDOMException should be inlined and fall to the slow path if exception occurs
+        https://bugs.webkit.org/show_bug.cgi?id=162503
+
+        Reviewed by Saam Barati.
+
+        Binding code emits setDOMException in critical paths. However, it is not inlined.
+        Since exception less frequently occurs, we should have inlined setDOMException that
+        early returns if it does not need to raise an exception. And it should call the exception
+        raising code as slow path case. This tiny optimization can offer improvement if
+        the DOM function is tiny and DOM binding occupies large part of it. Combined with r206338,
+        it offers 5% improvement in Dromaeo dom-attr getAttribute / setAttribute tests.
+
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::throwDOMException): Extract the actual exception raising code.
+        (WebCore::setDOMExceptionSlow): Call throwDOMException and keep it not inlined.
+        (WebCore::setDOMException):
+        * bindings/js/JSDOMBinding.h:
+        (WebCore::setDOMException): Use ThrowScope& to check `scope.exception()`.
+        And it has a path for normal case that allows early returning.
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateImplementation):
+        (GenerateImplementationFunctionCall):
+        (GenerateConstructorDefinition):
+
 2016-09-23  Antti Koivisto  <[email protected]>
 
         Move stylesheet change logic from Document to AuthorStyleSheets

Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp (206353 => 206354)


--- trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp	2016-09-24 21:53:48 UTC (rev 206353)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp	2016-09-25 00:43:38 UTC (rev 206354)
@@ -344,6 +344,28 @@
     return createDOMException(exec, ec, nullptr);
 }
 
+ALWAYS_INLINE static void throwDOMException(ExecState* exec, ThrowScope& throwScope, ExceptionCode ec)
+{
+    ASSERT(ec && !throwScope.exception());
+    throwException(exec, throwScope, createDOMException(exec, ec));
+}
+
+ALWAYS_INLINE static void throwDOMException(ExecState* exec, ThrowScope& throwScope, const ExceptionCodeWithMessage& ec)
+{
+    ASSERT(ec.code && !throwScope.exception());
+    throwException(exec, throwScope, createDOMException(exec, ec.code, ec.message));
+}
+
+void setDOMExceptionSlow(ExecState* exec, ThrowScope& throwScope, ExceptionCode ec)
+{
+    throwDOMException(exec, throwScope, ec);
+}
+
+void setDOMExceptionSlow(ExecState* exec, ThrowScope& throwScope, const ExceptionCodeWithMessage& ec)
+{
+    throwDOMException(exec, throwScope, ec);
+}
+
 void setDOMException(ExecState* exec, ExceptionCode ec)
 {
     VM& vm = exec->vm();
@@ -352,10 +374,10 @@
     if (!ec || scope.exception())
         return;
 
-    throwException(exec, scope, createDOMException(exec, ec));
+    throwDOMException(exec, scope, ec);
 }
 
-void setDOMException(JSC::ExecState* exec, const ExceptionCodeWithMessage& ec)
+void setDOMException(ExecState* exec, const ExceptionCodeWithMessage& ec)
 {
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -363,7 +385,7 @@
     if (!ec.code || scope.exception())
         return;
 
-    throwException(exec, scope, createDOMException(exec, ec.code, ec.message));
+    throwDOMException(exec, scope, ec);
 }
 
 #undef TRY_TO_CREATE_EXCEPTION

Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.h (206353 => 206354)


--- trunk/Source/WebCore/bindings/js/JSDOMBinding.h	2016-09-24 21:53:48 UTC (rev 206353)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.h	2016-09-25 00:43:38 UTC (rev 206354)
@@ -24,6 +24,7 @@
 #pragma once
 
 #include "DOMWrapperWorld.h"
+#include "ExceptionCode.h"
 #include "JSDOMGlobalObject.h"
 #include "JSDOMWrapper.h"
 #include "ScriptWrappable.h"
@@ -69,8 +70,6 @@
 class URL;
 class Node;
 
-struct ExceptionCodeWithMessage;
-
 template<typename> class ExceptionOr;
 
 using ExceptionCode = int;
@@ -190,6 +189,23 @@
 WEBCORE_EXPORT void setDOMException(JSC::ExecState*, ExceptionCode);
 void setDOMException(JSC::ExecState*, const ExceptionCodeWithMessage&);
 
+WEBCORE_EXPORT void setDOMExceptionSlow(JSC::ExecState*, JSC::ThrowScope&, ExceptionCode);
+void setDOMExceptionSlow(JSC::ExecState*, JSC::ThrowScope&, const ExceptionCodeWithMessage&);
+
+ALWAYS_INLINE void setDOMException(JSC::ExecState* exec, JSC::ThrowScope& throwScope, const ExceptionCodeWithMessage& message)
+{
+    if (LIKELY(!message.code || throwScope.exception()))
+        return;
+    setDOMExceptionSlow(exec, throwScope, message);
+}
+
+ALWAYS_INLINE void setDOMException(JSC::ExecState* exec, JSC::ThrowScope& throwScope, ExceptionCode ec)
+{
+    if (LIKELY(!ec || throwScope.exception()))
+        return;
+    setDOMExceptionSlow(exec, throwScope, ec);
+}
+
 template<typename T> inline JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, ExceptionOr<T>&&);
 template<typename T> inline JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject*, ExceptionOr<T>&&);
 

Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (206353 => 206354)


--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2016-09-24 21:53:48 UTC (rev 206353)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2016-09-25 00:43:38 UTC (rev 206354)
@@ -2922,7 +2922,7 @@
                 push(@implContent, "        $memoizedType memoizedResult = castedThis->wrapped().$implGetterFunctionName(" . join(", ", @arguments) . ");\n");
                 push(@implContent, "        cursor.appendInput<MemoizedDOMResult<$memoizedType>>(bindingName.get().string(), memoizedResult, $exceptionCode);\n");
                 push(@implContent, "        JSValue result = " . NativeToJSValue($attribute->signature, 0, $interface, "memoizedResult", "castedThis") . ";\n");
-                push(@implContent, "        setDOMException(state, ec);\n") if $getterExceptions;
+                push(@implContent, "        setDOMException(state, throwScope, ec);\n") if $getterExceptions;
                 push(@implContent, "        return JSValue::encode(result);\n");
                 push(@implContent, "    }\n");
                 push(@implContent, "\n");
@@ -2932,7 +2932,7 @@
                 push(@implContent, "        if (input && input->convertTo<$memoizedType>(memoizedResult)) {\n");
                 # FIXME: the generated code should report an error if an input cannot be fetched or converted.
                 push(@implContent, "            JSValue result = " . NativeToJSValue($attribute->signature, 0, $interface, "memoizedResult", "castedThis") . ";\n");
-                push(@implContent, "            setDOMException(state, input->exceptionCode());\n") if $getterExceptions;
+                push(@implContent, "            setDOMException(state, throwScope, input->exceptionCode());\n") if $getterExceptions;
                 push(@implContent, "            return JSValue::encode(result);\n");
                 push(@implContent, "        }\n");
                 push(@implContent, "    }\n");
@@ -3025,7 +3025,7 @@
                     push(@implContent, "    JSValue result = " . NativeToJSValue($attribute->signature, 0, $interface, "impl.$implGetterFunctionName(" . join(", ", @arguments) . ")", "castedThis") . ";\n");
                 }
 
-                push(@implContent, "    setDOMException(state, ec);\n");
+                push(@implContent, "    setDOMException(state, throwScope, ec);\n");
 
                 push(@implContent, "    return JSValue::encode(result);\n");
             }
@@ -3279,7 +3279,7 @@
                 if ($svgPropertyOrListPropertyType) {
                     if ($svgPropertyType) {
                         push(@implContent, "    if (impl.isReadOnly()) {\n");
-                        push(@implContent, "        setDOMException(state, NO_MODIFICATION_ALLOWED_ERR);\n");
+                        push(@implContent, "        setDOMException(state, throwScope, NO_MODIFICATION_ALLOWED_ERR);\n");
                         push(@implContent, "        return false;\n");
                         push(@implContent, "    }\n");
                         $implIncludes{"ExceptionCode.h"} = 1;
@@ -3291,7 +3291,7 @@
                         push(@implContent, "    podImpl.set$implSetterFunctionName(nativeValue");
                         push(@implContent, ", ec") if $setterRaisesException;
                         push(@implContent, ");\n");
-                        push(@implContent, "    setDOMException(state, ec);\n") if $setterRaisesException;
+                        push(@implContent, "    setDOMException(state, throwScope, ec);\n") if $setterRaisesException;
                     }
                     if ($svgPropertyType) {
                         if ($setterRaisesExceptionWithMessage) {
@@ -3330,7 +3330,7 @@
 
                     push(@arguments, "ec") if $setterRaisesException;
                     push(@implContent, "    ${functionName}(" . join(", ", @arguments) . ");\n");
-                    push(@implContent, "    setDOMException(state, ec);\n") if $setterRaisesException;
+                    push(@implContent, "    setDOMException(state, throwScope, ec);\n") if $setterRaisesException;
                     push(@implContent, "    return true;\n");
                 }
             }
@@ -3490,7 +3490,7 @@
                     push(@implContent, "    auto& impl = castedThis->wrapped();\n");
                     if ($svgPropertyType) {
                         push(@implContent, "    if (impl.isReadOnly()) {\n");
-                        push(@implContent, "        setDOMException(state, NO_MODIFICATION_ALLOWED_ERR);\n");
+                        push(@implContent, "        setDOMException(state, throwScope, NO_MODIFICATION_ALLOWED_ERR);\n");
                         push(@implContent, "        return JSValue::encode(jsUndefined());\n");
                         push(@implContent, "    }\n");
                         push(@implContent, "    $svgPropertyType& podImpl = impl.propertyReference();\n");
@@ -4433,15 +4433,15 @@
             push(@implContent, $indent . "InputCursor& cursor = state->lexicalGlobalObject()->inputCursor();\n");
             push(@implContent, $indent . "if (!cursor.isReplaying()) {\n");
             push(@implContent, $indent . "    $functionString;\n");
-            push(@implContent, $indent . "    setDOMException(state, ec);\n") if $raisesException;
+            push(@implContent, $indent . "    setDOMException(state, throwScope, ec);\n") if $raisesException;
             push(@implContent, $indent . "}\n");
             push(@implContent, "#else\n");
             push(@implContent, $indent . "$functionString;\n");
-            push(@implContent, $indent . "setDOMException(state, ec);\n") if $raisesException;
+            push(@implContent, $indent . "setDOMException(state, throwScope, ec);\n") if $raisesException;
             push(@implContent, "#endif\n");
         } else {
             push(@implContent, $indent . "$functionString;\n");
-            push(@implContent, $indent . "setDOMException(state, ec);\n") if $raisesException;
+            push(@implContent, $indent . "setDOMException(state, throwScope, ec);\n") if $raisesException;
         }
 
         if ($svgPropertyType and !$function->isStatic) {
@@ -4494,7 +4494,7 @@
         } else {
             push(@implContent, $indent . "JSValue result = " . NativeToJSValue($function->signature, 1, $interface, $functionString, $thisObject) . ";\n");
         }
-        push(@implContent, "\n" . $indent . "setDOMException(state, ec);\n") if $raisesException;
+        push(@implContent, "\n" . $indent . "setDOMException(state, throwScope, ec);\n") if $raisesException;
 
         if ($codeGenerator->ExtendedAttributeContains($function->signature->extendedAttributes->{"CallWith"}, "ScriptState")) {
             push(@implContent, $indent . "if (UNLIKELY(throwScope.exception()))\n");
@@ -5465,7 +5465,7 @@
 
             if ($interface->extendedAttributes->{"ConstructorRaisesException"}) {
                 push(@$outputArray, "    if (UNLIKELY(ec)) {\n");
-                push(@$outputArray, "        setDOMException(state, ec);\n");
+                push(@$outputArray, "        setDOMException(state, throwScope, ec);\n");
                 push(@$outputArray, "        return JSValue::encode(JSValue());\n");
                 push(@$outputArray, "    }\n");
             }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to