WebKit Bugzilla
Attachment 356426 Details for
Bug 192270
: Let JSDOMGlobalObject in uniqueIDBDatabase be deleted if no database is using it
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-192270-20181203155222.patch (text/plain), 12.82 KB, created by
Sihui Liu
on 2018-12-03 15:52:23 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Sihui Liu
Created:
2018-12-03 15:52:23 PST
Size:
12.82 KB
patch
obsolete
>Subversion Revision: 238822 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 37b4951e51b52f51bea852f50a0bd8027e76fb8a..310a23374015bf69fdce92e6a4c45e3730604c94 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,32 @@ >+2018-12-03 Sihui Liu <sihui_liu@apple.com> >+ >+ Let JSDOMGlobalObject in uniqueIDBDatabase be deleted if no database is using it >+ https://bugs.webkit.org/show_bug.cgi?id=192270 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Optimized UniqueIDBDatabase to not keep Global object and its vm forever, because they are >+ only used for serialization and deserialization of JavaScript values in IDB. >+ >+ No behavior change. >+ >+ * Modules/indexeddb/server/MemoryObjectStore.cpp: >+ (WebCore::IDBServer::MemoryObjectStore::updateIndexesForPutRecord): >+ (WebCore::IDBServer::MemoryObjectStore::populateIndexWithExistingRecords): >+ * Modules/indexeddb/server/MemoryObjectStore.h: >+ * Modules/indexeddb/server/UniqueIDBDatabase.cpp: >+ (WebCore::IDBServer::IDBSerializationContext::create): >+ (WebCore::IDBServer::IDBSerializationContext::IDBSerializationContext): >+ (WebCore::IDBServer::IDBSerializationContext::~IDBSerializationContext): >+ (WebCore::IDBServer::IDBSerializationContext::vm): >+ (WebCore::IDBServer::IDBSerializationContext::execState): >+ (WebCore::IDBServer::UniqueIDBDatabase::UniqueIDBDatabase): >+ (WebCore::IDBServer::UniqueIDBDatabase::sharedIDBSerializationContext): >+ (WebCore::IDBServer::UniqueIDBDatabase::performPutOrAdd): >+ (WebCore::IDBServer::UniqueIDBDatabase::databaseThreadVM): Deleted. >+ (WebCore::IDBServer::UniqueIDBDatabase::databaseThreadExecState): Deleted. >+ * Modules/indexeddb/server/UniqueIDBDatabase.h: >+ > 2018-12-03 Alex Christensen <achristensen@webkit.org> > > Add WKWebProcessPlugInLoadDelegate SPI willStartProvisionalLoadForFrame with a completion handler >diff --git a/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.cpp b/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.cpp >index 5cded3e58815008c757a8f869172181640754352..9ae013a9fe6d350280af3745005635eb2d27cddf 100644 >--- a/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.cpp >+++ b/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.cpp >@@ -299,9 +299,10 @@ void MemoryObjectStore::updateIndexesForDeleteRecord(const IDBKeyData& value) > > IDBError MemoryObjectStore::updateIndexesForPutRecord(const IDBKeyData& key, const ThreadSafeDataBuffer& value) > { >- JSLockHolder locker(UniqueIDBDatabase::databaseThreadVM()); >+ auto context = UniqueIDBDatabase::sharedIDBSerializationContext(); >+ JSLockHolder locker(context->vm()); > >- auto jsValue = deserializeIDBValueToJSValue(UniqueIDBDatabase::databaseThreadExecState(), value); >+ auto jsValue = deserializeIDBValueToJSValue(context->execState(), value); > if (jsValue.isUndefinedOrNull()) > return IDBError { }; > >@@ -310,7 +311,7 @@ IDBError MemoryObjectStore::updateIndexesForPutRecord(const IDBKeyData& key, con > > for (auto& index : m_indexesByName.values()) { > IndexKey indexKey; >- generateIndexKeyForValue(UniqueIDBDatabase::databaseThreadExecState(), index->info(), jsValue, indexKey); >+ generateIndexKeyForValue(context->execState(), index->info(), jsValue, indexKey); > > if (indexKey.isNull()) > continue; >@@ -336,15 +337,16 @@ IDBError MemoryObjectStore::populateIndexWithExistingRecords(MemoryIndex& index) > if (!m_keyValueStore) > return IDBError { }; > >- JSLockHolder locker(UniqueIDBDatabase::databaseThreadVM()); >+ auto context = UniqueIDBDatabase::sharedIDBSerializationContext(); >+ JSLockHolder locker(context->vm()); > > for (auto iterator : *m_keyValueStore) { >- auto jsValue = deserializeIDBValueToJSValue(UniqueIDBDatabase::databaseThreadExecState(), iterator.value); >+ auto jsValue = deserializeIDBValueToJSValue(context->execState(), iterator.value); > if (jsValue.isUndefinedOrNull()) > return IDBError { }; > > IndexKey indexKey; >- generateIndexKeyForValue(UniqueIDBDatabase::databaseThreadExecState(), index.info(), jsValue, indexKey); >+ generateIndexKeyForValue(context->execState(), index.info(), jsValue, indexKey); > > if (indexKey.isNull()) > continue; >diff --git a/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.h b/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.h >index 5b3d833e556f6cc917c08802a35c078116d87318..5bfc0966fb9642d81ee37af9949fb026d9cafd89 100644 >--- a/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.h >+++ b/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.h >@@ -32,6 +32,7 @@ > #include "MemoryIndex.h" > #include "MemoryObjectStoreCursor.h" > #include "ThreadSafeDataBuffer.h" >+#include "UniqueIDBDatabase.h" > #include <wtf/HashMap.h> > #include <wtf/RefCounted.h> > >diff --git a/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp b/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp >index fc07ef1451b97e075cd3a56f620093a349c0cbc9..163554f179ec451dfd681a684f436f11b0a6a0a9 100644 >--- a/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp >+++ b/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp >@@ -46,8 +46,6 @@ > #include "WebCoreJSClientData.h" > #include <JavaScriptCore/AuxiliaryBarrierInlines.h> > #include <JavaScriptCore/HeapInlines.h> >-#include <JavaScriptCore/StrongInlines.h> >-#include <JavaScriptCore/StructureInlines.h> > #include <wtf/MainThread.h> > #include <wtf/NeverDestroyed.h> > #include <wtf/Scope.h> >@@ -56,10 +54,46 @@ namespace WebCore { > using namespace JSC; > namespace IDBServer { > >+Ref<IDBSerializationContext> IDBSerializationContext::create() >+{ >+ return adoptRef(*new IDBSerializationContext); >+} >+ >+IDBSerializationContext::IDBSerializationContext() >+ : m_vm(JSC::VM::create()) >+{ >+ m_vm->heap.acquireAccess(); >+ JSVMClientData::initNormalWorld(m_vm.get()); >+ >+ JSC::JSLockHolder locker(m_vm.get()); >+ m_globalDOMObject = JSC::Strong<JSDOMGlobalObject>(*m_vm, JSDOMGlobalObject::create(*m_vm, JSDOMGlobalObject::createStructure(*m_vm, JSC::jsNull()), normalWorld(*m_vm))); >+} >+ >+IDBSerializationContext::~IDBSerializationContext() >+{ >+ if (m_vm) { >+ JSC::JSLockHolder locker(m_vm.get()); >+ m_globalDOMObject.clear(); >+ m_vm = nullptr; >+ } >+} >+ >+VM& IDBSerializationContext::vm() >+{ >+ return *m_vm; >+} >+ >+ExecState& IDBSerializationContext::execState() >+{ >+ RELEASE_ASSERT(m_globalDOMObject.get()->globalExec()); >+ return *m_globalDOMObject.get()->globalExec(); >+} >+ > UniqueIDBDatabase::UniqueIDBDatabase(IDBServer& server, const IDBDatabaseIdentifier& identifier) > : m_server(server) > , m_identifier(identifier) > , m_operationAndTransactionTimer(*this, &UniqueIDBDatabase::operationAndTransactionTimerFired) >+ , m_serializationContext(sharedIDBSerializationContext()) > { > LOG(IndexedDB, "UniqueIDBDatabase::UniqueIDBDatabase() (%p) %s", this, m_identifier.debugString().utf8().data()); > } >@@ -936,26 +970,15 @@ void UniqueIDBDatabase::putOrAdd(const IDBRequestData& requestData, const IDBKey > postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performPutOrAdd, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), keyData, value, overwriteMode)); > } > >-VM& UniqueIDBDatabase::databaseThreadVM() >-{ >- ASSERT(!isMainThread()); >- static VM* vm = &VM::create().leakRef(); >- if (!vm->heap.hasAccess()) { >- vm->heap.acquireAccess(); >- JSVMClientData::initNormalWorld(vm); >- } >- >- return *vm; >-} >- >-ExecState& UniqueIDBDatabase::databaseThreadExecState() >+RefPtr<IDBSerializationContext> UniqueIDBDatabase::sharedIDBSerializationContext() > { >- ASSERT(!isMainThread()); >- >- static NeverDestroyed<Strong<JSDOMGlobalObject>> domGlobalObject(databaseThreadVM(), JSDOMGlobalObject::create(databaseThreadVM(), JSDOMGlobalObject::createStructure(databaseThreadVM(), jsNull()), normalWorld(databaseThreadVM()))); >+ static NeverDestroyed<WeakPtr<IDBSerializationContext>> s_context; >+ if (s_context.get()) >+ return makeRefPtr(s_context.get().get()); > >- RELEASE_ASSERT(domGlobalObject.get()->globalExec()); >- return *domGlobalObject.get()->globalExec(); >+ auto newContext = IDBSerializationContext::create(); >+ s_context.get() = makeWeakPtr(newContext.ptr()); >+ return makeRefPtr(newContext.get()); > } > > void UniqueIDBDatabase::performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData& keyData, const IDBValue& originalRecordValue, IndexedDB::ObjectStoreOverwriteMode overwriteMode) >@@ -1011,22 +1034,22 @@ void UniqueIDBDatabase::performPutOrAdd(uint64_t callbackIdentifier, const IDBRe > // using steps to assign a key to a value using a key path. > ThreadSafeDataBuffer injectedRecordValue; > if (usedKeyIsGenerated && objectStoreInfo->keyPath()) { >- VM& vm = databaseThreadVM(); >+ VM& vm = m_serializationContext->vm(); > JSLockHolder locker(vm); > auto scope = DECLARE_THROW_SCOPE(vm); > >- auto value = deserializeIDBValueToJSValue(databaseThreadExecState(), originalRecordValue.data()); >+ auto value = deserializeIDBValueToJSValue(m_serializationContext->execState(), originalRecordValue.data()); > if (value.isUndefined()) { > postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, IDBError(ConstraintError, "Unable to deserialize record value for record key injection"_s), usedKey)); > return; > } > >- if (!injectIDBKeyIntoScriptValue(databaseThreadExecState(), usedKey, value, objectStoreInfo->keyPath().value())) { >+ if (!injectIDBKeyIntoScriptValue(m_serializationContext->execState(), usedKey, value, objectStoreInfo->keyPath().value())) { > postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, IDBError(ConstraintError, "Unable to inject record key into record value"_s), usedKey)); > return; > } > >- auto serializedValue = SerializedScriptValue::create(databaseThreadExecState(), value); >+ auto serializedValue = SerializedScriptValue::create(m_serializationContext->execState(), value); > if (UNLIKELY(scope.exception())) { > postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, IDBError(ConstraintError, "Unable to serialize record value after injecting record key"_s), usedKey)); > return; >diff --git a/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h b/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h >index d46dfa903cfb35ed7c3538e21c3e2d6c4ab87480..f4f004e7c9d46fb2bc28c17c84617476a1763b90 100644 >--- a/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h >+++ b/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h >@@ -35,6 +35,8 @@ > #include "Timer.h" > #include "UniqueIDBDatabaseConnection.h" > #include "UniqueIDBDatabaseTransaction.h" >+#include <JavaScriptCore/StrongInlines.h> >+#include <JavaScriptCore/StructureInlines.h> > #include <wtf/CrossThreadQueue.h> > #include <wtf/CrossThreadTask.h> > #include <wtf/Deque.h> >@@ -54,6 +56,7 @@ class IDBError; > class IDBGetAllResult; > class IDBRequestData; > class IDBTransactionInfo; >+class JSDOMGlobalObject; > > enum class IDBGetRecordDataType; > >@@ -72,6 +75,18 @@ typedef Function<void(const IDBError&, const IDBGetResult&)> GetResultCallback; > typedef Function<void(const IDBError&, const IDBGetAllResult&)> GetAllResultsCallback; > typedef Function<void(const IDBError&, uint64_t)> CountCallback; > >+class IDBSerializationContext : public RefCounted<IDBSerializationContext>, public CanMakeWeakPtr<IDBSerializationContext> { >+public: >+ static Ref<IDBSerializationContext> create(); >+ ~IDBSerializationContext(); >+ JSC::VM& vm(); >+ JSC::ExecState& execState(); >+private: >+ IDBSerializationContext(); >+ RefPtr<JSC::VM> m_vm; >+ JSC::Strong<JSDOMGlobalObject> m_globalDOMObject; >+}; >+ > class UniqueIDBDatabase : public CanMakeWeakPtr<UniqueIDBDatabase> { > public: > UniqueIDBDatabase(IDBServer&, const IDBDatabaseIdentifier&); >@@ -113,8 +128,7 @@ public: > void handleDelete(IDBConnectionToClient&, const IDBRequestData&); > void immediateCloseForUserDelete(); > >- static JSC::VM& databaseThreadVM(); >- static JSC::ExecState& databaseThreadExecState(); >+ static RefPtr<IDBSerializationContext> sharedIDBSerializationContext(); > > bool hardClosedForUserDelete() const { return m_hardClosedForUserDelete; } > >@@ -271,6 +285,8 @@ private: > std::unique_ptr<UniqueIDBDatabase> m_owningPointerForClose; > > HashSet<IDBResourceIdentifier> m_cursorPrefetches; >+ >+ RefPtr<IDBSerializationContext> m_serializationContext; > }; > > } // namespace IDBServer
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
ggaren
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 192270
:
356268
|
356284
| 356426