Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(625)

Unified Diff: third_party/WebKit/Source/platform/heap/Handle.h

Issue 1477023003: Refactor the Heap into ThreadHeap to prepare for per thread heaps Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/heap/Handle.h
diff --git a/third_party/WebKit/Source/platform/heap/Handle.h b/third_party/WebKit/Source/platform/heap/Handle.h
index a585ac832b03ae1955c647e43186b9f5f395c363..eea7f773333979c8cca67292310bc8a428277912 100644
--- a/third_party/WebKit/Source/platform/heap/Handle.h
+++ b/third_party/WebKit/Source/platform/heap/Handle.h
@@ -59,7 +59,8 @@ enum WeaknessPersistentConfiguration {
enum CrossThreadnessPersistentConfiguration {
SingleThreadPersistentConfiguration,
- CrossThreadPersistentConfiguration
+ CrossThreadPersistentConfiguration,
+ XThreadPersistentConfiguration
};
template<typename T, WeaknessPersistentConfiguration weaknessConfiguration, CrossThreadnessPersistentConfiguration crossThreadnessConfiguration>
@@ -203,6 +204,10 @@ private:
NO_LAZY_SWEEP_SANITIZE_ADDRESS
void assign(T* ptr)
{
+ if (crossThreadnessConfiguration == XThreadPersistentConfiguration
+ && ThreadState::forObject(m_raw) != ThreadState::forObject(ptr)) {
+ uninitialize();
+ }
m_raw = ptr;
checkPointer();
if (m_raw) {
@@ -218,11 +223,15 @@ private:
void initialize()
{
ASSERT(!m_persistentNode);
- if (!m_raw)
+ if (!m_raw || m_raw == reinterpret_cast<T*>(-1))
return;
TraceCallback traceCallback = TraceMethodDelegate<PersistentBase<T, weaknessConfiguration, crossThreadnessConfiguration>, &PersistentBase<T, weaknessConfiguration, crossThreadnessConfiguration>::trace>::trampoline;
- if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) {
+ if (crossThreadnessConfiguration == XThreadPersistentConfiguration) {
+ BasePage* page = pageFromObject(m_raw);
+ ASSERT(page);
+ m_persistentNode = page->heap()->threadState()->xThreadPersistentRegion()->allocatePersistentNode(this, traceCallback);
+ } else if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) {
m_persistentNode = ThreadState::crossThreadPersistentRegion().allocatePersistentNode(this, traceCallback);
} else {
ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state();
@@ -239,7 +248,13 @@ private:
if (!m_persistentNode)
return;
- if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) {
+ if (crossThreadnessConfiguration == XThreadPersistentConfiguration) {
+ ASSERT(m_raw);
+ ASSERT(m_raw != reinterpret_cast<T*>(-1));
+ BasePage* page = pageFromObject(m_raw);
+ ASSERT(page);
+ page->heap()->threadState()->xThreadPersistentRegion()->freePersistentNode(m_persistentNode);
+ } else if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) {
ThreadState::crossThreadPersistentRegion().freePersistentNode(m_persistentNode);
} else {
ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state();
@@ -253,6 +268,10 @@ private:
void checkPointer()
{
+ if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) {
+ ThreadState* threadState = ThreadState::forObject(m_raw);
+ ASSERT(!threadState || !threadState->perThreadHeapEnabled());
+ }
#if ENABLE(ASSERT) && defined(ADDRESS_SANITIZER)
if (!m_raw)
return;
@@ -525,6 +544,69 @@ public:
}
};
+template<typename T>
+class XThreadPersistent : public PersistentBase<T, NonWeakPersistentConfiguration, XThreadPersistentConfiguration> {
haraken 2016/01/07 08:06:22 I'm considering a way to land the per-thread heap
+ typedef PersistentBase<T, NonWeakPersistentConfiguration, XThreadPersistentConfiguration> Parent;
+public:
+ XThreadPersistent() : Parent() { }
+ XThreadPersistent(std::nullptr_t) : Parent(nullptr) { }
+ XThreadPersistent(T* raw) : Parent(raw) { }
+ XThreadPersistent(T& raw) : Parent(raw) { }
+ XThreadPersistent(const XThreadPersistent& other) : Parent(other) { }
+ template<typename U>
+ XThreadPersistent(const XThreadPersistent<U>& other) : Parent(other) { }
+ template<typename U>
+ XThreadPersistent(const Member<U>& other) : Parent(other) { }
+ template<typename U>
+ XThreadPersistent(const RawPtr<U>& other) : Parent(other.get()) { }
+
+ template<typename U>
+ XThreadPersistent& operator=(U* other)
+ {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ XThreadPersistent& operator=(std::nullptr_t)
+ {
+ Parent::operator=(nullptr);
+ return *this;
+ }
+
+ XThreadPersistent& operator=(const XThreadPersistent& other)
+ {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ template<typename U>
+ XThreadPersistent& operator=(const XThreadPersistent<U>& other)
+ {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ template<typename U>
+ XThreadPersistent& operator=(const Member<U>& other)
+ {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ template<typename U>
+ XThreadPersistent& operator=(const RawPtr<U>& other)
+ {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ explicit XThreadPersistent(WTF::HashTableDeletedValueType) : Parent(reinterpret_cast<T*>(-1))
+ {
+ }
+
+ bool isHashTableDeletedValue() const { return *this == reinterpret_cast<T*>(-1); }
+};
+
template<typename Collection>
class PersistentHeapCollectionBase : public Collection {
// We overload the various new and delete operators with using the WTF PartitionAllocator to ensure persistent
@@ -1030,12 +1112,15 @@ class PLATFORM_EXPORT DummyBase<void> { };
#define RefPtrWillBeWeakMember blink::WeakMember
#define RefPtrWillBeWeakPersistent blink::WeakPersistent
#define RefPtrWillBeCrossThreadPersistent blink::CrossThreadPersistent
+#define RefPtrWillBeXThreadPersistent blink::XThreadPersistent
#define RawPtrWillBeMember blink::Member
#define RawPtrWillBePersistent blink::Persistent
+#define RawPtrWillBeXThreadPersistent blink::XThreadPersistent
#define RawPtrWillBeWeakMember blink::WeakMember
#define RawPtrWillBeWeakPersistent blink::WeakPersistent
#define RawPtrWillBeUntracedMember blink::UntracedMember
#define OwnPtrWillBeCrossThreadPersistent blink::CrossThreadPersistent
+#define OwnPtrWillBeXThreadPersistent blink::XThreadPersistent
#define OwnPtrWillBeMember blink::Member
#define OwnPtrWillBePersistent blink::Persistent
#define OwnPtrWillBeRawPtr WTF::RawPtr
@@ -1121,12 +1206,15 @@ template<typename T> T* adoptPtrWillBeNoop(T* ptr)
#define RefPtrWillBeWeakMember WTF::RefPtr
#define RefPtrWillBeWeakPersistent WTF::RefPtr
#define RefPtrWillBeCrossThreadPersistent WTF::RefPtr
+#define RefPtrWillBeXThreadPersistent WTF::RefPtr
#define RawPtrWillBeMember WTF::RawPtr
#define RawPtrWillBePersistent WTF::RawPtr
+#define RawPtrWillBeXThreadPersistent WTF::RawPtr
#define RawPtrWillBeWeakMember WTF::RawPtr
#define RawPtrWillBeWeakPersistent WTF::RawPtr
#define RawPtrWillBeUntracedMember WTF::RawPtr
#define OwnPtrWillBeCrossThreadPersistent WTF::OwnPtr
+#define OwnPtrWillBeXThreadPersistent WTF::OwnPtr
#define OwnPtrWillBeMember WTF::OwnPtr
#define OwnPtrWillBePersistent WTF::OwnPtr
#define OwnPtrWillBeRawPtr WTF::OwnPtr
@@ -1542,7 +1630,7 @@ struct PointerParamStorageTraits<T*, false> {
template<typename T>
struct PointerParamStorageTraits<T*, true> {
static_assert(sizeof(T), "T must be fully defined");
- using StorageType = blink::CrossThreadPersistent<T>;
+ using StorageType = blink::XThreadPersistent<T>;
static StorageType wrap(T* value) { return value; }
static T* unwrap(const StorageType& value) { return value.get(); }
@@ -1573,6 +1661,43 @@ struct ParamStorageTraits<blink::AllowCrossThreadWeakPersistent<T>> {
template<typename T>
PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete;
+template<typename T> struct HashTraits<blink::XThreadPersistent<T>> : SimpleClassHashTraits<blink::XThreadPersistent<T>> {
+ static const bool emptyValueIsZero = false; // Persistent's constructor needs to be called properly.
+
+ // FIXME: The distinction between PeekInType and PassInType is there for
+ // the sake of the reference counting handles. When they are gone the two
+ // types can be merged into PassInType.
+ // FIXME: Implement proper const'ness for iterator types. Requires support
+ // in the marking Visitor.
+ using PeekInType = const blink::XThreadPersistent<T>&;
+ using PassInType = const blink::XThreadPersistent<T>&;
+ using IteratorGetType = blink::XThreadPersistent<T>*;
+ using IteratorConstGetType = const blink::XThreadPersistent<T>*;
+ using IteratorReferenceType = blink::XThreadPersistent<T>&;
+ using IteratorConstReferenceType = const blink::XThreadPersistent<T>&;
+ static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return *x; }
+ static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return *x; }
+ // FIXME: Similarly, there is no need for a distinction between PeekOutType
+ // and PassOutType without reference counting.
+ using PeekOutType = T*;
+ using PassOutType = T*;
+
+ template<typename U>
+ static void store(const U& value, blink::Persistent<T>& storage) { storage = value; }
+
+ static PeekOutType peek(const blink::XThreadPersistent<T>& value) { return value; }
+ static PassOutType passOut(const blink::XThreadPersistent<T>& value) { return value; }
+};
+
+template<typename T> struct PtrHash<blink::XThreadPersistent<T>> : PtrHash<T*> {
+ static unsigned hash(const blink::XThreadPersistent<T>& key) { return PtrHash<T*>::hash(key.get()); }
+ static bool equal(const blink::XThreadPersistent<T>& a, const blink::XThreadPersistent<T>& b) { return a == b; }
+};
+
+template<typename T> struct DefaultHash<blink::XThreadPersistent<T>> {
+ using Hash = PtrHash<blink::XThreadPersistent<T>>;
+};
+
} // namespace WTF
#endif

Powered by Google App Engine
This is Rietveld 408576698