Use one VM per thread for IDB serialization work in network process
authorsihui_liu@apple.com <sihui_liu@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Aug 2019 00:12:42 +0000 (00:12 +0000)
committersihui_liu@apple.com <sihui_liu@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Aug 2019 00:12:42 +0000 (00:12 +0000)
https://bugs.webkit.org/show_bug.cgi?id=200526

Reviewed by Geoffrey Garen.

We had one static VM in UniqueIDBDatabase for serialization/deserialization in MemoryObjectStore. This VM was
never destroyed and could be used on different background threads.

We also had one VM per SQLiteIDBBackingStore for serialization/deserialization in SQLiteIDBBackingStore. If
there were multiple IndexedDB databases of the same session opened, we would have multiple VMs created
on the same thread. Each VM has its memory allocator and garbage collector, which takes up memory.

To be more memory efficient and safe, we can use one VM per thread in the network process, and create/destroy
the VMs on demand.

* Modules/indexeddb/server/IDBSerializationContext.cpp: Added.
(WebCore::IDBServer::IDBSerializationContext::getOrCreateIDBSerializationContext):
(WebCore::IDBServer::IDBSerializationContext::~IDBSerializationContext):
(WebCore::IDBServer::IDBSerializationContext::initializeVM):
(WebCore::IDBServer::IDBSerializationContext::vm):
(WebCore::IDBServer::IDBSerializationContext::execState):
(WebCore::IDBServer::IDBSerializationContext::IDBSerializationContext):
* Modules/indexeddb/server/IDBSerializationContext.h: Added.
* Modules/indexeddb/server/IDBServer.cpp:
(WebCore::IDBServer::IDBServer::createBackingStore):
* Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
(WebCore::IDBServer::MemoryIDBBackingStore::create):
(WebCore::IDBServer::MemoryIDBBackingStore::MemoryIDBBackingStore):
(WebCore::IDBServer::MemoryIDBBackingStore::createObjectStore):
* Modules/indexeddb/server/MemoryIDBBackingStore.h:
* Modules/indexeddb/server/MemoryObjectStore.cpp:
(WebCore::IDBServer::MemoryObjectStore::create):
(WebCore::IDBServer::MemoryObjectStore::MemoryObjectStore):
(WebCore::IDBServer::MemoryObjectStore::updateIndexesForPutRecord):
(WebCore::IDBServer::MemoryObjectStore::populateIndexWithExistingRecords):
* Modules/indexeddb/server/MemoryObjectStore.h:
* Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
(WebCore::IDBServer::SQLiteIDBBackingStore::SQLiteIDBBackingStore):
(WebCore::IDBServer::SQLiteIDBBackingStore::~SQLiteIDBBackingStore):
(WebCore::IDBServer::SQLiteIDBBackingStore::updateOneIndexForAddRecord):
(WebCore::IDBServer::SQLiteIDBBackingStore::updateAllIndexesForAddRecord):
(WebCore::IDBServer::SQLiteIDBBackingStore::initializeVM): Deleted.
(WebCore::IDBServer::SQLiteIDBBackingStore::vm): Deleted.
(WebCore::IDBServer::SQLiteIDBBackingStore::globalObject): Deleted.
* Modules/indexeddb/server/SQLiteIDBBackingStore.h:
* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::databaseThreadVM): Deleted.
(WebCore::IDBServer::UniqueIDBDatabase::databaseThreadExecState): Deleted.
* Modules/indexeddb/server/UniqueIDBDatabase.h:
* Sources.txt:

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

14 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/server/IDBSerializationContext.cpp [new file with mode: 0644]
Source/WebCore/Modules/indexeddb/server/IDBSerializationContext.h [new file with mode: 0644]
Source/WebCore/Modules/indexeddb/server/IDBServer.cpp
Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp
Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h
Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.cpp
Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.h
Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp
Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj

index 434c1a4..3483946 100644 (file)
@@ -1,3 +1,56 @@
+2019-08-15  Sihui Liu  <sihui_liu@apple.com>
+
+        Use one VM per thread for IDB serialization work in network process
+        https://bugs.webkit.org/show_bug.cgi?id=200526
+
+        Reviewed by Geoffrey Garen.
+
+        We had one static VM in UniqueIDBDatabase for serialization/deserialization in MemoryObjectStore. This VM was 
+        never destroyed and could be used on different background threads.
+        We also had one VM per SQLiteIDBBackingStore for serialization/deserialization in SQLiteIDBBackingStore. If 
+        there were multiple IndexedDB databases of the same session opened, we would have multiple VMs created
+        on the same thread. Each VM has its memory allocator and garbage collector, which takes up memory.
+        To be more memory efficient and safe, we can use one VM per thread in the network process, and create/destroy
+        the VMs on demand.
+
+        * Modules/indexeddb/server/IDBSerializationContext.cpp: Added.
+        (WebCore::IDBServer::IDBSerializationContext::getOrCreateIDBSerializationContext):
+        (WebCore::IDBServer::IDBSerializationContext::~IDBSerializationContext):
+        (WebCore::IDBServer::IDBSerializationContext::initializeVM):
+        (WebCore::IDBServer::IDBSerializationContext::vm):
+        (WebCore::IDBServer::IDBSerializationContext::execState):
+        (WebCore::IDBServer::IDBSerializationContext::IDBSerializationContext):
+        * Modules/indexeddb/server/IDBSerializationContext.h: Added.
+        * Modules/indexeddb/server/IDBServer.cpp:
+        (WebCore::IDBServer::IDBServer::createBackingStore):
+        * Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
+        (WebCore::IDBServer::MemoryIDBBackingStore::create):
+        (WebCore::IDBServer::MemoryIDBBackingStore::MemoryIDBBackingStore):
+        (WebCore::IDBServer::MemoryIDBBackingStore::createObjectStore):
+        * Modules/indexeddb/server/MemoryIDBBackingStore.h:
+        * Modules/indexeddb/server/MemoryObjectStore.cpp:
+        (WebCore::IDBServer::MemoryObjectStore::create):
+        (WebCore::IDBServer::MemoryObjectStore::MemoryObjectStore):
+        (WebCore::IDBServer::MemoryObjectStore::updateIndexesForPutRecord):
+        (WebCore::IDBServer::MemoryObjectStore::populateIndexWithExistingRecords):
+        * Modules/indexeddb/server/MemoryObjectStore.h:
+        * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
+        (WebCore::IDBServer::SQLiteIDBBackingStore::SQLiteIDBBackingStore):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::~SQLiteIDBBackingStore):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::updateOneIndexForAddRecord):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::updateAllIndexesForAddRecord):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::initializeVM): Deleted.
+        (WebCore::IDBServer::SQLiteIDBBackingStore::vm): Deleted.
+        (WebCore::IDBServer::SQLiteIDBBackingStore::globalObject): Deleted.
+        * Modules/indexeddb/server/SQLiteIDBBackingStore.h:
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::databaseThreadVM): Deleted.
+        (WebCore::IDBServer::UniqueIDBDatabase::databaseThreadExecState): Deleted.
+        * Modules/indexeddb/server/UniqueIDBDatabase.h:
+        * Sources.txt:
+
 2019-08-15  Zalan Bujtas  <zalan@apple.com>
 
         [ContentChangeObserver] Dispatch synthetic click when the visibility candidate element becomes hidden again.
diff --git a/Source/WebCore/Modules/indexeddb/server/IDBSerializationContext.cpp b/Source/WebCore/Modules/indexeddb/server/IDBSerializationContext.cpp
new file mode 100644 (file)
index 0000000..a9f38ff
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "IDBSerializationContext.h"
+
+#include <pal/SessionID.h>
+
+#if ENABLE(INDEXED_DATABASE)
+
+namespace WebCore {
+
+namespace IDBServer {
+
+static Lock serializationContextMapMutex;
+
+static HashMap<PAL::SessionID, IDBSerializationContext*>& serializationContextMap()
+{
+    static NeverDestroyed<HashMap<PAL::SessionID, IDBSerializationContext*>> map;
+    return map;
+}
+
+Ref<IDBSerializationContext> IDBSerializationContext::getOrCreateIDBSerializationContext(PAL::SessionID sessionID)
+{
+    Locker<Lock> locker(serializationContextMapMutex);
+    auto[iter, isNewEntry] = serializationContextMap().add(sessionID, nullptr);
+    if (isNewEntry) {
+        Ref<IDBSerializationContext> protectedContext = adoptRef(*new IDBSerializationContext(sessionID));
+        iter->value = protectedContext.ptr();
+        return protectedContext;
+    }
+
+    return *iter->value;
+}
+
+IDBSerializationContext::~IDBSerializationContext()
+{
+    Locker<Lock> locker(serializationContextMapMutex);
+    ASSERT(this == serializationContextMap().get(m_sessionID));
+
+    if (m_vm) {
+        JSC::JSLockHolder lock(*m_vm);
+        m_globalObject.clear();
+        m_vm = nullptr;
+    }
+    serializationContextMap().remove(m_sessionID);
+}
+
+void IDBSerializationContext::initializeVM()
+{
+    if (m_vm)
+        return;
+
+    ASSERT(!m_globalObject);
+    m_vm = JSC::VM::create();
+
+    JSC::JSLockHolder locker(m_vm.get());
+    m_globalObject.set(*m_vm, JSC::JSGlobalObject::create(*m_vm, JSC::JSGlobalObject::createStructure(*m_vm, JSC::jsNull())));
+}
+
+JSC::VM& IDBSerializationContext::vm()
+{
+    initializeVM();
+    return *m_vm;
+}
+
+JSC::ExecState& IDBSerializationContext::execState()
+{
+    initializeVM();
+    return *m_globalObject.get()->globalExec();
+}
+
+IDBSerializationContext::IDBSerializationContext(PAL::SessionID sessionID)
+    : m_sessionID(sessionID)
+{
+}
+
+} // namespace IDBServer
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/Modules/indexeddb/server/IDBSerializationContext.h b/Source/WebCore/Modules/indexeddb/server/IDBSerializationContext.h
new file mode 100644 (file)
index 0000000..a9d215b
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include <JavaScriptCore/StrongInlines.h>
+#include <JavaScriptCore/StructureInlines.h>
+
+namespace PAL {
+class SessionID;
+}
+
+namespace JSC {
+class ExecState;
+class VM;
+}
+
+namespace WebCore {
+
+namespace IDBServer {
+
+class IDBSerializationContext : public RefCounted<IDBSerializationContext> {
+public:
+    static Ref<IDBSerializationContext> getOrCreateIDBSerializationContext(PAL::SessionID);
+
+    ~IDBSerializationContext();
+
+    JSC::VM& vm();
+    JSC::ExecState& execState();
+
+private:
+    IDBSerializationContext(PAL::SessionID);
+    void initializeVM();
+
+    RefPtr<JSC::VM> m_vm;
+    JSC::Strong<JSC::JSGlobalObject> m_globalObject;
+    PAL::SessionID m_sessionID;
+};
+
+} // namespace IDBServer
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
index 89bfe79..55b4124 100644 (file)
@@ -133,7 +133,7 @@ std::unique_ptr<IDBBackingStore> IDBServer::createBackingStore(const IDBDatabase
     ASSERT(!isMainThread());
 
     if (m_databaseDirectoryPath.isEmpty())
-        return MemoryIDBBackingStore::create(identifier);
+        return MemoryIDBBackingStore::create(m_sessionID, identifier);
 
     return std::make_unique<SQLiteIDBBackingStore>(m_sessionID, identifier, m_databaseDirectoryPath, m_backingStoreTemporaryFileHandler, m_perOriginQuota);
 }
index 7d142b0..ffc35c3 100644 (file)
@@ -46,13 +46,14 @@ namespace IDBServer {
 // The IndexedDB spec states the value you can get from the key generator is 2^53
 static uint64_t maxGeneratedKeyValue = 0x20000000000000;
 
-std::unique_ptr<MemoryIDBBackingStore> MemoryIDBBackingStore::create(const IDBDatabaseIdentifier& identifier)
+std::unique_ptr<MemoryIDBBackingStore> MemoryIDBBackingStore::create(PAL::SessionID sessionID, const IDBDatabaseIdentifier& identifier)
 {
-    return std::make_unique<MemoryIDBBackingStore>(identifier);
+    return std::make_unique<MemoryIDBBackingStore>(sessionID, identifier);
 }
 
-MemoryIDBBackingStore::MemoryIDBBackingStore(const IDBDatabaseIdentifier& identifier)
+MemoryIDBBackingStore::MemoryIDBBackingStore(PAL::SessionID sessionID, const IDBDatabaseIdentifier& identifier)
     : m_identifier(identifier)
+    , m_sessionID(sessionID)
 {
 }
 
@@ -135,7 +136,7 @@ IDBError MemoryIDBBackingStore::createObjectStore(const IDBResourceIdentifier& t
         return IDBError { ConstraintError };
 
     ASSERT(!m_objectStoresByIdentifier.contains(info.identifier()));
-    auto objectStore = MemoryObjectStore::create(info);
+    auto objectStore = MemoryObjectStore::create(m_sessionID, info);
 
     m_databaseInfo->addExistingObjectStore(info);
 
index 15fe3c4..98c745c 100644 (file)
@@ -41,9 +41,9 @@ class MemoryObjectStore;
 class MemoryIDBBackingStore : public IDBBackingStore {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    static std::unique_ptr<MemoryIDBBackingStore> create(const IDBDatabaseIdentifier&);
+    static std::unique_ptr<MemoryIDBBackingStore> create(PAL::SessionID, const IDBDatabaseIdentifier&);
     
-    MemoryIDBBackingStore(const IDBDatabaseIdentifier&);
+    MemoryIDBBackingStore(PAL::SessionID, const IDBDatabaseIdentifier&);
     ~MemoryIDBBackingStore() final;
 
     IDBError getOrEstablishDatabaseInfo(IDBDatabaseInfo&) final;
@@ -91,6 +91,7 @@ private:
     RefPtr<MemoryObjectStore> takeObjectStoreByIdentifier(uint64_t identifier);
 
     IDBDatabaseIdentifier m_identifier;
+    PAL::SessionID m_sessionID;
     std::unique_ptr<IDBDatabaseInfo> m_databaseInfo;
 
     HashMap<IDBResourceIdentifier, std::unique_ptr<MemoryBackingStoreTransaction>> m_transactions;
index ed6eba9..d865b64 100644 (file)
@@ -32,6 +32,7 @@
 #include "IDBError.h"
 #include "IDBGetAllResult.h"
 #include "IDBKeyRangeData.h"
+#include "IDBSerializationContext.h"
 #include "IDBValue.h"
 #include "IndexKey.h"
 #include "Logging.h"
@@ -45,13 +46,14 @@ namespace WebCore {
 using namespace JSC;
 namespace IDBServer {
 
-Ref<MemoryObjectStore> MemoryObjectStore::create(const IDBObjectStoreInfo& info)
+Ref<MemoryObjectStore> MemoryObjectStore::create(PAL::SessionID sessionID, const IDBObjectStoreInfo& info)
 {
-    return adoptRef(*new MemoryObjectStore(info));
+    return adoptRef(*new MemoryObjectStore(sessionID, info));
 }
 
-MemoryObjectStore::MemoryObjectStore(const IDBObjectStoreInfo& info)
+MemoryObjectStore::MemoryObjectStore(PAL::SessionID sessionID, const IDBObjectStoreInfo& info)
     : m_info(info)
+    , m_serializationContext(IDBSerializationContext::getOrCreateIDBSerializationContext(sessionID))
 {
 }
 
@@ -299,9 +301,9 @@ void MemoryObjectStore::updateIndexesForDeleteRecord(const IDBKeyData& value)
 
 IDBError MemoryObjectStore::updateIndexesForPutRecord(const IDBKeyData& key, const ThreadSafeDataBuffer& value)
 {
-    JSLockHolder locker(UniqueIDBDatabase::databaseThreadVM());
+    JSLockHolder locker(m_serializationContext->vm());
 
-    auto jsValue = deserializeIDBValueToJSValue(UniqueIDBDatabase::databaseThreadExecState(), value);
+    auto jsValue = deserializeIDBValueToJSValue(m_serializationContext->execState(), value);
     if (jsValue.isUndefinedOrNull())
         return IDBError { };
 
@@ -310,7 +312,7 @@ IDBError MemoryObjectStore::updateIndexesForPutRecord(const IDBKeyData& key, con
 
     for (auto& index : m_indexesByName.values()) {
         IndexKey indexKey;
-        generateIndexKeyForValue(UniqueIDBDatabase::databaseThreadExecState(), index->info(), jsValue, indexKey, m_info.keyPath(), key);
+        generateIndexKeyForValue(m_serializationContext->execState(), index->info(), jsValue, indexKey, m_info.keyPath(), key);
 
         if (indexKey.isNull())
             continue;
@@ -336,15 +338,15 @@ IDBError MemoryObjectStore::populateIndexWithExistingRecords(MemoryIndex& index)
     if (!m_keyValueStore)
         return IDBError { };
 
-    JSLockHolder locker(UniqueIDBDatabase::databaseThreadVM());
+    JSLockHolder locker(m_serializationContext->vm());
 
     for (const auto& iterator : *m_keyValueStore) {
-        auto jsValue = deserializeIDBValueToJSValue(UniqueIDBDatabase::databaseThreadExecState(), iterator.value);
+        auto jsValue = deserializeIDBValueToJSValue(m_serializationContext->execState(), iterator.value);
         if (jsValue.isUndefinedOrNull())
             return IDBError { };
 
         IndexKey indexKey;
-        generateIndexKeyForValue(UniqueIDBDatabase::databaseThreadExecState(), index.info(), jsValue, indexKey, m_info.keyPath(), iterator.key);
+        generateIndexKeyForValue(m_serializationContext->execState(), index.info(), jsValue, indexKey, m_info.keyPath(), iterator.key);
 
         if (indexKey.isNull())
             continue;
index 657b638..ac70108 100644 (file)
 #include <wtf/HashMap.h>
 #include <wtf/RefCounted.h>
 
+namespace PAL {
+class SessionID;
+}
+
 namespace WebCore {
 
 class IDBCursorInfo;
@@ -52,13 +56,14 @@ enum class IndexRecordType;
 
 namespace IDBServer {
 
+class IDBSerializationContext;
 class MemoryBackingStoreTransaction;
 
 typedef HashMap<IDBKeyData, ThreadSafeDataBuffer, IDBKeyDataHash, IDBKeyDataHashTraits> KeyValueMap;
 
 class MemoryObjectStore : public RefCounted<MemoryObjectStore> {
 public:
-    static Ref<MemoryObjectStore> create(const IDBObjectStoreInfo&);
+    static Ref<MemoryObjectStore> create(PAL::SessionID, const IDBObjectStoreInfo&);
 
     ~MemoryObjectStore();
 
@@ -104,7 +109,7 @@ public:
     void renameIndex(MemoryIndex&, const String& newName);
 
 private:
-    MemoryObjectStore(const IDBObjectStoreInfo&);
+    MemoryObjectStore(PAL::SessionID, const IDBObjectStoreInfo&);
 
     IDBKeyDataSet::iterator lowestIteratorInRange(const IDBKeyRangeData&, bool reverse) const;
 
@@ -128,6 +133,8 @@ private:
     HashMap<uint64_t, RefPtr<MemoryIndex>> m_indexesByIdentifier;
     HashMap<String, RefPtr<MemoryIndex>> m_indexesByName;
     HashMap<IDBResourceIdentifier, std::unique_ptr<MemoryObjectStoreCursor>> m_cursors;
+
+    Ref<IDBSerializationContext> m_serializationContext;
 };
 
 } // namespace IDBServer
index bfbd09d..40b6b67 100644 (file)
@@ -38,6 +38,7 @@
 #include "IDBKeyData.h"
 #include "IDBObjectStoreInfo.h"
 #include "IDBSerialization.h"
+#include "IDBSerializationContext.h"
 #include "IDBTransactionInfo.h"
 #include "IDBValue.h"
 #include "IndexKey.h"
@@ -234,6 +235,7 @@ SQLiteIDBBackingStore::SQLiteIDBBackingStore(PAL::SessionID sessionID, const IDB
     , m_databaseRootDirectory(databaseRootDirectory)
     , m_temporaryFileHandler(fileHandler)
     , m_quota(quota)
+    , m_serializationContext(IDBSerializationContext::getOrCreateIDBSerializationContext(sessionID))
 {
     m_databaseDirectory = fullDatabaseDirectoryWithUpgrade();
 }
@@ -242,36 +244,6 @@ SQLiteIDBBackingStore::~SQLiteIDBBackingStore()
 {
     if (m_sqliteDB)
         closeSQLiteDB();
-
-    if (m_vm) {
-        JSLockHolder locker(m_vm.get());
-        m_globalObject.clear();
-        m_vm = nullptr;
-    }
-}
-
-
-void SQLiteIDBBackingStore::initializeVM()
-{
-    if (!m_vm) {
-        ASSERT(!m_globalObject);
-        m_vm = VM::create();
-
-        JSLockHolder locker(m_vm.get());
-        m_globalObject.set(*m_vm, JSGlobalObject::create(*m_vm, JSGlobalObject::createStructure(*m_vm, jsNull())));
-    }
-}
-
-VM& SQLiteIDBBackingStore::vm()
-{
-    initializeVM();
-    return *m_vm;
-}
-
-JSGlobalObject& SQLiteIDBBackingStore::globalObject()
-{
-    initializeVM();
-    return **m_globalObject;
 }
 
 static bool createOrMigrateRecordsTableIfNecessary(SQLiteDatabase& database)
@@ -1732,16 +1704,16 @@ IDBError SQLiteIDBBackingStore::deleteRange(const IDBResourceIdentifier& transac
 
 IDBError SQLiteIDBBackingStore::updateOneIndexForAddRecord(const IDBIndexInfo& info, const IDBKeyData& key, const ThreadSafeDataBuffer& value, int64_t recordID)
 {
-    JSLockHolder locker(vm());
+    JSLockHolder locker(m_serializationContext->vm());
 
-    auto jsValue = deserializeIDBValueToJSValue(*globalObject().globalExec(), value);
+    auto jsValue = deserializeIDBValueToJSValue(m_serializationContext->execState(), value);
     if (jsValue.isUndefinedOrNull())
         return IDBError { };
 
     IndexKey indexKey;
     auto* objectStoreInfo = infoForObjectStore(info.objectStoreIdentifier());
     ASSERT(objectStoreInfo);
-    generateIndexKeyForValue(*m_globalObject->globalExec(), info, jsValue, indexKey, objectStoreInfo->keyPath(), key);
+    generateIndexKeyForValue(m_serializationContext->execState(), info, jsValue, indexKey, objectStoreInfo->keyPath(), key);
 
     if (indexKey.isNull())
         return IDBError { };
@@ -1751,9 +1723,9 @@ IDBError SQLiteIDBBackingStore::updateOneIndexForAddRecord(const IDBIndexInfo& i
 
 IDBError SQLiteIDBBackingStore::updateAllIndexesForAddRecord(const IDBObjectStoreInfo& info, const IDBKeyData& key, const ThreadSafeDataBuffer& value, int64_t recordID)
 {
-    JSLockHolder locker(vm());
+    JSLockHolder locker(m_serializationContext->vm());
 
-    auto jsValue = deserializeIDBValueToJSValue(*globalObject().globalExec(), value);
+    auto jsValue = deserializeIDBValueToJSValue(m_serializationContext->execState(), value);
     if (jsValue.isUndefinedOrNull())
         return IDBError { };
 
@@ -1761,7 +1733,7 @@ IDBError SQLiteIDBBackingStore::updateAllIndexesForAddRecord(const IDBObjectStor
     bool anyRecordsSucceeded = false;
     for (auto& index : info.indexMap().values()) {
         IndexKey indexKey;
-        generateIndexKeyForValue(*m_globalObject->globalExec(), index, jsValue, indexKey, info.keyPath(), key);
+        generateIndexKeyForValue(m_serializationContext->execState(), index, jsValue, indexKey, info.keyPath(), key);
 
         if (indexKey.isNull())
             continue;
index 06dc344..bb907be 100644 (file)
@@ -43,6 +43,7 @@ class SQLiteStatement;
 
 namespace IDBServer {
 
+class IDBSerializationContext;
 class SQLiteIDBCursor;
 
 class SQLiteIDBBackingStore : public IDBBackingStore {
@@ -190,10 +191,6 @@ private:
 
     std::unique_ptr<SQLiteStatement> m_cachedStatements[static_cast<int>(SQL::Count)];
 
-    JSC::VM& vm();
-    JSC::JSGlobalObject& globalObject();
-    void initializeVM();
-
     PAL::SessionID m_sessionID;
     IDBDatabaseIdentifier m_identifier;
     std::unique_ptr<IDBDatabaseInfo> m_databaseInfo;
@@ -207,12 +204,11 @@ private:
     String m_databaseRootDirectory;
     String m_databaseDirectory;
 
-    RefPtr<JSC::VM> m_vm;
-    JSC::Strong<JSC::JSGlobalObject> m_globalObject;
-
     IDBBackingStoreTemporaryFileHandler& m_temporaryFileHandler;
     
     uint64_t m_quota;
+
+    Ref<IDBSerializationContext> m_serializationContext;
 };
 
 } // namespace IDBServer
index 7304974..6f2c7eb 100644 (file)
@@ -1197,23 +1197,6 @@ void UniqueIDBDatabase::putOrAddAfterQuotaCheck(uint64_t taskSize, const IDBRequ
     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performPutOrAdd, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), keyData, value, overwriteMode));
 }
 
-VM& UniqueIDBDatabase::databaseThreadVM()
-{
-    ASSERT(!isMainThread());
-    static VM* vm = &VM::create().leakRef();
-    return *vm;
-}
-
-ExecState& UniqueIDBDatabase::databaseThreadExecState()
-{
-    ASSERT(!isMainThread());
-
-    static NeverDestroyed<Strong<JSGlobalObject>> globalObject(databaseThreadVM(), JSGlobalObject::create(databaseThreadVM(), JSGlobalObject::createStructure(databaseThreadVM(), jsNull())));
-
-    RELEASE_ASSERT(globalObject.get()->globalExec());
-    return *globalObject.get()->globalExec();
-}
-
 void UniqueIDBDatabase::performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData& keyData, const IDBValue& originalRecordValue, IndexedDB::ObjectStoreOverwriteMode overwriteMode)
 {
     ASSERT(!isMainThread());
index 8c2a1b3..2e80860 100644 (file)
 #include <wtf/HashSet.h>
 #include <wtf/ListHashSet.h>
 
-namespace JSC {
-class ExecState;
-class VM;
-}
-
 namespace WebCore {
 
 class IDBError;
@@ -119,9 +114,6 @@ public:
     void handleDelete(IDBConnectionToClient&, const IDBRequestData&);
     void immediateCloseForUserDelete();
 
-    static JSC::VM& databaseThreadVM();
-    static JSC::ExecState& databaseThreadExecState();
-
     bool hardClosedForUserDelete() const { return m_hardClosedForUserDelete; }
 
     uint64_t spaceUsed() const;
index ca46142..83b613c 100644 (file)
@@ -102,6 +102,7 @@ Modules/indexeddb/client/TransactionOperation.cpp
 
 Modules/indexeddb/server/IDBConnectionToClient.cpp
 Modules/indexeddb/server/IDBSerialization.cpp
+Modules/indexeddb/server/IDBSerializationContext.cpp
 Modules/indexeddb/server/IDBServer.cpp
 Modules/indexeddb/server/IndexValueEntry.cpp
 Modules/indexeddb/server/IndexValueStore.cpp
index 4957bab..a7bc3a9 100644 (file)
                931CBD0F161A44E900E4C874 /* ScrollingStateScrollingNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 931CBD09161A44E900E4C874 /* ScrollingStateScrollingNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
                931CBD11161A44E900E4C874 /* ScrollingStateTree.h in Headers */ = {isa = PBXBuildFile; fileRef = 931CBD0B161A44E900E4C874 /* ScrollingStateTree.h */; settings = {ATTRIBUTES = (Private, ); }; };
                931D72F615FE695300C4C07E /* LayoutMilestone.h in Headers */ = {isa = PBXBuildFile; fileRef = 931D72F515FE695300C4C07E /* LayoutMilestone.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               9323B07023061F9700901C8B /* IDBSerializationContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 9323B06F23061E9C00901C8B /* IDBSerializationContext.h */; };
                932CC0B71DFFD158004C0F9F /* MediaTrackConstraints.h in Headers */ = {isa = PBXBuildFile; fileRef = 932CC0B61DFFD158004C0F9F /* MediaTrackConstraints.h */; settings = {ATTRIBUTES = (Private, ); }; };
                932CC0D51DFFD667004C0F9F /* JSMediaTrackConstraints.h in Headers */ = {isa = PBXBuildFile; fileRef = 932CC0D11DFFD667004C0F9F /* JSMediaTrackConstraints.h */; };
                93309DD7099E64920056E581 /* AppendNodeCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 93309D88099E64910056E581 /* AppendNodeCommand.h */; };
                931CBD0A161A44E900E4C874 /* ScrollingStateTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollingStateTree.cpp; sourceTree = "<group>"; };
                931CBD0B161A44E900E4C874 /* ScrollingStateTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollingStateTree.h; sourceTree = "<group>"; };
                931D72F515FE695300C4C07E /* LayoutMilestone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayoutMilestone.h; sourceTree = "<group>"; };
+               9323B06D23061E9B00901C8B /* IDBSerializationContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBSerializationContext.cpp; sourceTree = "<group>"; };
+               9323B06F23061E9C00901C8B /* IDBSerializationContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBSerializationContext.h; sourceTree = "<group>"; };
                9327A94109968D1A0068A546 /* HTMLOptionsCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLOptionsCollection.cpp; sourceTree = "<group>"; };
                932CC0B61DFFD158004C0F9F /* MediaTrackConstraints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaTrackConstraints.h; sourceTree = "<group>"; };
                932CC0D01DFFD667004C0F9F /* JSMediaTrackConstraints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMediaTrackConstraints.cpp; sourceTree = "<group>"; };
                510A58EE1BAB71E000C19282 /* server */ = {
                        isa = PBXGroup;
                        children = (
+                               9323B06D23061E9B00901C8B /* IDBSerializationContext.cpp */,
+                               9323B06F23061E9C00901C8B /* IDBSerializationContext.h */,
                                51BA4AC71BBC5AD600DF3D6D /* IDBBackingStore.h */,
                                516D7D6D1BB5F06500AF7C77 /* IDBConnectionToClient.cpp */,
                                510A58FE1BB07AA500C19282 /* IDBConnectionToClient.h */,
                                BC4918C90BFEA050009D6316 /* JSHTMLIFrameElement.h in Headers */,
                                1AE2AA980A1CDD2D00B42B25 /* JSHTMLImageElement.h in Headers */,
                                A80E7E970A1A83E3007FB8C5 /* JSHTMLInputElement.h in Headers */,
+                               9323B07023061F9700901C8B /* IDBSerializationContext.h in Headers */,
                                836B09561F5F34D9003C3702 /* JSHTMLInputElementEntriesAPI.h in Headers */,
                                A6148A7912E41E3B0044A784 /* JSHTMLKeygenElement.h in Headers */,
                                1AE2AB220A1CE63B00B42B25 /* JSHTMLLabelElement.h in Headers */,