Title: [103726] trunk
Revision
103726
Author
[email protected]
Date
2011-12-27 13:39:43 -0800 (Tue, 27 Dec 2011)

Log Message

Function should handle wrapping/unwrapping RefPtr and PassRefPtr
https://bugs.webkit.org/show_bug.cgi?id=75266

Reviewed by Sam Weinig.

Source/_javascript_Core:

Add ParamStorageTraits that can be used for deciding how bound parameters should be stored
and peeked at. For RefPtr we want to use the raw pointer when "peeking" to avoid ref-churn.
For PassRefPtr, we want to use RefPtr for storage but still use the raw pointer when peeking.

* wtf/Functional.h:
(WTF::ParamStorageTraits::wrap):
(WTF::ParamStorageTraits::unwrap):

Tools:

* TestWebKitAPI/Tests/WTF/Functional.cpp:
(TestWebKitAPI::Number::create):
(TestWebKitAPI::Number::~Number):
(TestWebKitAPI::Number::value):
(TestWebKitAPI::Number::Number):
(TestWebKitAPI::multiplyNumberByTwo):
(TestWebKitAPI::TEST):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (103725 => 103726)


--- trunk/Source/_javascript_Core/ChangeLog	2011-12-27 21:04:16 UTC (rev 103725)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-12-27 21:39:43 UTC (rev 103726)
@@ -1,3 +1,18 @@
+2011-12-27  Anders Carlsson  <[email protected]>
+
+        Function should handle wrapping/unwrapping RefPtr and PassRefPtr
+        https://bugs.webkit.org/show_bug.cgi?id=75266
+
+        Reviewed by Sam Weinig.
+
+        Add ParamStorageTraits that can be used for deciding how bound parameters should be stored
+        and peeked at. For RefPtr we want to use the raw pointer when "peeking" to avoid ref-churn.
+        For PassRefPtr, we want to use RefPtr for storage but still use the raw pointer when peeking.
+
+        * wtf/Functional.h:
+        (WTF::ParamStorageTraits::wrap):
+        (WTF::ParamStorageTraits::unwrap):
+
 2011-12-27  Tony Chang  <[email protected]>
 
         [chromium] really enable wpo for WebCore libs and for WTF

Modified: trunk/Source/_javascript_Core/wtf/Functional.h (103725 => 103726)


--- trunk/Source/_javascript_Core/wtf/Functional.h	2011-12-27 21:04:16 UTC (rev 103725)
+++ trunk/Source/_javascript_Core/wtf/Functional.h	2011-12-27 21:39:43 UTC (rev 103726)
@@ -196,6 +196,27 @@
     static void deref(T* t) { t->deref(); }
 };
 
+template<typename T> struct ParamStorageTraits {
+    typedef T StorageType;
+
+    static StorageType wrap(const T& value) { return value; }
+    static const T& unwrap(const StorageType& value) { return value; }
+};
+
+template<typename T> struct ParamStorageTraits<PassRefPtr<T> > {
+    typedef RefPtr<T> StorageType;
+
+    static StorageType wrap(PassRefPtr<T> value) { return value; }
+    static T* unwrap(const StorageType& value) { return value.get(); }
+};
+
+template<typename T> struct ParamStorageTraits<RefPtr<T> > {
+    typedef RefPtr<T> StorageType;
+
+    static StorageType wrap(RefPtr<T> value) { return value.release();  }
+    static T* unwrap(const StorageType& value) { return value.get(); }
+};
+
 class FunctionImplBase : public ThreadSafeRefCounted<FunctionImplBase> {
 public:
     virtual ~FunctionImplBase() { }
@@ -234,7 +255,7 @@
 public:
     BoundFunctionImpl(FunctionWrapper functionWrapper, const P0& p0)
         : m_functionWrapper(functionWrapper)
-        , m_p0(p0)
+        , m_p0(ParamStorageTraits<P0>::wrap(p0))
     {
         RefAndDeref<P0, FunctionWrapper::shouldRefFirstParameter>::ref(m_p0);
     }
@@ -246,20 +267,20 @@
 
     virtual R operator()()
     {
-        return m_functionWrapper(m_p0);
+        return m_functionWrapper(ParamStorageTraits<P0>::unwrap(m_p0));
     }
 
 private:
     FunctionWrapper m_functionWrapper;
-    P0 m_p0;
+    typename ParamStorageTraits<P0>::StorageType m_p0;
 };
 
 template<typename FunctionWrapper, typename R, typename P0, typename P1> class BoundFunctionImpl<FunctionWrapper, R (P0, P1)> : public FunctionImpl<typename FunctionWrapper::ResultType ()> {
 public:
     BoundFunctionImpl(FunctionWrapper functionWrapper, const P0& p0, const P1& p1)
         : m_functionWrapper(functionWrapper)
-        , m_p0(p0)
-        , m_p1(p1)
+        , m_p0(ParamStorageTraits<P0>::wrap(p0))
+        , m_p1(ParamStorageTraits<P1>::wrap(p1))
     {
         RefAndDeref<P0, FunctionWrapper::shouldRefFirstParameter>::ref(m_p0);
     }
@@ -271,22 +292,22 @@
 
     virtual typename FunctionWrapper::ResultType operator()()
     {
-        return m_functionWrapper(m_p0, m_p1);
+        return m_functionWrapper(ParamStorageTraits<P0>::unwrap(m_p0), ParamStorageTraits<P1>::unwrap(m_p1));
     }
 
 private:
     FunctionWrapper m_functionWrapper;
-    P0 m_p0;
-    P1 m_p1;
+    typename ParamStorageTraits<P0>::StorageType m_p0;
+    typename ParamStorageTraits<P1>::StorageType m_p1;
 };
 
 template<typename FunctionWrapper, typename R, typename P0, typename P1, typename P2> class BoundFunctionImpl<FunctionWrapper, R (P0, P1, P2)> : public FunctionImpl<typename FunctionWrapper::ResultType ()> {
 public:
     BoundFunctionImpl(FunctionWrapper functionWrapper, const P0& p0, const P1& p1, const P2& p2)
         : m_functionWrapper(functionWrapper)
-        , m_p0(p0)
-        , m_p1(p1)
-        , m_p2(p2)
+        , m_p0(ParamStorageTraits<P0>::wrap(p0))
+        , m_p1(ParamStorageTraits<P1>::wrap(p1))
+        , m_p2(ParamStorageTraits<P2>::wrap(p2))
     {
         RefAndDeref<P0, FunctionWrapper::shouldRefFirstParameter>::ref(m_p0);
     }
@@ -298,14 +319,14 @@
 
     virtual typename FunctionWrapper::ResultType operator()()
     {
-        return m_functionWrapper(m_p0, m_p1, m_p2);
+        return m_functionWrapper(ParamStorageTraits<P0>::unwrap(m_p0), ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2));
     }
 
 private:
     FunctionWrapper m_functionWrapper;
-    P0 m_p0;
-    P1 m_p1;
-    P2 m_p2;
+    typename ParamStorageTraits<P0>::StorageType m_p0;
+    typename ParamStorageTraits<P1>::StorageType m_p1;
+    typename ParamStorageTraits<P2>::StorageType m_p2;
 };
 
 class FunctionBase {

Modified: trunk/Tools/ChangeLog (103725 => 103726)


--- trunk/Tools/ChangeLog	2011-12-27 21:04:16 UTC (rev 103725)
+++ trunk/Tools/ChangeLog	2011-12-27 21:39:43 UTC (rev 103726)
@@ -1,3 +1,18 @@
+2011-12-27  Anders Carlsson  <[email protected]>
+
+        Function should handle wrapping/unwrapping RefPtr and PassRefPtr
+        https://bugs.webkit.org/show_bug.cgi?id=75266
+
+        Reviewed by Sam Weinig.
+
+        * TestWebKitAPI/Tests/WTF/Functional.cpp:
+        (TestWebKitAPI::Number::create):
+        (TestWebKitAPI::Number::~Number):
+        (TestWebKitAPI::Number::value):
+        (TestWebKitAPI::Number::Number):
+        (TestWebKitAPI::multiplyNumberByTwo):
+        (TestWebKitAPI::TEST):
+
 2011-12-24  Kentaro Hara  <[email protected]>
 
         Add unittests for the C++ parser of prepare-ChangeLog

Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/Functional.cpp (103725 => 103726)


--- trunk/Tools/TestWebKitAPI/Tests/WTF/Functional.cpp	2011-12-27 21:04:16 UTC (rev 103725)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/Functional.cpp	2011-12-27 21:39:43 UTC (rev 103726)
@@ -24,6 +24,7 @@
  */
 
 #include "config.h"
+#include <wtf/RefCounted.h>
 #include <wtf/Functional.h>
 
 namespace TestWebKitAPI {
@@ -151,6 +152,49 @@
 
 }
 
+class Number : public RefCounted<Number> {
+public:
+    static PassRefPtr<Number> create(int value)
+    {
+        return adoptRef(new Number(value));
+    }
+
+    ~Number()
+    {
+        m_value = 0;
+    }
+
+    int value() const { return m_value; }
+
+private:
+    explicit Number(int value)
+        : m_value(value)
+    {
+    }
+
+    int m_value;
+};
+
+static int multiplyNumberByTwo(Number* number)
+{
+    return number->value() * 2;
+}
+
+TEST(FunctionalTest, RefCountedStorage)
+{
+    RefPtr<Number> five = Number::create(5);
+    Function<int ()> multiplyFiveByTwoFunction = bind(multiplyNumberByTwo, five);
+    ASSERT_EQ(10, multiplyFiveByTwoFunction());
+
+    Function<int ()> multiplyFourByTwoFunction = bind(multiplyNumberByTwo, Number::create(4));
+    ASSERT_EQ(8, multiplyFourByTwoFunction());
+
+    RefPtr<Number> six = Number::create(6);
+    Function<int ()> multiplySixByTwoFunction = bind(multiplyNumberByTwo, six.release());
+    ASSERT_FALSE(six);
+    ASSERT_EQ(12, multiplySixByTwoFunction());
+}
+
 namespace RefAndDerefTests {
     
     template<typename T> struct RefCounted {
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to