Commit 3dde2144 authored by tkent@chromium.org's avatar tkent@chromium.org

Oilpan: Prepare to make ExecutionContext GarbageCollectedMixin.

We creates closures with ExecutionContexts in LocalFileSystem. The
ExecutionContext needs to be a CrossThreadPersistent data member of
closure. This CL adds ParamStorageTraits specialized to garbage-collected
classes.

This is a preparation to remove RefCounted from Node.

BUG=357163

Review URL: https://codereview.chromium.org/318023002

git-svn-id: svn://svn.chromium.org/blink/trunk@175734 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent c1570f62
......@@ -156,8 +156,6 @@ PassRefPtr<CustomElementLifecycleCallbacks> CustomElementConstructorBuilder::cre
{
ASSERT(!m_prototype.IsEmpty());
RefPtr<ExecutionContext> executionContext = m_scriptState->executionContext();
v8::TryCatch exceptionCatcher;
exceptionCatcher.SetVerbose(true);
......
......@@ -1132,8 +1132,10 @@ private:
virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) OVERRIDE FINAL;
void cloneDataFromDocument(const Document&);
#if !ENABLE(OILPAN)
virtual void refExecutionContext() OVERRIDE FINAL { ref(); }
virtual void derefExecutionContext() OVERRIDE FINAL { deref(); }
#endif
virtual const KURL& virtualURL() const OVERRIDE FINAL; // Same as url(), but needed for ExecutionContext to implement it without a performance loss for direct calls.
virtual KURL virtualCompleteURL(const String&) const OVERRIDE FINAL; // Same as completeURL() for the same reason as above.
......
......@@ -38,6 +38,7 @@
#include "core/frame/DOMTimer.h"
#include "platform/LifecycleContext.h"
#include "platform/Supplementable.h"
#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "wtf/Functional.h"
#include "wtf/OwnPtr.h"
......@@ -60,7 +61,10 @@ class PublicURLManager;
class SecurityOrigin;
class ScriptCallStack;
class ExecutionContext : public LifecycleContext<ExecutionContext>, public Supplementable<ExecutionContext> {
class ExecutionContext
: public WillBeGarbageCollectedMixin
, public LifecycleContext<ExecutionContext>
, public Supplementable<ExecutionContext> {
public:
ExecutionContext();
virtual ~ExecutionContext();
......@@ -107,9 +111,10 @@ public:
// Called after the construction of an ActiveDOMObject to synchronize suspend state.
void suspendActiveDOMObjectIfNeeded(ActiveDOMObject*);
#if !ENABLE(OILPAN)
void ref() { refExecutionContext(); }
void deref() { derefExecutionContext(); }
#endif
// Gets the next id in a circular sequence from 1 to 2^31-1.
int circularSequentialID();
......@@ -133,8 +138,10 @@ private:
bool dispatchErrorEvent(PassRefPtrWillBeRawPtr<ErrorEvent>, AccessControlStatus);
#if !ENABLE(OILPAN)
virtual void refExecutionContext() = 0;
virtual void derefExecutionContext() = 0;
#endif
// LifecycleContext implementation.
// Implementation details for DOMTimer. No other classes should call these functions.
......
......@@ -47,13 +47,17 @@ public:
virtual void close() OVERRIDE { }
};
class NullExecutionContext : public ExecutionContext, public RefCounted<NullExecutionContext> {
class NullExecutionContext : public RefCountedWillBeGarbageCollectedFinalized<NullExecutionContext>, public ExecutionContext {
WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(NullExecutionContext);
public:
void trace(Visitor* visitor) { ExecutionContext::trace(visitor); }
#if !ENABLE(OILPAN)
using RefCounted<NullExecutionContext>::ref;
using RefCounted<NullExecutionContext>::deref;
virtual void refExecutionContext() OVERRIDE { ref(); }
virtual void derefExecutionContext() OVERRIDE { deref(); }
#endif
virtual EventQueue* eventQueue() const OVERRIDE { return m_queue.get(); }
virtual bool tasksNeedSuspension() { return m_tasksNeedSuspension; }
......@@ -95,7 +99,7 @@ private:
TEST(MainThreadTaskRunnerTest, PostTask)
{
RefPtr<NullExecutionContext> context = adoptRef(new NullExecutionContext());
RefPtrWillBeRawPtr<NullExecutionContext> context = adoptRefWillBeNoop(new NullExecutionContext());
OwnPtr<MainThreadTaskRunner> runner = MainThreadTaskRunner::create(context.get());
bool isMarked = false;
......@@ -107,7 +111,7 @@ TEST(MainThreadTaskRunnerTest, PostTask)
TEST(MainThreadTaskRunnerTest, SuspendTask)
{
RefPtr<NullExecutionContext> context = adoptRef(new NullExecutionContext());
RefPtrWillBeRawPtr<NullExecutionContext> context = adoptRefWillBeNoop(new NullExecutionContext());
OwnPtr<MainThreadTaskRunner> runner = MainThreadTaskRunner::create(context.get());
bool isMarked = false;
......@@ -125,7 +129,7 @@ TEST(MainThreadTaskRunnerTest, SuspendTask)
TEST(MainThreadTaskRunnerTest, RemoveRunner)
{
RefPtr<NullExecutionContext> context = adoptRef(new NullExecutionContext());
RefPtrWillBeRawPtr<NullExecutionContext> context = adoptRefWillBeNoop(new NullExecutionContext());
OwnPtr<MainThreadTaskRunner> runner = MainThreadTaskRunner::create(context.get());
bool isMarked = false;
......
......@@ -148,8 +148,10 @@ namespace WebCore {
void addMessageToWorkerConsole(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtr<ScriptCallStack>, ScriptState*);
private:
#if !ENABLE(OILPAN)
virtual void refExecutionContext() OVERRIDE FINAL { ref(); }
virtual void derefExecutionContext() OVERRIDE FINAL { deref(); }
#endif
virtual const KURL& virtualURL() const OVERRIDE FINAL;
virtual KURL virtualCompleteURL(const String&) const OVERRIDE FINAL;
......
......@@ -86,7 +86,7 @@ namespace WebCore {
private:
static void workerObjectDestroyedInternal(ExecutionContext*, WorkerMessagingProxy*);
RefPtr<ExecutionContext> m_executionContext;
RefPtrWillBePersistent<ExecutionContext> m_executionContext;
OwnPtr<WorkerObjectProxy> m_workerObjectProxy;
Worker* m_workerObject;
bool m_mayBeDestroyed;
......
......@@ -74,7 +74,7 @@ protected:
OwnPtr<ErrorCallback> m_errorCallback;
RefPtrWillBePersistent<DOMFileSystemBase> m_fileSystem;
RefPtr<ExecutionContext> m_executionContext;
RefPtrWillBePersistent<ExecutionContext> m_executionContext;
};
// Subclasses ----------------------------------------------------------------
......
......@@ -88,12 +88,12 @@ void LocalFileSystem::resolveURL(ExecutionContext* context, const KURL& fileSyst
RefPtr<CallbackWrapper> wrapper = adoptRef(new CallbackWrapper(callbacks));
requestFileSystemAccessInternal(context,
bind(&LocalFileSystem::resolveURLInternal, this, fileSystemURL, wrapper),
bind(&LocalFileSystem::fileSystemNotAllowedInternal, this, PassRefPtr<ExecutionContext>(context), wrapper));
bind(&LocalFileSystem::fileSystemNotAllowedInternal, this, PassRefPtrWillBeRawPtr<ExecutionContext>(context), wrapper));
}
void LocalFileSystem::requestFileSystem(ExecutionContext* context, FileSystemType type, long long size, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
{
RefPtr<ExecutionContext> contextPtr(context);
RefPtrWillBeRawPtr<ExecutionContext> contextPtr(context);
RefPtr<CallbackWrapper> wrapper = adoptRef(new CallbackWrapper(callbacks));
requestFileSystemAccessInternal(context,
bind(&LocalFileSystem::fileSystemAllowedInternal, this, contextPtr, type, wrapper),
......@@ -102,7 +102,7 @@ void LocalFileSystem::requestFileSystem(ExecutionContext* context, FileSystemTyp
void LocalFileSystem::deleteFileSystem(ExecutionContext* context, FileSystemType type, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
{
RefPtr<ExecutionContext> contextPtr(context);
RefPtrWillBeRawPtr<ExecutionContext> contextPtr(context);
ASSERT(context);
ASSERT_WITH_SECURITY_IMPLICATION(context->isDocument());
......@@ -130,14 +130,14 @@ void LocalFileSystem::requestFileSystemAccessInternal(ExecutionContext* context,
}
void LocalFileSystem::fileSystemNotAllowedInternal(
PassRefPtr<ExecutionContext> context,
PassRefPtrWillBeRawPtr<ExecutionContext> context,
PassRefPtr<CallbackWrapper> callbacks)
{
context->postTask(createCallbackTask(&fileSystemNotAllowed, callbacks->release()));
}
void LocalFileSystem::fileSystemAllowedInternal(
PassRefPtr<ExecutionContext> context,
PassRefPtrWillBeRawPtr<ExecutionContext> context,
FileSystemType type,
PassRefPtr<CallbackWrapper> callbacks)
{
......@@ -153,7 +153,7 @@ void LocalFileSystem::resolveURLInternal(
}
void LocalFileSystem::deleteFileSystemInternal(
PassRefPtr<ExecutionContext> context,
PassRefPtrWillBeRawPtr<ExecutionContext> context,
FileSystemType type,
PassRefPtr<CallbackWrapper> callbacks)
{
......
......@@ -71,10 +71,10 @@ protected:
private:
void requestFileSystemAccessInternal(ExecutionContext*, const Closure& allowed, const Closure& denied);
void fileSystemNotAllowedInternal(PassRefPtr<ExecutionContext>, PassRefPtr<CallbackWrapper>);
void fileSystemAllowedInternal(PassRefPtr<ExecutionContext>, FileSystemType, PassRefPtr<CallbackWrapper>);
void fileSystemNotAllowedInternal(PassRefPtrWillBeRawPtr<ExecutionContext>, PassRefPtr<CallbackWrapper>);
void fileSystemAllowedInternal(PassRefPtrWillBeRawPtr<ExecutionContext>, FileSystemType, PassRefPtr<CallbackWrapper>);
void resolveURLInternal(const KURL&, PassRefPtr<CallbackWrapper>);
void deleteFileSystemInternal(PassRefPtr<ExecutionContext>, FileSystemType, PassRefPtr<CallbackWrapper>);
void deleteFileSystemInternal(PassRefPtrWillBeRawPtr<ExecutionContext>, FileSystemType, PassRefPtr<CallbackWrapper>);
OwnPtr<FileSystemClient> m_client;
};
......
......@@ -53,13 +53,17 @@ public:
virtual void close() OVERRIDE { }
};
class NullExecutionContext FINAL : public ExecutionContext, public RefCounted<NullExecutionContext> {
class NullExecutionContext FINAL : public RefCountedWillBeGarbageCollectedFinalized<NullExecutionContext>, public ExecutionContext {
WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(NullExecutionContext);
public:
void trace(Visitor* visitor) { ExecutionContext::trace(visitor); }
#if !ENABLE(OILPAN)
using RefCounted<NullExecutionContext>::ref;
using RefCounted<NullExecutionContext>::deref;
virtual void refExecutionContext() OVERRIDE { ref(); }
virtual void derefExecutionContext() OVERRIDE { deref(); }
#endif
virtual EventQueue* eventQueue() const OVERRIDE { return m_queue.get(); }
NullExecutionContext();
......@@ -76,7 +80,7 @@ class IDBRequestTest : public testing::Test {
public:
IDBRequestTest()
: m_scope(v8::Isolate::GetCurrent())
, m_executionContext(adoptRef(new NullExecutionContext()))
, m_executionContext(adoptRefWillBeNoop(new NullExecutionContext()))
{
m_scope.scriptState()->setExecutionContext(m_executionContext.get());
}
......@@ -92,7 +96,7 @@ public:
private:
V8TestingScope m_scope;
RefPtr<ExecutionContext> m_executionContext;
RefPtrWillBePersistent<ExecutionContext> m_executionContext;
};
TEST_F(IDBRequestTest, EventsAfterStopping)
......
......@@ -67,7 +67,7 @@ public:
private:
V8TestingScope m_scope;
RefPtr<ExecutionContext> m_executionContext;
RefPtrWillBePersistent<ExecutionContext> m_executionContext;
};
class FakeWebIDBDatabase FINAL : public blink::WebIDBDatabase {
......
......@@ -56,8 +56,7 @@ public:
clear();
}
// FIXME: Oilpan: Trace m_executionContext.
void trace(Visitor* visitor) { }
void trace(Visitor* visitor) { visitor->trace(m_executionContext); }
void clear()
{
......@@ -130,7 +129,7 @@ private:
Mutex m_mutex;
OwnPtr<T> m_callback;
RefPtr<ExecutionContext> m_executionContext;
RefPtrWillBeMember<ExecutionContext> m_executionContext;
};
} // namespace WebCore
......
......@@ -34,6 +34,7 @@
#include "platform/heap/Heap.h"
#include "platform/heap/ThreadState.h"
#include "platform/heap/Visitor.h"
#include "wtf/Functional.h"
#include "wtf/HashFunctions.h"
#include "wtf/Locker.h"
#include "wtf/RawPtr.h"
......@@ -1152,6 +1153,36 @@ struct NeedsTracing<ListHashSetNode<T, WebCore::HeapListHashSetAllocator<T, inli
static const bool value = true;
};
// For wtf/Functional.h
template<typename T, bool isGarbageCollected> struct PointerParamStorageTraits;
template<typename T> struct PointerParamStorageTraits<T*, false> {
typedef T* StorageType;
static StorageType wrap(T* value) { return value; }
static T* unwrap(const StorageType& value) { return value; }
};
template<typename T> struct PointerParamStorageTraits<T*, true> {
typedef WebCore::CrossThreadPersistent<T> StorageType;
static StorageType wrap(T* value) { return value; }
static T* unwrap(const StorageType& value) { return value.get(); }
};
// FIXME: This doesn't support collections and const types. See
// COMPILE_ASSERT_IS_GARBAGE_COLLECTED.
template<typename T> struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, WTF::IsSubclassOfTemplate<T, WebCore::GarbageCollected>::value || WebCore::IsGarbageCollectedMixin<T>::value> {
};
// We assume RawPtr<T> is used only for garbage-collected types.
template<typename T> struct ParamStorageTraits<RawPtr<T> > {
typedef WebCore::CrossThreadPersistent<T> StorageType;
static StorageType wrap(RawPtr<T> value) { return value.get(); }
static T* unwrap(const StorageType& value) { return value.get(); }
};
} // namespace WTF
#endif
......@@ -3978,4 +3978,24 @@ TEST(HeapTest, NeedsAdjustAndMark)
EXPECT_FALSE(NeedsAdjustAndMark<const UseMixin>::value);
}
TEST(HeapTest, Bind)
{
Closure closure = bind(&Bar::trace, Bar::create(), static_cast<Visitor*>(0));
Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
// The closure should have a persistent handle to the Bar.
EXPECT_EQ(1u, Bar::s_live);
Closure closure2 = bind(&Bar::trace, RawPtr<Bar>(Bar::create()), static_cast<Visitor*>(0));
Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
// The closure should have a persistent handle to the Bar.
EXPECT_EQ(2u, Bar::s_live);
UseMixin::s_traceCount = 0;
Mixin* mixin = UseMixin::create();
Closure mixinClosure = bind(&Mixin::trace, mixin, static_cast<Visitor*>(0));
Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
// The closure should have a persistent handle to the mixin.
EXPECT_EQ(1, UseMixin::s_traceCount);
}
} // WebCore namespace
......@@ -131,7 +131,7 @@ private:
void workerGlobalScopeDestroyedOnMainThread();
// 'shadow page' - created to proxy loading requests from the worker.
RefPtr<WebCore::ExecutionContext> m_loadingDocument;
RefPtrWillBePersistent<WebCore::ExecutionContext> m_loadingDocument;
WebView* m_webView;
WebFrame* m_mainFrame;
bool m_askedToTerminate;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment