| Index: third_party/WebKit/Source/platform/heap/Persistent.h
|
| diff --git a/third_party/WebKit/Source/platform/heap/Handle.h b/third_party/WebKit/Source/platform/heap/Persistent.h
|
| similarity index 63%
|
| copy from third_party/WebKit/Source/platform/heap/Handle.h
|
| copy to third_party/WebKit/Source/platform/heap/Persistent.h
|
| index 432b9d7c1885e01acfe50a1def69a37b9ffaf6c3..8aa3708af2df13521feaaa734413965cde3ac299 100644
|
| --- a/third_party/WebKit/Source/platform/heap/Handle.h
|
| +++ b/third_party/WebKit/Source/platform/heap/Persistent.h
|
| @@ -1,50 +1,14 @@
|
| -/*
|
| - * Copyright (C) 2014 Google 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:
|
| - *
|
| - * * Redistributions of source code must retain the above copyright
|
| - * notice, this list of conditions and the following disclaimer.
|
| - * * 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.
|
| - * * Neither the name of Google Inc. nor the names of its
|
| - * contributors may be used to endorse or promote products derived from
|
| - * this software without specific prior written permission.
|
| - *
|
| - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
|
| - * OWNER OR 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.
|
| - */
|
| -
|
| -#ifndef Handle_h
|
| -#define Handle_h
|
| -
|
| -#include "platform/heap/Heap.h"
|
| -#include "platform/heap/HeapAllocator.h"
|
| -#include "platform/heap/InlinedGlobalMarkingVisitor.h"
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef Persistent_h
|
| +#define Persistent_h
|
| +
|
| +#include "platform/heap/Member.h"
|
| #include "platform/heap/PersistentNode.h"
|
| -#include "platform/heap/ThreadState.h"
|
| -#include "platform/heap/TraceTraits.h"
|
| -#include "platform/heap/Visitor.h"
|
| #include "wtf/Allocator.h"
|
| #include "wtf/Atomics.h"
|
| -#include "wtf/HashFunctions.h"
|
| -
|
| -#if defined(LEAK_SANITIZER)
|
| -#include "wtf/LeakAnnotations.h"
|
| -#endif
|
|
|
| namespace blink {
|
|
|
| @@ -665,378 +629,6 @@ public:
|
| }
|
| };
|
|
|
| -// Members are used in classes to contain strong pointers to other oilpan heap
|
| -// allocated objects.
|
| -// All Member fields of a class must be traced in the class' trace method.
|
| -// During the mark phase of the GC all live objects are marked as live and
|
| -// all Member fields of a live object will be traced marked as live as well.
|
| -template<typename T>
|
| -class Member {
|
| - DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
|
| -public:
|
| - Member() : m_raw(nullptr)
|
| - {
|
| - }
|
| -
|
| - Member(std::nullptr_t) : m_raw(nullptr)
|
| - {
|
| - }
|
| -
|
| - Member(T* raw) : m_raw(raw)
|
| - {
|
| - checkPointer();
|
| - }
|
| -
|
| - explicit Member(T& raw) : m_raw(&raw)
|
| - {
|
| - checkPointer();
|
| - }
|
| -
|
| - Member(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1))
|
| - {
|
| - }
|
| -
|
| - bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>(-1); }
|
| -
|
| - template<typename U>
|
| - Member(const Persistent<U>& other) : m_raw(other)
|
| - {
|
| - checkPointer();
|
| - }
|
| -
|
| - Member(const Member& other) : m_raw(other)
|
| - {
|
| - checkPointer();
|
| - }
|
| -
|
| - template<typename U>
|
| - Member(const Member<U>& other) : m_raw(other)
|
| - {
|
| - checkPointer();
|
| - }
|
| -
|
| - T* release()
|
| - {
|
| - T* result = m_raw;
|
| - m_raw = nullptr;
|
| - return result;
|
| - }
|
| -
|
| - explicit operator bool() const { return m_raw; }
|
| -
|
| - operator T*() const { return m_raw; }
|
| -
|
| - T* operator->() const { return m_raw; }
|
| - T& operator*() const { return *m_raw; }
|
| -
|
| - template<typename U>
|
| - Member& operator=(const Persistent<U>& other)
|
| - {
|
| - m_raw = other;
|
| - checkPointer();
|
| - return *this;
|
| - }
|
| -
|
| - template<typename U>
|
| - Member& operator=(const Member<U>& other)
|
| - {
|
| - m_raw = other;
|
| - checkPointer();
|
| - return *this;
|
| - }
|
| -
|
| - template<typename U>
|
| - Member& operator=(U* other)
|
| - {
|
| - m_raw = other;
|
| - checkPointer();
|
| - return *this;
|
| - }
|
| -
|
| - Member& operator=(std::nullptr_t)
|
| - {
|
| - m_raw = nullptr;
|
| - return *this;
|
| - }
|
| -
|
| - void swap(Member<T>& other)
|
| - {
|
| - std::swap(m_raw, other.m_raw);
|
| - checkPointer();
|
| - }
|
| -
|
| - T* get() const { return m_raw; }
|
| -
|
| - void clear() { m_raw = nullptr; }
|
| -
|
| -
|
| -protected:
|
| - void checkPointer()
|
| - {
|
| -#if ENABLE(ASSERT) && defined(ADDRESS_SANITIZER)
|
| - if (!m_raw)
|
| - return;
|
| - // HashTable can store a special value (which is not aligned to the
|
| - // allocation granularity) to Member<> to represent a deleted entry.
|
| - // Thus we treat a pointer that is not aligned to the granularity
|
| - // as a valid pointer.
|
| - if (reinterpret_cast<intptr_t>(m_raw) % allocationGranularity)
|
| - return;
|
| -
|
| - // TODO(haraken): What we really want to check here is that the pointer
|
| - // is a traceable object. In other words, the pointer is either of:
|
| - //
|
| - // (a) a pointer to the head of an on-heap object.
|
| - // (b) a pointer to the head of an on-heap mixin object.
|
| - //
|
| - // We can check it by calling ThreadHeap::isHeapObjectAlive(m_raw),
|
| - // but we cannot call it here because it requires to include T.h.
|
| - // So we currently only try to implement the check for (a), but do
|
| - // not insist that T's definition is in scope.
|
| - if (IsFullyDefined<T>::value && !IsGarbageCollectedMixin<T>::value)
|
| - ASSERT(HeapObjectHeader::fromPayload(m_raw)->checkHeader());
|
| -#endif
|
| - }
|
| -
|
| - T* m_raw;
|
| -
|
| - template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStrongly z, typename U, typename V> friend struct CollectionBackingTraceTrait;
|
| - friend class Visitor;
|
| -
|
| -};
|
| -
|
| -// WeakMember is similar to Member in that it is used to point to other oilpan
|
| -// heap allocated objects.
|
| -// However instead of creating a strong pointer to the object, the WeakMember creates
|
| -// a weak pointer, which does not keep the pointee alive. Hence if all pointers to
|
| -// to a heap allocated object are weak the object will be garbage collected. At the
|
| -// time of GC the weak pointers will automatically be set to null.
|
| -template<typename T>
|
| -class WeakMember : public Member<T> {
|
| -public:
|
| - WeakMember() : Member<T>() { }
|
| -
|
| - WeakMember(std::nullptr_t) : Member<T>(nullptr) { }
|
| -
|
| - WeakMember(T* raw) : Member<T>(raw) { }
|
| -
|
| - WeakMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { }
|
| -
|
| - template<typename U>
|
| - WeakMember(const Persistent<U>& other) : Member<T>(other) { }
|
| -
|
| - template<typename U>
|
| - WeakMember(const Member<U>& other) : Member<T>(other) { }
|
| -
|
| - template<typename U>
|
| - WeakMember& operator=(const Persistent<U>& other)
|
| - {
|
| - this->m_raw = other;
|
| - this->checkPointer();
|
| - return *this;
|
| - }
|
| -
|
| - template<typename U>
|
| - WeakMember& operator=(const Member<U>& other)
|
| - {
|
| - this->m_raw = other;
|
| - this->checkPointer();
|
| - return *this;
|
| - }
|
| -
|
| - template<typename U>
|
| - WeakMember& operator=(U* other)
|
| - {
|
| - this->m_raw = other;
|
| - this->checkPointer();
|
| - return *this;
|
| - }
|
| -
|
| - WeakMember& operator=(std::nullptr_t)
|
| - {
|
| - this->m_raw = nullptr;
|
| - return *this;
|
| - }
|
| -
|
| -private:
|
| - T** cell() const { return const_cast<T**>(&this->m_raw); }
|
| -
|
| - template<typename Derived> friend class VisitorHelper;
|
| -};
|
| -
|
| -// UntracedMember is a pointer to an on-heap object that is not traced for some
|
| -// reason. Please don't use this unless you understand what you're doing.
|
| -// Basically, all pointers to on-heap objects must be stored in either of
|
| -// Persistent, Member or WeakMember. It is not allowed to leave raw pointers to
|
| -// on-heap objects. However, there can be scenarios where you have to use raw
|
| -// pointers for some reason, and in that case you can use UntracedMember. Of
|
| -// course, it must be guaranteed that the pointing on-heap object is kept alive
|
| -// while the raw pointer is pointing to the object.
|
| -template<typename T>
|
| -class UntracedMember final : public Member<T> {
|
| -public:
|
| - UntracedMember() : Member<T>() { }
|
| -
|
| - UntracedMember(std::nullptr_t) : Member<T>(nullptr) { }
|
| -
|
| - UntracedMember(T* raw) : Member<T>(raw) { }
|
| -
|
| - template<typename U>
|
| - UntracedMember(const Persistent<U>& other) : Member<T>(other) { }
|
| -
|
| - template<typename U>
|
| - UntracedMember(const Member<U>& other) : Member<T>(other) { }
|
| -
|
| - UntracedMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { }
|
| -
|
| - template<typename U>
|
| - UntracedMember& operator=(const Persistent<U>& other)
|
| - {
|
| - this->m_raw = other;
|
| - this->checkPointer();
|
| - return *this;
|
| - }
|
| -
|
| - template<typename U>
|
| - UntracedMember& operator=(const Member<U>& other)
|
| - {
|
| - this->m_raw = other;
|
| - this->checkPointer();
|
| - return *this;
|
| - }
|
| -
|
| - template<typename U>
|
| - UntracedMember& operator=(U* other)
|
| - {
|
| - this->m_raw = other;
|
| - this->checkPointer();
|
| - return *this;
|
| - }
|
| -
|
| - UntracedMember& operator=(std::nullptr_t)
|
| - {
|
| - this->m_raw = nullptr;
|
| - return *this;
|
| - }
|
| -};
|
| -
|
| -// Comparison operators between (Weak)Members, Persistents, and UntracedMembers.
|
| -template<typename T, typename U> inline bool operator==(const Member<T>& a, const Member<U>& b) { return a.get() == b.get(); }
|
| -template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Member<U>& b) { return a.get() != b.get(); }
|
| -template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Persistent<U>& b) { return a.get() == b.get(); }
|
| -template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Persistent<U>& b) { return a.get() != b.get(); }
|
| -
|
| -template<typename T, typename U> inline bool operator==(const Member<T>& a, const Persistent<U>& b) { return a.get() == b.get(); }
|
| -template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Persistent<U>& b) { return a.get() != b.get(); }
|
| -template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Member<U>& b) { return a.get() == b.get(); }
|
| -template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Member<U>& b) { return a.get() != b.get(); }
|
| -
|
| -template<typename T, bool = IsGarbageCollectedType<T>::value>
|
| -class RawPtrOrMemberTrait {
|
| - STATIC_ONLY(RawPtrOrMemberTrait)
|
| -public:
|
| - using Type = T*;
|
| -};
|
| -
|
| -template<typename T>
|
| -class RawPtrOrMemberTrait<T, true> {
|
| - STATIC_ONLY(RawPtrOrMemberTrait)
|
| -public:
|
| - using Type = Member<T>;
|
| -};
|
| -
|
| -// Abstraction for injecting calls to an object's 'dispose()' method
|
| -// on leaving a stack scope, ensuring earlier release of resources
|
| -// than waiting until the object is eventually GCed.
|
| -template<typename T, void (T::*Disposer)() = (&T::dispose)>
|
| -class ScopedDisposal {
|
| - STACK_ALLOCATED();
|
| -public:
|
| - ScopedDisposal(T* object)
|
| - : m_object(object)
|
| - {
|
| - }
|
| -
|
| - ~ScopedDisposal()
|
| - {
|
| - if (m_object)
|
| - (m_object->*Disposer)();
|
| - }
|
| -
|
| - void clear() { m_object.clear(); }
|
| -
|
| -private:
|
| - typename RawPtrOrMemberTrait<T>::Type m_object;
|
| -};
|
| -
|
| -// SelfKeepAlive<Object> is the idiom to use for objects that have to keep
|
| -// themselves temporarily alive and cannot rely on there being some
|
| -// external reference in that interval:
|
| -//
|
| -// class Opener {
|
| -// public:
|
| -// ...
|
| -// void open()
|
| -// {
|
| -// // Retain a self-reference while in an open()ed state:
|
| -// m_keepAlive = this;
|
| -// ....
|
| -// }
|
| -//
|
| -// void close()
|
| -// {
|
| -// // Clear self-reference that ensured we were kept alive while opened.
|
| -// m_keepAlive.clear();
|
| -// ....
|
| -// }
|
| -//
|
| -// private:
|
| -// ...
|
| -// SelfKeepAlive m_keepAlive;
|
| -// };
|
| -//
|
| -// The responsibility to call clear() in a timely fashion resides with the implementation
|
| -// of the object.
|
| -//
|
| -//
|
| -template<typename Self>
|
| -class SelfKeepAlive final {
|
| - DISALLOW_NEW();
|
| -public:
|
| - SelfKeepAlive()
|
| - {
|
| - }
|
| -
|
| - explicit SelfKeepAlive(Self* self)
|
| - {
|
| - assign(self);
|
| - }
|
| -
|
| - SelfKeepAlive& operator=(Self* self)
|
| - {
|
| - assign(self);
|
| - return *this;
|
| - }
|
| -
|
| - void clear()
|
| - {
|
| - m_keepAlive.clear();
|
| - }
|
| -
|
| - typedef Persistent<Self> (SelfKeepAlive::*UnspecifiedBoolType);
|
| - operator UnspecifiedBoolType() const { return m_keepAlive ? &SelfKeepAlive::m_keepAlive : 0; }
|
| -
|
| -private:
|
| - void assign(Self* self)
|
| - {
|
| - ASSERT(!m_keepAlive || m_keepAlive.get() == self);
|
| - m_keepAlive = self;
|
| - }
|
| -
|
| - GC_PLUGIN_IGNORE("420515")
|
| - Persistent<Self> m_keepAlive;
|
| -};
|
| -
|
| // Only a very reduced form of weak heap object references can currently be held
|
| // by WTF::Closure<>s. i.e., bound as a 'this' pointer only.
|
| //
|
| @@ -1075,89 +667,21 @@ CrossThreadPersistent<T> wrapCrossThreadPersistent(T* value)
|
| return CrossThreadPersistent<T>(value);
|
| }
|
|
|
| -// LEAK_SANITIZER_DISABLED_SCOPE: all allocations made in the current scope
|
| -// will be exempted from LSan consideration.
|
| -//
|
| -// TODO(sof): move this to wtf/LeakAnnotations.h (LeakSanitizer.h?) once
|
| -// wtf/ can freely call upon Oilpan functionality.
|
| -#if defined(LEAK_SANITIZER)
|
| -class LeakSanitizerDisableScope {
|
| - STACK_ALLOCATED();
|
| - WTF_MAKE_NONCOPYABLE(LeakSanitizerDisableScope);
|
| -public:
|
| - LeakSanitizerDisableScope()
|
| - {
|
| - __lsan_disable();
|
| - if (ThreadState::current())
|
| - ThreadState::current()->enterStaticReferenceRegistrationDisabledScope();
|
| - }
|
| +// Comparison operators between (Weak)Members, Persistents, and UntracedMembers.
|
| +template<typename T, typename U> inline bool operator==(const Member<T>& a, const Member<U>& b) { return a.get() == b.get(); }
|
| +template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Member<U>& b) { return a.get() != b.get(); }
|
| +template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Persistent<U>& b) { return a.get() == b.get(); }
|
| +template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Persistent<U>& b) { return a.get() != b.get(); }
|
|
|
| - ~LeakSanitizerDisableScope()
|
| - {
|
| - __lsan_enable();
|
| - if (ThreadState::current())
|
| - ThreadState::current()->leaveStaticReferenceRegistrationDisabledScope();
|
| - }
|
| -};
|
| -#define LEAK_SANITIZER_DISABLED_SCOPE LeakSanitizerDisableScope lsanDisabledScope
|
| -#else
|
| -#define LEAK_SANITIZER_DISABLED_SCOPE
|
| -#endif
|
| +template<typename T, typename U> inline bool operator==(const Member<T>& a, const Persistent<U>& b) { return a.get() == b.get(); }
|
| +template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Persistent<U>& b) { return a.get() != b.get(); }
|
| +template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Member<U>& b) { return a.get() == b.get(); }
|
| +template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Member<U>& b) { return a.get() != b.get(); }
|
|
|
| } // namespace blink
|
|
|
| namespace WTF {
|
|
|
| -template <typename T>
|
| -struct MemberHash : PtrHash<T> {
|
| - STATIC_ONLY(MemberHash);
|
| - template <typename U>
|
| - static unsigned hash(const U& key) { return PtrHash<T>::hash(key); }
|
| - template <typename U, typename V>
|
| - static bool equal(const U& a, const V& b) { return a == b; }
|
| -};
|
| -
|
| -template <typename T>
|
| -struct WeakMemberHash : MemberHash<T> {
|
| - STATIC_ONLY(WeakMemberHash);
|
| -};
|
| -
|
| -template <typename T>
|
| -struct UntracedMemberHash : MemberHash<T> {
|
| - STATIC_ONLY(UntracedMemberHash);
|
| -};
|
| -
|
| -// PtrHash is the default hash for hash tables with members.
|
| -template <typename T>
|
| -struct DefaultHash<blink::Member<T>> {
|
| - STATIC_ONLY(DefaultHash);
|
| - using Hash = MemberHash<T>;
|
| -};
|
| -
|
| -template <typename T>
|
| -struct DefaultHash<blink::WeakMember<T>> {
|
| - STATIC_ONLY(DefaultHash);
|
| - using Hash = WeakMemberHash<T>;
|
| -};
|
| -
|
| -template <typename T>
|
| -struct DefaultHash<blink::UntracedMember<T>> {
|
| - STATIC_ONLY(DefaultHash);
|
| - using Hash = UntracedMemberHash<T>;
|
| -};
|
| -
|
| -template<typename T>
|
| -struct NeedsTracing<blink::Member<T>> {
|
| - STATIC_ONLY(NeedsTracing);
|
| - static const bool value = true;
|
| -};
|
| -
|
| -template<typename T>
|
| -struct IsWeak<blink::WeakMember<T>> {
|
| - STATIC_ONLY(IsWeak);
|
| - static const bool value = true;
|
| -};
|
| -
|
| template<typename T>
|
| struct ParamStorageTraits<blink::WeakPersistentThisPointer<T>> {
|
| STATIC_ONLY(ParamStorageTraits);
|
| @@ -1192,4 +716,4 @@ struct ParamStorageTraits<blink::CrossThreadWeakPersistentThisPointer<T>> {
|
|
|
| } // namespace WTF
|
|
|
| -#endif
|
| +#endif // Persistent_h
|
|
|