Add CHECKs to try to narrow down cause of bad internal fields in Window DOM wrapper

BUG=696528

Review-Url: https://codereview.chromium.org/2736533002
Cr-Commit-Position: refs/heads/master@{#454781}
diff --git a/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp b/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp
index 4a31146..67d3a44 100644
--- a/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp
@@ -33,9 +33,11 @@
 #include <utility>
 
 #include "bindings/core/v8/V8DOMWrapper.h"
+#include "bindings/core/v8/V8Window.h"
 #include "core/frame/Frame.h"
 #include "v8/include/v8.h"
 #include "wtf/Assertions.h"
+#include "wtf/debug/Alias.h"
 
 namespace blink {
 
@@ -130,11 +132,40 @@
 // If there are JS code holds a closure to the old inner window,
 // it won't be able to reach the outer window via its global object.
 void WindowProxy::initializeIfNeeded() {
+  v8::HandleScope handleScope(m_isolate);
+  Lifecycle oldLifecycle = m_lifecycle;
+  DOMWindow* window = m_frame->domWindow();
+  bool isLocal = window->isLocalDOMWindow();
+  // Prevent these locals from getting optimized out, and hopefully, the heap
+  // contents captured into minidumps.
+  WTF::debug::alias(&oldLifecycle);
+  WTF::debug::alias(&window);
+  WTF::debug::alias(&isLocal);
+
   // TODO(haraken): It is wrong to re-initialize an already detached window
   // proxy. This must be 'if(m_lifecycle == Lifecycle::ContextUninitialized)'.
   if (m_lifecycle != Lifecycle::ContextInitialized) {
     initialize();
+    // Note: this set of CHECKs is intentionally duplicated below to distinguish
+    // between initializing the global with null internal fields or returning a
+    // global that claims to be initialized but has null internal fields.
+    v8::Local<v8::Object> globalProxy = m_globalProxy.newLocal(m_isolate);
+    CHECK(!globalProxy.IsEmpty());
+    CHECK(V8Window::hasInstance(globalProxy, m_isolate));
+    CHECK(window);
+    CHECK_EQ(window, V8Window::toImpl(globalProxy));
+  } else {
+    v8::Local<v8::Object> globalProxy = m_globalProxy.newLocal(m_isolate);
+    CHECK(!globalProxy.IsEmpty());
+    CHECK(V8Window::hasInstance(globalProxy, m_isolate));
+    CHECK(window);
+    CHECK_EQ(window, V8Window::toImpl(globalProxy));
   }
+
+  // Sanity check: WindowProxy's frame's window should still be the same
+  DOMWindow* window2 = m_frame->domWindow();
+  WTF::debug::alias(&window2);
+  CHECK_EQ(window, window2);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp b/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp
index 3fcba55..fc2e921 100644
--- a/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp
+++ b/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp
@@ -5,6 +5,7 @@
 #include "web/WebRemoteFrameImpl.h"
 
 #include "bindings/core/v8/RemoteWindowProxy.h"
+#include "bindings/core/v8/V8Window.h"
 #include "core/dom/Fullscreen.h"
 #include "core/dom/RemoteSecurityContext.h"
 #include "core/dom/SecurityContext.h"
@@ -26,6 +27,7 @@
 #include "web/RemoteFrameOwner.h"
 #include "web/WebLocalFrameImpl.h"
 #include "web/WebViewImpl.h"
+#include "wtf/debug/Alias.h"
 
 namespace blink {
 
@@ -215,9 +217,23 @@
 
 v8::Local<v8::Context> WebRemoteFrameImpl::deprecatedMainWorldScriptContext()
     const {
-  return static_cast<RemoteWindowProxy*>(
-             frame()->windowProxy(DOMWrapperWorld::mainWorld()))
-      ->contextIfInitialized();
+  v8::Local<v8::Context> context =
+      static_cast<RemoteWindowProxy*>(
+          frame()->windowProxy(DOMWrapperWorld::mainWorld()))
+          ->contextIfInitialized();
+
+  DOMWindow* window = frame()->domWindow();
+  // Prevent this local from getting optimized out, and hopefully, the heap
+  // contents captured into minidumps.
+  WTF::debug::alias(&window);
+
+  v8::Local<v8::Object> globalProxy = context->Global();
+  CHECK(!globalProxy.IsEmpty());
+  CHECK(V8Window::hasInstance(globalProxy, v8::Isolate::GetCurrent()));
+  CHECK(window);
+  CHECK_EQ(window, V8Window::toImpl(globalProxy));
+
+  return context;
 }
 
 void WebRemoteFrameImpl::reload(WebFrameLoadType) {