Index: third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.h |
diff --git a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.h b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.h |
index bb3fd0bcd3b6fa48abfa56a46fb7cfc8bc09a746..343873a62d19728ed9771116298bdb5ee6d6c7cb 100644 |
--- a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.h |
+++ b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.h |
@@ -43,6 +43,7 @@ |
namespace blink { |
class DOMDataStore; |
+class DOMObjectHolderBase; |
enum WorldIdConstants { |
MainWorldId = 0, |
@@ -54,8 +55,6 @@ enum WorldIdConstants { |
TestingWorldId, |
}; |
-class DOMObjectHolderBase; |
- |
// This class represent a collection of DOM wrappers for a specific world. |
class CORE_EXPORT DOMWrapperWorld : public RefCounted<DOMWrapperWorld> { |
public: |
@@ -117,7 +116,6 @@ class CORE_EXPORT DOMWrapperWorld : public RefCounted<DOMWrapperWorld> { |
int worldId() const { return m_worldId; } |
DOMDataStore& domDataStore() const { return *m_domDataStore; } |
- public: |
template <typename T> |
void registerDOMObjectHolder(v8::Isolate*, T*, v8::Local<v8::Value>); |
@@ -129,6 +127,29 @@ class CORE_EXPORT DOMWrapperWorld : public RefCounted<DOMWrapperWorld> { |
void registerDOMObjectHolderInternal(std::unique_ptr<DOMObjectHolderBase>); |
void unregisterDOMObjectHolder(DOMObjectHolderBase*); |
+ // Dissociates all wrappers in all worlds associated with |scriptWrappable|. |
+ // |
+ // Do not use this function except for DOMWindow. Only DOMWindow needs to |
+ // dissociate wrappers from the ScriptWrappable because of the following two |
+ // reasons. |
+ // |
+ // Reason 1) Case of the main world |
+ // A DOMWindow may be collected by Blink GC *before* V8 GC collects the |
+ // wrapper because the wrapper object associated with a DOMWindow is a global |
haraken
2017/02/01 08:40:43
I don't fully understand why it can happen.
A glo
Yuki
2017/02/01 08:47:58
No, it's not "global object". It's "global proxy
|
+ // proxy object, which remains after navigations. We don't want V8 GC |
+ // to reset the weak persistent handle within the DOMWindow *after* Blink GC |
+ // collects the DOMWindow because it's use-after-free. Thus, we need to |
+ // dissociate the wrapper in advance. |
+ // |
+ // Reason 2) Case of isolated worlds |
+ // As same, a DOMWindow may be collected before the wrapper gets collected. |
+ // A DOMWrapperMap supports mapping from ScriptWrappable* to v8::Global<T>, |
+ // and we don't want to leave an entry of an already-dead DOMWindow* to the |
+ // persistent handle for the global proxy object, especially considering that |
+ // the address to the already-dead DOMWindow* may be re-used. |
+ friend class DOMWindow; |
+ static void dissociateWrappersInAllWorlds(ScriptWrappable*); |
+ |
static unsigned isolatedWorldCount; |
const int m_worldId; |