Title: [164347] trunk/Source
Revision
164347
Author
[email protected]
Date
2014-02-18 19:21:47 -0800 (Tue, 18 Feb 2014)

Log Message

Add fast mapping from StringImpl to JSString
https://bugs.webkit.org/show_bug.cgi?id=128625

Reviewed by Geoff Garen & Andreas Kling.

Source/_javascript_Core: 

* runtime/JSString.cpp:
(JSC::JSString::WeakOwner::finalize):
    - once the JSString weakly owned by a StringImpl becomed unreachable remove the WeakImpl.
* runtime/JSString.h:
(JSC::jsStringWithWeakOwner):
    - create a JSString wrapping a StringImpl, and weakly caches the JSString on the StringImpl.
* runtime/VM.cpp:
(JSC::VM::VM):
    - initialize jsStringWeakOwner.
(JSC::VM::createLeakedForMainThread):
    - initialize jsStringWeakOwner - the main thread gets to use the weak pointer
      on StringImpl to cache a JSString wrapper.
* runtime/VM.h:
    - renamed createLeaked -> createLeakedForMainThread to make it clear this
      should only be used to cretae the main thread VM.

Source/WebCore: 

Removed JSStringCache from WebCore; call JSC::jsStringWithWeakOwner instead.

* bindings/js/DOMWrapperWorld.cpp:
(WebCore::DOMWrapperWorld::clearWrappers):
    - removed JSStringCache.
* bindings/js/DOMWrapperWorld.h:
    - removed JSStringCache.
* bindings/js/JSDOMBinding.h:
(WebCore::jsStringWithCache):
    - call jsStringWithWeakOwner insead of using JSStringCache.
* bindings/js/JSDOMWindowBase.cpp:
(WebCore::JSDOMWindowBase::commonVM):
    - renamed createLeaked -> createLeakedForMainThread.
* bindings/scripts/StaticString.pm:
(GenerateStrings):
    - StringImpl has an additional field.

Source/WTF: 

Add weak pointer from StringImpl to JSString.

* wtf/text/StringImpl.cpp:
(WTF::StringImpl::~StringImpl):
    - ASSERT m_weakJSString is null.
* wtf/text/StringImpl.h:
(WTF::StringImpl::StringImpl):
    - initialize m_weakJSString.
(WTF::StringImpl::weakJSString):
(WTF::StringImpl::setWeakJSString):
    - added acessors for m_weakJSString.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (164346 => 164347)


--- trunk/Source/_javascript_Core/ChangeLog	2014-02-19 02:58:52 UTC (rev 164346)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-02-19 03:21:47 UTC (rev 164347)
@@ -1,3 +1,26 @@
+2014-02-17  Gavin Barraclough  <[email protected]>
+
+        Add fast mapping from StringImpl to JSString
+        https://bugs.webkit.org/show_bug.cgi?id=128625
+
+        Reviewed by Geoff Garen & Andreas Kling.
+
+        * runtime/JSString.cpp:
+        (JSC::JSString::WeakOwner::finalize):
+            - once the JSString weakly owned by a StringImpl becomed unreachable remove the WeakImpl.
+        * runtime/JSString.h:
+        (JSC::jsStringWithWeakOwner):
+            - create a JSString wrapping a StringImpl, and weakly caches the JSString on the StringImpl.
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+            - initialize jsStringWeakOwner.
+        (JSC::VM::createLeakedForMainThread):
+            - initialize jsStringWeakOwner - the main thread gets to use the weak pointer
+              on StringImpl to cache a JSString wrapper.
+        * runtime/VM.h:
+            - renamed createLeaked -> createLeakedForMainThread to make it clear this
+              should only be used to cretae the main thread VM.
+
 2014-02-18  Oliver Hunt  <[email protected]>
 
         Prevent builtin js named with C++ reserved words from breaking the build

Modified: trunk/Source/_javascript_Core/runtime/JSString.cpp (164346 => 164347)


--- trunk/Source/_javascript_Core/runtime/JSString.cpp	2014-02-19 02:58:52 UTC (rev 164346)
+++ trunk/Source/_javascript_Core/runtime/JSString.cpp	2014-02-19 03:21:47 UTC (rev 164347)
@@ -298,4 +298,11 @@
     return false;
 }
 
+void JSString::WeakOwner::finalize(Handle<Unknown>, void* context)
+{
+    StringImpl* impl = static_cast<StringImpl*>(context);
+    WeakSet::deallocate(impl->weakJSString());
+    impl->setWeakJSString(nullptr);
+}
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/JSString.h (164346 => 164347)


--- trunk/Source/_javascript_Core/runtime/JSString.h	2014-02-19 02:58:52 UTC (rev 164346)
+++ trunk/Source/_javascript_Core/runtime/JSString.h	2014-02-19 03:21:47 UTC (rev 164347)
@@ -63,6 +63,11 @@
 
     class JSString : public JSCell {
     public:
+        class WeakOwner final : public WeakHandleOwner {
+        public:
+            virtual void finalize(Handle<Unknown>, void* context) override;
+        };
+
         friend class JIT;
         friend class VM;
         friend class SpecializedThunkJIT;
@@ -405,6 +410,28 @@
         return JSString::create(*vm, s.impl());
     }
 
+    inline JSString* jsStringWithWeakOwner(VM* vm, const String& s)
+    {
+        WeakHandleOwner* jsStringWeakOwner = vm->jsStringWeakOwner.get();
+        StringImpl* impl = s.impl();
+
+        // If this vm is not allowed to weakly own strings just call jsString.
+        if (!jsStringWeakOwner || !impl)
+            return jsString(vm, s);
+
+        // Check for an existing weakly owned JSString.
+        if (WeakImpl* weakImpl = impl->weakJSString()) {
+            if (weakImpl->state() == WeakImpl::Live)
+                return asString(weakImpl->jsValue());
+            WeakSet::deallocate(weakImpl);
+            impl->setWeakJSString(nullptr);
+        }
+
+        JSString* string = jsString(vm, s);
+        impl->setWeakJSString(WeakSet::allocate(string, jsStringWeakOwner, impl));
+        return string;
+    }
+
     inline JSString* jsSubstring(ExecState* exec, JSString* s, unsigned offset, unsigned length)
     {
         ASSERT(offset <= static_cast<unsigned>(s->length()));

Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (164346 => 164347)


--- trunk/Source/_javascript_Core/runtime/VM.cpp	2014-02-19 02:58:52 UTC (rev 164346)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp	2014-02-19 03:21:47 UTC (rev 164347)
@@ -403,9 +403,11 @@
     return adoptRef(new VM(Default, heapType));
 }
 
-PassRefPtr<VM> VM::createLeaked(HeapType heapType)
+PassRefPtr<VM> VM::createLeakedForMainThread(HeapType heapType)
 {
-    return create(heapType);
+    VM* vm = new VM(Default, heapType);
+    vm->jsStringWeakOwner = adoptPtr(new JSString::WeakOwner);
+    return adoptRef(vm);
 }
 
 bool VM::sharedInstanceExists()

Modified: trunk/Source/_javascript_Core/runtime/VM.h (164346 => 164347)


--- trunk/Source/_javascript_Core/runtime/VM.h	2014-02-19 02:58:52 UTC (rev 164346)
+++ trunk/Source/_javascript_Core/runtime/VM.h	2014-02-19 03:21:47 UTC (rev 164347)
@@ -184,8 +184,8 @@
     class VM : public ThreadSafeRefCounted<VM> {
     public:
         // WebCore has a one-to-one mapping of threads to VMs;
-        // either create() or createLeaked() should only be called once
-        // on a thread, this is the 'default' VM (it uses the
+        // either create() or createLeakedForMainThread() should only be
+        // called once on a thread, this is the 'default' VM (it uses the
         // thread's default string uniquing table from wtfThreadData).
         // API contexts created using the new context group aware interface
         // create APIContextGroup objects which require less locking of JSC
@@ -203,7 +203,7 @@
         JS_EXPORT_PRIVATE static VM& sharedInstance();
 
         JS_EXPORT_PRIVATE static PassRefPtr<VM> create(HeapType = SmallHeap);
-        JS_EXPORT_PRIVATE static PassRefPtr<VM> createLeaked(HeapType = SmallHeap);
+        JS_EXPORT_PRIVATE static PassRefPtr<VM> createLeakedForMainThread(HeapType = SmallHeap);
         static PassRefPtr<VM> createContextGroup(HeapType = SmallHeap);
         JS_EXPORT_PRIVATE ~VM();
 
@@ -222,7 +222,10 @@
         // The heap should be just after executableAllocator and before other members to ensure that it's
         // destructed after all the objects that reference it.
         Heap heap;
-        
+
+        // Used to manage weak references from StringImpls to JSStrings.
+        OwnPtr<WeakHandleOwner> jsStringWeakOwner;
+
 #if ENABLE(DFG_JIT)
         OwnPtr<DFG::LongLivedState> dfgState;
 #endif // ENABLE(DFG_JIT)

Modified: trunk/Source/WTF/ChangeLog (164346 => 164347)


--- trunk/Source/WTF/ChangeLog	2014-02-19 02:58:52 UTC (rev 164346)
+++ trunk/Source/WTF/ChangeLog	2014-02-19 03:21:47 UTC (rev 164347)
@@ -1,3 +1,22 @@
+2014-02-17  Gavin Barraclough  <[email protected]>
+
+        Add fast mapping from StringImpl to JSString
+        https://bugs.webkit.org/show_bug.cgi?id=128625
+
+        Reviewed by Geoff Garen & Andreas Kling.
+
+        Add weak pointer from StringImpl to JSString.
+
+        * wtf/text/StringImpl.cpp:
+        (WTF::StringImpl::~StringImpl):
+            - ASSERT m_weakJSString is null.
+        * wtf/text/StringImpl.h:
+        (WTF::StringImpl::StringImpl):
+            - initialize m_weakJSString.
+        (WTF::StringImpl::weakJSString):
+        (WTF::StringImpl::setWeakJSString):
+            - added acessors for m_weakJSString.
+
 2014-02-18  Joseph Pecoraro  <[email protected]>
 
         [iOS] Web Inspector: JSContext inspection crashes in isMainThread, uninitialized WebCoreWebThreadIsLockedOrDisabled

Modified: trunk/Source/WTF/wtf/text/StringImpl.cpp (164346 => 164347)


--- trunk/Source/WTF/wtf/text/StringImpl.cpp	2014-02-19 02:58:52 UTC (rev 164346)
+++ trunk/Source/WTF/wtf/text/StringImpl.cpp	2014-02-19 03:21:47 UTC (rev 164347)
@@ -44,7 +44,7 @@
 
 using namespace Unicode;
 
-COMPILE_ASSERT(sizeof(StringImpl) == 2 * sizeof(int) + 3 * sizeof(void*), StringImpl_should_stay_small);
+COMPILE_ASSERT(sizeof(StringImpl) == 2 * sizeof(int) + 4 * sizeof(void*), StringImpl_should_stay_small);
 
 #ifdef STRING_STATS
 StringStats StringImpl::m_stringStats;
@@ -110,6 +110,7 @@
 StringImpl::~StringImpl()
 {
     ASSERT(!isStatic());
+    ASSERT(!m_weakJSString);
 
     STRING_STATS_REMOVE_STRING(this);
 

Modified: trunk/Source/WTF/wtf/text/StringImpl.h (164346 => 164347)


--- trunk/Source/WTF/wtf/text/StringImpl.h	2014-02-19 02:58:52 UTC (rev 164346)
+++ trunk/Source/WTF/wtf/text/StringImpl.h	2014-02-19 03:21:47 UTC (rev 164347)
@@ -54,6 +54,10 @@
 struct IdentifierLCharFromUCharTranslator;
 }
 
+namespace JSC {
+    class WeakImpl;
+}
+
 namespace WTF {
 
 struct CStringTranslator;
@@ -162,6 +166,7 @@
         : m_refCount(s_refCountFlagIsStaticString)
         , m_length(length)
         , m_data16(characters)
+        , m_weakJSString(nullptr)
         , m_hashAndFlags(s_hashFlagIsIdentifier | BufferOwned)
     {
         // Ensure that the hash is computed so that AtomicStringHash can call existingHash()
@@ -179,6 +184,7 @@
         : m_refCount(s_refCountFlagIsStaticString)
         , m_length(length)
         , m_data8(characters)
+        , m_weakJSString(nullptr)
         , m_hashAndFlags(s_hashFlag8BitBuffer | s_hashFlagIsIdentifier | BufferOwned)
     {
         // Ensure that the hash is computed so that AtomicStringHash can call existingHash()
@@ -196,6 +202,7 @@
         : m_refCount(s_refCountIncrement)
         , m_length(length)
         , m_data8(tailPointer<LChar>())
+        , m_weakJSString(nullptr)
         , m_hashAndFlags(s_hashFlag8BitBuffer | BufferInternal)
     {
         ASSERT(m_data8);
@@ -209,6 +216,7 @@
         : m_refCount(s_refCountIncrement)
         , m_length(length)
         , m_data16(tailPointer<UChar>())
+        , m_weakJSString(nullptr)
         , m_hashAndFlags(BufferInternal)
     {
         ASSERT(m_data16);
@@ -222,6 +230,7 @@
         : m_refCount(s_refCountIncrement)
         , m_length(length)
         , m_data8(characters.leakPtr())
+        , m_weakJSString(nullptr)
         , m_hashAndFlags(s_hashFlag8BitBuffer | BufferOwned)
     {
         ASSERT(m_data8);
@@ -235,6 +244,7 @@
         : m_refCount(s_refCountIncrement)
         , m_length(length)
         , m_data16(characters)
+        , m_weakJSString(nullptr)
         , m_hashAndFlags(BufferInternal)
     {
         ASSERT(m_data16);
@@ -247,6 +257,7 @@
         : m_refCount(s_refCountIncrement)
         , m_length(length)
         , m_data8(characters)
+        , m_weakJSString(nullptr)
         , m_hashAndFlags(s_hashFlag8BitBuffer | BufferInternal)
     {
         ASSERT(m_data8);
@@ -260,6 +271,7 @@
         : m_refCount(s_refCountIncrement)
         , m_length(length)
         , m_data16(characters.leakPtr())
+        , m_weakJSString(nullptr)
         , m_hashAndFlags(BufferOwned)
     {
         ASSERT(m_data16);
@@ -273,6 +285,7 @@
         : m_refCount(s_refCountIncrement)
         , m_length(length)
         , m_data8(characters)
+        , m_weakJSString(nullptr)
         , m_hashAndFlags(s_hashFlag8BitBuffer | BufferSubstring)
     {
         ASSERT(is8Bit());
@@ -290,6 +303,7 @@
         : m_refCount(s_refCountIncrement)
         , m_length(length)
         , m_data16(characters)
+        , m_weakJSString(nullptr)
         , m_hashAndFlags(BufferSubstring)
     {
         ASSERT(!is8Bit());
@@ -309,6 +323,7 @@
         // We expect m_length to be initialized to 0 as we use it
         // to represent a null terminated buffer.
         , m_data8(reinterpret_cast<const LChar*>(&m_length))
+        , m_weakJSString(nullptr)
     {
         ASSERT(m_data8);
         // Set the hash early, so that all empty unique StringImpls have a hash,
@@ -612,6 +627,9 @@
         m_refCount = tempRefCount;
     }
 
+    JSC::WeakImpl* weakJSString() { return m_weakJSString; }
+    void setWeakJSString(JSC::WeakImpl* weakJSString) { m_weakJSString = weakJSString; }
+
     WTF_EXPORT_PRIVATE static StringImpl* empty();
 
     // FIXME: Does this really belong in StringImpl?
@@ -851,6 +869,7 @@
         unsigned m_refCount;
         unsigned m_length;
         const LChar* m_data8;
+        JSC::WeakImpl* m_weakJSString;
         mutable UChar* m_copyData16;
         unsigned m_hashAndFlags;
 
@@ -876,6 +895,7 @@
         const LChar* m_data8;
         const UChar* m_data16;
     };
+    JSC::WeakImpl* m_weakJSString;
     mutable UChar* m_copyData16;
     mutable unsigned m_hashAndFlags;
 };

Modified: trunk/Source/WebCore/ChangeLog (164346 => 164347)


--- trunk/Source/WebCore/ChangeLog	2014-02-19 02:58:52 UTC (rev 164346)
+++ trunk/Source/WebCore/ChangeLog	2014-02-19 03:21:47 UTC (rev 164347)
@@ -1,3 +1,27 @@
+2014-02-17  Gavin Barraclough  <[email protected]>
+
+        Add fast mapping from StringImpl to JSString
+        https://bugs.webkit.org/show_bug.cgi?id=128625
+
+        Reviewed by Geoff Garen & Andreas Kling.
+
+        Removed JSStringCache from WebCore; call JSC::jsStringWithWeakOwner instead.
+
+        * bindings/js/DOMWrapperWorld.cpp:
+        (WebCore::DOMWrapperWorld::clearWrappers):
+            - removed JSStringCache.
+        * bindings/js/DOMWrapperWorld.h:
+            - removed JSStringCache.
+        * bindings/js/JSDOMBinding.h:
+        (WebCore::jsStringWithCache):
+            - call jsStringWithWeakOwner insead of using JSStringCache.
+        * bindings/js/JSDOMWindowBase.cpp:
+        (WebCore::JSDOMWindowBase::commonVM):
+            - renamed createLeaked -> createLeakedForMainThread.
+        * bindings/scripts/StaticString.pm:
+        (GenerateStrings):
+            - StringImpl has an additional field.
+
 2014-02-18  Simon Fraser  <[email protected]>
 
         Remove UIWKRemoteView

Modified: trunk/Source/WebCore/bindings/js/DOMWrapperWorld.cpp (164346 => 164347)


--- trunk/Source/WebCore/bindings/js/DOMWrapperWorld.cpp	2014-02-19 02:58:52 UTC (rev 164346)
+++ trunk/Source/WebCore/bindings/js/DOMWrapperWorld.cpp	2014-02-19 03:21:47 UTC (rev 164347)
@@ -53,7 +53,6 @@
 void DOMWrapperWorld::clearWrappers()
 {
     m_wrappers.clear();
-    m_stringCache.clear();
 
     // These items are created lazily.
     while (!m_scriptControllersWithWindowShells.isEmpty())

Modified: trunk/Source/WebCore/bindings/js/DOMWrapperWorld.h (164346 => 164347)


--- trunk/Source/WebCore/bindings/js/DOMWrapperWorld.h	2014-02-19 02:58:52 UTC (rev 164346)
+++ trunk/Source/WebCore/bindings/js/DOMWrapperWorld.h	2014-02-19 03:21:47 UTC (rev 164347)
@@ -33,7 +33,6 @@
 class ScriptController;
 
 typedef HashMap<void*, JSC::Weak<JSC::JSObject>> DOMObjectWrapperMap;
-typedef JSC::WeakGCMap<StringImpl*, JSC::JSString, PtrHash<StringImpl*>> JSStringCache;
 
 class DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
 public:
@@ -51,7 +50,6 @@
 
     // FIXME: can we make this private?
     DOMObjectWrapperMap m_wrappers;
-    JSStringCache m_stringCache;
     HashMap<CSSValue*, void*> m_cssValueRoots;
 
     bool isNormal() const { return m_isNormal; }

Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.h (164346 => 164347)


--- trunk/Source/WebCore/bindings/js/JSDOMBinding.h	2014-02-19 02:58:52 UTC (rev 164346)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.h	2014-02-19 03:21:47 UTC (rev 164347)
@@ -594,11 +594,7 @@
         }
     }
 
-    JSStringCache& stringCache = currentWorld(exec).m_stringCache;
-    JSStringCache::AddResult addResult = stringCache.add(stringImpl, nullptr);
-    if (addResult.isNewEntry)
-        addResult.iterator->value = JSC::jsString(exec, String(stringImpl));
-    return JSC::JSValue(addResult.iterator->value.get());
+    return JSC::jsStringWithWeakOwner(&exec->vm(), s);
 }
 
 inline String propertyNameToString(JSC::PropertyName propertyName)

Modified: trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp (164346 => 164347)


--- trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp	2014-02-19 02:58:52 UTC (rev 164346)
+++ trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp	2014-02-19 03:21:47 UTC (rev 164347)
@@ -215,7 +215,7 @@
 #endif
     if (!vm) {
         ScriptController::initializeThreading();
-        vm = VM::createLeaked(LargeHeap).leakRef();
+        vm = VM::createLeakedForMainThread(LargeHeap).leakRef();
 #if PLATFORM(IOS)
         PassOwnPtr<WebSafeGCActivityCallback> activityCallback = WebSafeGCActivityCallback::create(&vm->heap);
         vm->heap.setActivityCallback(activityCallback);

Modified: trunk/Source/WebCore/bindings/scripts/StaticString.pm (164346 => 164347)


--- trunk/Source/WebCore/bindings/scripts/StaticString.pm	2014-02-19 02:58:52 UTC (rev 164346)
+++ trunk/Source/WebCore/bindings/scripts/StaticString.pm	2014-02-19 03:21:47 UTC (rev 164347)
@@ -48,6 +48,7 @@
     $length,
     ${name}String8,
     0,
+    nullptr,
     StringImpl::StaticASCIILiteral::s_initialFlags | (${hash} << StringImpl::StaticASCIILiteral::s_hashShift)
 };
 END
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to