summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorsgjesse@chromium.org <sgjesse@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-20 11:01:33 +0000
committersgjesse@chromium.org <sgjesse@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-20 11:01:33 +0000
commit349feecde71c4d71834870c88bb701830e75f927 (patch)
treeb415ba0265ecfd07bf1cb650f09facff53fc86b6 /webkit
parent292c90d8dfa53f696f79d6ba50e9699146a9602d (diff)
downloadchromium_src-349feecde71c4d71834870c88bb701830e75f927.zip
chromium_src-349feecde71c4d71834870c88bb701830e75f927.tar.gz
chromium_src-349feecde71c4d71834870c88bb701830e75f927.tar.bz2
Added GC protection support for objects with possible pending activity which is only backed by weak wrappers.
The objects which can have pending activity are XMLHttpRequest and MessagePort. In WebKit these two classes are both instances of ActiveDOMObject. In the V8 binding layer these two types of objects are now beeing tracked so that before GC their wrappers can be made not weak if there is currently pending activity. In addition to that MessagePort wrappers now have an additional internal field to reference their entangled port when entangled. Before MessagePort where added to WebKit pending activity for XMLHttpRequest was handled through a direct GC protect mechanism which protected/unprotected the object when its state changed. However, using this for MessagePort would require an GC protection check in each MessagePort message as the transition to/from pending is not as explicit as for XMLHttpRequest. Changed direct calls to dom_object_map().set(...) to use SetJSWrapperForDOMObject and added an ASSERT to check that SetJSWrapperForDOMObject is called with a DOM wrapper object. Changed the order of calls to SetDOMWrapper and SetJSWrapperForDOMObject to make sure that SetDOMWrapper is called first. This fixes 3 GC related layout tests chrome/fast/dom/xmlhttprequest-gc.html LayoutTests/fast/events/message-channel-gc-2.html LayoutTests/fast/events/message-channel-gc-3.html Added a chrome specific GC layout test for MessagePort (chrome/fast/dom/xmlhttprequest-gc.html) to match the existing one for XMLHttpRequest (chrome/fast/dom/xmlhttprequest-gc.html). This change forks MessagePort.cpp. Review URL: http://codereview.chromium.org/11205 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5770 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/data/layout_tests/chrome/fast/dom/messageport-gc-expected.txt4
-rw-r--r--webkit/data/layout_tests/chrome/fast/dom/messageport-gc.html53
-rw-r--r--webkit/data/layout_tests/chrome/fast/dom/xmlhttprequest-gc.html4
-rw-r--r--webkit/port/bindings/v8/ScriptController.cpp31
-rw-r--r--webkit/port/bindings/v8/ScriptController.h5
-rw-r--r--webkit/port/bindings/v8/V8XMLHttpRequestCustom.cpp2
-rw-r--r--webkit/port/bindings/v8/v8_custom.h4
-rw-r--r--webkit/port/bindings/v8/v8_proxy.cpp137
-rw-r--r--webkit/port/bindings/v8/v8_proxy.h4
-rw-r--r--webkit/tools/layout_tests/test_lists/mac/tests_fixable.txt1
-rw-r--r--webkit/tools/layout_tests/test_lists/win/tests_fixable.txt3
11 files changed, 227 insertions, 21 deletions
diff --git a/webkit/data/layout_tests/chrome/fast/dom/messageport-gc-expected.txt b/webkit/data/layout_tests/chrome/fast/dom/messageport-gc-expected.txt
new file mode 100644
index 0000000..90845ac
--- /dev/null
+++ b/webkit/data/layout_tests/chrome/fast/dom/messageport-gc-expected.txt
@@ -0,0 +1,4 @@
+ALERT: port1
+ALERT: from port2
+ALERT: port2
+ALERT: from port1
diff --git a/webkit/data/layout_tests/chrome/fast/dom/messageport-gc.html b/webkit/data/layout_tests/chrome/fast/dom/messageport-gc.html
new file mode 100644
index 0000000..0582370
--- /dev/null
+++ b/webkit/data/layout_tests/chrome/fast/dom/messageport-gc.html
@@ -0,0 +1,53 @@
+<html>
+
+<script>
+var channel;
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+function on_message1(evt) {
+ try {
+ alert(this.x);
+ alert(evt.data);
+ this.postMessage("from port1")
+ } catch (e) {
+ document.write(e);
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+ }
+}
+
+function on_message2(evt) {
+ try {
+ alert(this.y);
+ alert(evt.data);
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+ } catch (e) {
+ document.write(e);
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+ }
+}
+
+function run_test() {
+ channel = new MessageChannel();
+ channel.port1.x = 'port1';
+ channel.port2.y = 'port2';
+ channel.port1.onmessage = on_message1;
+ channel.port2.onmessage = on_message2;
+ channel.port2.postMessage('from port2');
+ channel.port1.start();
+ channel.port2.start();
+ channel = null;
+ if (window.GCController) {
+ window.GCController.collect();
+ }
+}
+
+</script>
+<body onload='run_test()'>
+</body>
+</html>
diff --git a/webkit/data/layout_tests/chrome/fast/dom/xmlhttprequest-gc.html b/webkit/data/layout_tests/chrome/fast/dom/xmlhttprequest-gc.html
index d4c638c..eee66da 100644
--- a/webkit/data/layout_tests/chrome/fast/dom/xmlhttprequest-gc.html
+++ b/webkit/data/layout_tests/chrome/fast/dom/xmlhttprequest-gc.html
@@ -12,8 +12,8 @@ function run_test() {
xhr.send(null);
xhr = null;
- if (window.gc) {
- gc();
+ if (window.GCController) {
+ window.GCController.collect();
} else {
// allocate 4000 objects to trigger GC
for (var i = 0; i < 4000; i++)
diff --git a/webkit/port/bindings/v8/ScriptController.cpp b/webkit/port/bindings/v8/ScriptController.cpp
index 7eda483..bf4b029 100644
--- a/webkit/port/bindings/v8/ScriptController.cpp
+++ b/webkit/port/bindings/v8/ScriptController.cpp
@@ -110,6 +110,37 @@ void ScriptController::gcUnprotectJSWrapper(void* dom_object)
V8Proxy::GCUnprotect(static_cast<Peerable*>(dom_object));
}
+void ScriptController::entangleMessagePorts(MessagePort *port1,
+ MessagePort *port2)
+{
+ // When two message ports are entangled make sure that the two wrappers are
+ // also entangled. If one of the ports has pending activity it's wrapper
+ // will be protected from beeing GC'ed and by entangeling the wrappers the
+ // wrapper for the entangled port will also be protected.
+ v8::Handle<v8::Value> port1_wrapper =
+ V8Proxy::ToV8Object(V8ClassIndex::MESSAGEPORT, port1);
+ v8::Handle<v8::Value> port2_wrapper =
+ V8Proxy::ToV8Object(V8ClassIndex::MESSAGEPORT, port2);
+ ASSERT(port1_wrapper->IsObject());
+ v8::Handle<v8::Object>::Cast(port1_wrapper)->SetInternalField(
+ V8Custom::kMessagePortEntangledPortIndex, port2_wrapper);
+ ASSERT(port2_wrapper->IsObject());
+ v8::Handle<v8::Object>::Cast(port2_wrapper)->SetInternalField(
+ V8Custom::kMessagePortEntangledPortIndex, port1_wrapper);
+}
+
+void ScriptController::unentangleMessagePort(MessagePort *port)
+{
+ // Remove the wrapper entanglement when a port is unentangled.
+ if (port->peer() != NULL) {
+ v8::Handle<v8::Value> wrapper =
+ V8Proxy::ToV8Object(V8ClassIndex::MESSAGEPORT, port);
+ ASSERT(wrapper->IsObject());
+ v8::Handle<v8::Object>::Cast(wrapper)->SetInternalField(
+ V8Custom::kMessagePortEntangledPortIndex, v8::Undefined());
+ }
+}
+
void ScriptController::pauseTimeouts(OwnPtr<PausedTimeouts>& result)
{
DOMWindow* window = m_frame->domWindow();
diff --git a/webkit/port/bindings/v8/ScriptController.h b/webkit/port/bindings/v8/ScriptController.h
index 34de5f0..da87bf6 100644
--- a/webkit/port/bindings/v8/ScriptController.h
+++ b/webkit/port/bindings/v8/ScriptController.h
@@ -34,6 +34,7 @@
#define ScriptController_h
#include "HashMap.h"
+#include "MessagePort.h"
#include "SecurityOrigin.h"
#include "bindings/npruntime.h"
@@ -209,6 +210,10 @@ public:
static void gcProtectJSWrapper(void* object);
static void gcUnprotectJSWrapper(void* object);
+ // Handle entangle/unentangle of message ports.
+ static void entangleMessagePorts(MessagePort *port1, MessagePort *port2);
+ static void unentangleMessagePort(MessagePort *port);
+
// Get/Set RecordPlaybackMode flag.
// This is a special mode where JS helps the browser implement
// playback/record mode. Generally, in this mode, some functions
diff --git a/webkit/port/bindings/v8/V8XMLHttpRequestCustom.cpp b/webkit/port/bindings/v8/V8XMLHttpRequestCustom.cpp
index e7a3702..3a9653c 100644
--- a/webkit/port/bindings/v8/V8XMLHttpRequestCustom.cpp
+++ b/webkit/port/bindings/v8/V8XMLHttpRequestCustom.cpp
@@ -59,7 +59,7 @@ CALLBACK_FUNC_DECL(XMLHttpRequestConstructor) {
V8Proxy::SetDOMWrapper(args.Holder(),
V8ClassIndex::ToInt(V8ClassIndex::XMLHTTPREQUEST), xhr.get());
// Set object as the peer.
- V8Proxy::SetJSWrapperForDOMObject(xhr.get(),
+ V8Proxy::SetJSWrapperForActiveDOMObject(xhr.get(),
v8::Persistent<v8::Object>::New(args.Holder()));
return args.Holder();
}
diff --git a/webkit/port/bindings/v8/v8_custom.h b/webkit/port/bindings/v8/v8_custom.h
index d3bee4c..de64bd7 100644
--- a/webkit/port/bindings/v8/v8_custom.h
+++ b/webkit/port/bindings/v8/v8_custom.h
@@ -63,8 +63,10 @@ class V8Custom {
static const int kMessagePortRequestCacheIndex =
kDefaultWrapperInternalFieldCount + 0;
- static const int kMessagePortInternalFieldCount =
+ static const int kMessagePortEntangledPortIndex =
kDefaultWrapperInternalFieldCount + 1;
+ static const int kMessagePortInternalFieldCount =
+ kDefaultWrapperInternalFieldCount + 2;
static const int kDOMWindowLocationIndex =
kDefaultWrapperInternalFieldCount + 0;
diff --git a/webkit/port/bindings/v8/v8_proxy.cpp b/webkit/port/bindings/v8/v8_proxy.cpp
index 822c298..a39f06b 100644
--- a/webkit/port/bindings/v8/v8_proxy.cpp
+++ b/webkit/port/bindings/v8/v8_proxy.cpp
@@ -279,7 +279,9 @@ class DOMPeerableWrapperMap : public DOMWrapperMap<T> {
};
-static void WeakPeerableCallback(v8::Persistent<v8::Value> obj, void* para);
+static void WeakDOMObjectCallback(v8::Persistent<v8::Value> obj, void* para);
+static void WeakActiveDOMObjectCallback(v8::Persistent<v8::Value> obj,
+ void* para);
static void WeakNodeCallback(v8::Persistent<v8::Value> obj, void* para);
// A map from DOM node to its JS wrapper.
static DOMWrapperMap<Node>& dom_node_map()
@@ -289,14 +291,24 @@ static DOMWrapperMap<Node>& dom_node_map()
}
-// A map from a non-DOM node (peerable) to its JS wrapper.
+// A map from a non-DOM node (peerable) to its JS wrapper. This map does not
+// contain the DOM objects which can have pending activity.
static DOMWrapperMap<Peerable>& dom_object_map()
{
static DOMPeerableWrapperMap<Peerable>
- static_dom_object_map(&WeakPeerableCallback);
+ static_dom_object_map(&WeakDOMObjectCallback);
return static_dom_object_map;
}
+// A map from a non-DOM node (peerable) to its JS wrapper for DOM objects which
+// can have pending activity.
+static DOMWrapperMap<Peerable>& active_dom_object_map()
+{
+ static DOMPeerableWrapperMap<Peerable>
+ static_active_dom_object_map(&WeakActiveDOMObjectCallback);
+ return static_active_dom_object_map;
+}
+
#if ENABLE(SVG)
static void WeakSVGElementInstanceCallback(v8::Persistent<v8::Value> obj,
void* param);
@@ -431,7 +443,7 @@ SVGElement* V8Proxy::GetSVGContext(void* obj)
// Called when obj is near death (not reachable from JS roots)
// It is time to remove the entry from the table and dispose
// the handle.
-static void WeakPeerableCallback(v8::Persistent<v8::Value> obj, void* para)
+static void WeakDOMObjectCallback(v8::Persistent<v8::Value> obj, void* para)
{
Peerable* dom_obj = static_cast<Peerable*>(para);
ASSERT(dom_object_map().contains(dom_obj));
@@ -441,6 +453,17 @@ static void WeakPeerableCallback(v8::Persistent<v8::Value> obj, void* para)
dom_object_map().forget(dom_obj);
}
+static void WeakActiveDOMObjectCallback(v8::Persistent<v8::Value> obj,
+ void* para)
+{
+ Peerable* dom_obj = static_cast<Peerable*>(para);
+ ASSERT(active_dom_object_map().contains(dom_obj));
+
+ // forget function removes object from the map,
+ // disposes the wrapper and clears the peer.
+ active_dom_object_map().forget(dom_obj);
+}
+
static void WeakNodeCallback(v8::Persistent<v8::Value> obj, void* param)
{
Node* node = static_cast<Node*>(param);
@@ -452,6 +475,8 @@ static void WeakNodeCallback(v8::Persistent<v8::Value> obj, void* param)
// Create object groups for DOM tree nodes.
static void GCPrologue()
{
+ v8::HandleScope scope;
+
#ifndef NDEBUG
// Check that all references in the map are weak.
PeerableMap peer_map = dom_object_map().impl();
@@ -463,6 +488,28 @@ static void GCPrologue()
}
#endif
+ // Run through all objects with possible pending activity making their
+ // wrappers non weak if there is pending activity.
+ PeerableMap active_map = active_dom_object_map().impl();
+ for (PeerableMap::iterator it = active_map.begin(), end = active_map.end();
+ it != end; ++it) {
+ Peerable* obj = it->first;
+ v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>(it->second);
+ ASSERT(wrapper.IsWeak());
+ V8ClassIndex::V8WrapperType type = V8Proxy::GetDOMWrapperType(wrapper);
+ if (type == V8ClassIndex::XMLHTTPREQUEST) {
+ XMLHttpRequest* xhr = static_cast<XMLHttpRequest*>(obj);
+ if (xhr->hasPendingActivity()) {
+ wrapper.ClearWeak();
+ }
+ } else if (type == V8ClassIndex::MESSAGEPORT) {
+ MessagePort* message_port = static_cast<MessagePort*>(obj);
+ if (message_port->hasPendingActivity()) {
+ wrapper.ClearWeak();
+ }
+ }
+ }
+
// Create object groups.
NodeMap node_map = dom_node_map().impl();
for (NodeMap::iterator it = node_map.begin(), end = node_map.end();
@@ -499,6 +546,32 @@ static void GCPrologue()
static void GCEpilogue()
{
+ v8::HandleScope scope;
+
+ // Run through all objects with pending activity making their wrappers weak
+ // again.
+ PeerableMap active_map = active_dom_object_map().impl();
+ for (PeerableMap::iterator it = active_map.begin(), end = active_map.end();
+ it != end; ++it) {
+ Peerable* obj = it->first;
+ v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>(it->second);
+ V8ClassIndex::V8WrapperType type = V8Proxy::GetDOMWrapperType(wrapper);
+ if (type == V8ClassIndex::XMLHTTPREQUEST) {
+ XMLHttpRequest* xhr = static_cast<XMLHttpRequest*>(obj);
+ if (xhr->hasPendingActivity()) {
+ ASSERT(!wrapper.IsWeak());
+ wrapper.MakeWeak(xhr, &WeakActiveDOMObjectCallback);
+ }
+ } else if (type == V8ClassIndex::MESSAGEPORT) {
+ MessagePort* message_port = static_cast<MessagePort*>(obj);
+ if (message_port->hasPendingActivity()) {
+ ASSERT(!wrapper.IsWeak());
+ wrapper.MakeWeak(message_port, &WeakActiveDOMObjectCallback);
+ }
+ }
+ ASSERT(wrapper.IsWeak());
+ }
+
#ifndef NDEBUG
// Check all survivals are weak.
PeerableMap peer_map = dom_object_map().impl();
@@ -817,11 +890,29 @@ void V8Proxy::DestroyGlobal()
void V8Proxy::SetJSWrapperForDOMObject(Peerable* obj, v8::Persistent<v8::Object> wrapper)
{
+ ASSERT(MaybeDOMWrapper(wrapper));
+#ifndef NDEBUG
+ V8ClassIndex::V8WrapperType type = V8Proxy::GetDOMWrapperType(wrapper);
+ ASSERT(type != V8ClassIndex::XMLHTTPREQUEST &&
+ type != V8ClassIndex::MESSAGEPORT);
+#endif
dom_object_map().set(obj, wrapper);
}
+void V8Proxy::SetJSWrapperForActiveDOMObject(Peerable* obj, v8::Persistent<v8::Object> wrapper)
+{
+ ASSERT(MaybeDOMWrapper(wrapper));
+#ifndef NDEBUG
+ V8ClassIndex::V8WrapperType type = V8Proxy::GetDOMWrapperType(wrapper);
+ ASSERT(type == V8ClassIndex::XMLHTTPREQUEST ||
+ type == V8ClassIndex::MESSAGEPORT);
+#endif
+ active_dom_object_map().set(obj, wrapper);
+}
+
void V8Proxy::SetJSWrapperForDOMNode(Node* node, v8::Persistent<v8::Object> wrapper)
{
+ ASSERT(MaybeDOMWrapper(wrapper));
dom_node_map().set(node, wrapper);
}
@@ -1862,12 +1953,13 @@ void V8Proxy::initContextIfNeeded()
DOMWindow* window = m_frame->domWindow();
- // Setup the peer object for the DOM window.
- dom_object_map().set(window, v8::Persistent<v8::Object>::New(window_peer));
// Wrap the window.
SetDOMWrapper(window_peer,
V8ClassIndex::ToInt(V8ClassIndex::DOMWINDOW),
window);
+ // Setup the peer object for the DOM window.
+ V8Proxy::SetJSWrapperForDOMObject(window,
+ v8::Persistent<v8::Object>::New(window_peer));
// Insert the window instance as the prototype of the shadow object.
v8::Handle<v8::Object> v8_global = context->Global();
v8_global->Set(v8::String::New("__proto__"), window_peer);
@@ -2002,6 +2094,9 @@ v8::Handle<v8::Value> V8Proxy::ToV8Object(V8ClassIndex::V8WrapperType type, void
return StyleSheetToV8Object(static_cast<StyleSheet*>(imp));
case V8ClassIndex::DOMWINDOW:
return WindowToV8Object(static_cast<DOMWindow*>(imp));
+ case V8ClassIndex::XMLHTTPREQUEST:
+ case V8ClassIndex::MESSAGEPORT:
+ return ActiveDOMObjectToV8Object(type, static_cast<Peerable*>(imp));
#if ENABLE(SVG)
SVGNONNODE_WRAPPER_TYPES(MAKE_CASE)
if (type == V8ClassIndex::SVGELEMENTINSTANCE)
@@ -2023,7 +2118,7 @@ v8::Handle<v8::Value> V8Proxy::ToV8Object(V8ClassIndex::V8WrapperType type, void
v8::Local<v8::Object> v8obj = InstantiateV8Object(type, type, imp);
if (!v8obj.IsEmpty()) {
result = v8::Persistent<v8::Object>::New(v8obj);
- dom_object_map().set(obj, result);
+ SetJSWrapperForDOMObject(obj, result);
// Special case for Location and Navigator. Both Safari and FF let
// Location and Navigator JS wrappers survive GC. To mimic their
@@ -2516,7 +2611,7 @@ v8::Handle<v8::Value> V8Proxy::EventToV8Object(Event* event)
return v8::Null();
}
- dom_object_map().set(event, v8::Persistent<v8::Object>::New(result));
+ SetJSWrapperForDOMObject(event, v8::Persistent<v8::Object>::New(result));
return result;
}
@@ -2664,7 +2759,7 @@ v8::Handle<v8::Value> V8Proxy::EventTargetToV8Object(EventTarget* target)
// XMLHttpRequest is created within its JS counterpart.
XMLHttpRequest* xhr = target->toXMLHttpRequest();
if (xhr) {
- v8::Handle<v8::Object> peer = dom_object_map().get(xhr);
+ v8::Handle<v8::Object> peer = active_dom_object_map().get(xhr);
ASSERT(!peer.IsEmpty());
return peer;
}
@@ -2672,7 +2767,7 @@ v8::Handle<v8::Value> V8Proxy::EventTargetToV8Object(EventTarget* target)
// MessagePort is created within its JS counterpart
MessagePort* port = target->toMessagePort();
if (port) {
- v8::Handle<v8::Object> peer = dom_object_map().get(port);
+ v8::Handle<v8::Object> peer = active_dom_object_map().get(port);
ASSERT(!peer.IsEmpty());
return peer;
}
@@ -2733,7 +2828,7 @@ v8::Handle<v8::Value> V8Proxy::StyleSheetToV8Object(StyleSheet* sheet)
InstantiateV8Object(type, V8ClassIndex::STYLESHEET, sheet);
if (!result.IsEmpty()) {
// Only update the DOM object map if the result is non-empty.
- dom_object_map().set(sheet, v8::Persistent<v8::Object>::New(result));
+ SetJSWrapperForDOMObject(sheet, v8::Persistent<v8::Object>::New(result));
}
// Add a hidden reference from stylesheet object to its owner node.
@@ -2777,7 +2872,7 @@ v8::Handle<v8::Value> V8Proxy::CSSValueToV8Object(CSSValue* value)
InstantiateV8Object(type, V8ClassIndex::CSSVALUE, value);
if (!result.IsEmpty())
// Only update the DOM object map if the result is non-empty.
- dom_object_map().set(value, v8::Persistent<v8::Object>::New(result));
+ SetJSWrapperForDOMObject(value, v8::Persistent<v8::Object>::New(result));
return result;
}
@@ -2830,7 +2925,7 @@ v8::Handle<v8::Value> V8Proxy::CSSRuleToV8Object(CSSRule* rule)
InstantiateV8Object(type, V8ClassIndex::CSSRULE, rule);
if (!result.IsEmpty())
// Only update the DOM object map if the result is non-empty.
- dom_object_map().set(rule, v8::Persistent<v8::Object>::New(result));
+ SetJSWrapperForDOMObject(rule, v8::Persistent<v8::Object>::New(result));
return result;
}
@@ -2852,6 +2947,22 @@ v8::Handle<v8::Value> V8Proxy::WindowToV8Object(DOMWindow* window)
return global;
}
+v8::Handle<v8::Value> V8Proxy::ActiveDOMObjectToV8Object(
+ V8ClassIndex::V8WrapperType type, Peerable* obj)
+{
+ v8::Handle<v8::Object> result = active_dom_object_map().get(obj);
+ if (!result.IsEmpty())
+ return result;
+
+ // Set the peer object for future access.
+ result = InstantiateV8Object(type, type, obj);
+ if (!result.IsEmpty())
+ // Only update the DOM object map if the result is non-empty.
+ SetJSWrapperForActiveDOMObject(obj,
+ v8::Persistent<v8::Object>::New(result));
+ return result;
+}
+
void V8Proxy::BindJSObjectToWindow(Frame* frame,
const char* name,
int type,
diff --git a/webkit/port/bindings/v8/v8_proxy.h b/webkit/port/bindings/v8/v8_proxy.h
index 05c3315..bb16921 100644
--- a/webkit/port/bindings/v8/v8_proxy.h
+++ b/webkit/port/bindings/v8/v8_proxy.h
@@ -393,6 +393,8 @@ class V8Proxy {
// Set JS wrapper of a DOM object
static void SetJSWrapperForDOMObject(Peerable* obj,
v8::Persistent<v8::Object> wrapper);
+ static void SetJSWrapperForActiveDOMObject(Peerable* obj,
+ v8::Persistent<v8::Object> wrapper);
static void SetJSWrapperForDOMNode(Node* node,
v8::Persistent<v8::Object> wrapper);
@@ -442,6 +444,8 @@ class V8Proxy {
// Returns the JS wrapper of a window object, initializes the environment
// of the window frame if needed.
static v8::Handle<v8::Value> WindowToV8Object(DOMWindow* window);
+ static v8::Handle<v8::Value> ActiveDOMObjectToV8Object(
+ V8ClassIndex::V8WrapperType type, Peerable* obj);
#if ENABLE(SVG)
static v8::Handle<v8::Value> SVGElementInstanceToV8Object(
diff --git a/webkit/tools/layout_tests/test_lists/mac/tests_fixable.txt b/webkit/tools/layout_tests/test_lists/mac/tests_fixable.txt
index fda2eb3..b95ed53 100644
--- a/webkit/tools/layout_tests/test_lists/mac/tests_fixable.txt
+++ b/webkit/tools/layout_tests/test_lists/mac/tests_fixable.txt
@@ -659,7 +659,6 @@ LayoutTests/fast/text/drawBidiText.html = FAIL
LayoutTests/http/tests/security/dataURL/xss-DENIED-from-data-url-sub-frame-to-data-url-sub-frame.html = FAIL
LayoutTests/http/tests/security/dataURL/xss-DENIED-from-data-url-to-data-url.html = FAIL
LayoutTests/http/tests/security/dataURL/xss-DENIED-to-data-url-from-data-url.html = FAIL
-chrome/fast/dom/xmlhttprequest-gc.html = FAIL
chrome/fast/dom/xss-DENIED-javascript-variations.html = FAIL
chrome/fast/forms/basic-textareas.html = FAIL
//LayoutTests/http/tests/misc/dns-prefetch-control.html = TIMEOUT | PASS
diff --git a/webkit/tools/layout_tests/test_lists/win/tests_fixable.txt b/webkit/tools/layout_tests/test_lists/win/tests_fixable.txt
index 8485ed6..214525b 100644
--- a/webkit/tools/layout_tests/test_lists/win/tests_fixable.txt
+++ b/webkit/tools/layout_tests/test_lists/win/tests_fixable.txt
@@ -1040,7 +1040,6 @@ LayoutTests/fast/text/drawBidiText.html = FAIL
LayoutTests/http/tests/security/dataURL/xss-DENIED-from-data-url-sub-frame-to-data-url-sub-frame.html = FAIL
LayoutTests/http/tests/security/dataURL/xss-DENIED-from-data-url-to-data-url.html = FAIL
LayoutTests/http/tests/security/dataURL/xss-DENIED-to-data-url-from-data-url.html = FAIL
-chrome/fast/dom/xmlhttprequest-gc.html = FAIL
chrome/fast/dom/xss-DENIED-javascript-variations.html = FAIL
chrome/fast/forms/basic-textareas.html = FAIL
LayoutTests/http/tests/misc/dns-prefetch-control.html = TIMEOUT | PASS
@@ -1082,7 +1081,6 @@ LayoutTests/fast/js/large-expressions.html = FAIL
LayoutTests/fast/transforms/transformed-focused-text-input.html = FAIL
LayoutTests/editing/deleting/delete-4038408-fix.html = FAIL
-LayoutTests/fast/events/message-channel-gc-2.html = TIMEOUT
// MERGE 38305:38376 REGRESSIONS: These are all new tests, not regressions.
// May just need rebaselining.
@@ -1094,7 +1092,6 @@ LayoutTests/transforms/2d/zoom-menulist.html = FAIL
// Issue http://code.google.com/p/chromium/issues/detail?id=4432)
LayoutTests/fast/dom/HTMLImageElement/image-loading-gc.html = TIMEOUT
-LayoutTests/fast/events/message-channel-gc-3.html = TIMEOUT
// MERGE 38389:38450
LayoutTests/editing/pasteboard/paste-blockquote-into-blockquote-4.html = FAIL