diff --git a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeys-with-session.html b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeys-with-session.html
index 6def08fd..25a7cc93 100644
--- a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeys-with-session.html
+++ b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeys-with-session.html
@@ -19,14 +19,21 @@
             // For this test, create a MediaKeySession and verify lifetime.
             async_test(function(test)
             {
+                gc();
                 var initDataType;
                 var initData;
                 var mediaKeys;
-                var startingSuspendableObjectCount = window.internals.suspendableObjectCount(document);
+                var startingMediaKeysCount = window.internals.mediaKeysCount();
+                var startingMediaKeySessionCount = window.internals.mediaKeySessionCount();
 
-                function numSuspendableObjectsCreated()
+                function numMediaKeysCreated()
                 {
-                    return window.internals.suspendableObjectCount(document) - startingSuspendableObjectCount;
+                    return window.internals.mediaKeysCount() - startingMediaKeysCount;
+                }
+
+                function numMediaKeySessionCreated()
+                {
+                    return window.internals.mediaKeySessionCount() - startingMediaKeySessionCount;
                 }
 
                 // Create a MediaKeys object with a session.
@@ -37,27 +44,14 @@
                 }).then(function(result) {
                     mediaKeys = result;
 
-                    // Verify MediaKeys is an SuspendableObject.
-                    // In non-Oilpan, numSuspendableObjectsCreate() == 1.
-                    // In Oilpan, numSuspendableObjectsCreate() <= 4.
-                    // (1 MediaKeys,
-                    //  1 MediaKeysInitializer and
-                    //  1 MediaKeySystemAccessInitializer (navigator.requestMediaKeySystemAccess() use above),
-                    //  1 MediaKeySystemAccessInitializer (isInitDataSupported() (via getSupportedInitDataType())))
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 1, 4, 'MediaKeys.create()');
+                    assert_equals(numMediaKeysCreated(), 1, 'MediaKeys.create()');
+                    assert_equals(numMediaKeySessionCreated(), 0, 'After final gc()');
 
                     var mediaKeySession = mediaKeys.createSession();
                     return mediaKeySession.generateRequest(initDataType, initData);
                 }).then(function() {
-                    // Should be 1 MediaKeys + 1 MediaKeySession.
-                    // In non-Oilpan, numSuspendableObjectsCreate() == 2.
-                    // In Oilpan, numSuspendableObjectsCreate() <= 6.
-                    // (1 MediaKeys,
-                    //  1 MediaKeysInitializer and
-                    //  2 MediaKeySystemAccessInitializer,
-                    //  1 ContentDecryptionModuleResultPromise and
-                    //  1 MediaKeySession).
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 2, 6, 'MediaKeys.createSession()');
+                    assert_equals(numMediaKeysCreated(), 1, 'MediaKeys.createSession()');
+                    assert_equals(numMediaKeySessionCreated(), 1, 'MediaKeys.createSession()');
 
                     // Run gc(), should not affect MediaKeys object nor the
                     // session since we still have a reference to it.
@@ -68,9 +62,8 @@
                 }).then(function(result) {
                     assert_equals(typeof mediaKeys.createSession, 'function');
 
-                    // MediaKeys + MediaKeySessions should remain.
-                    // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 2, 3, 'After gc()');
+                    assert_equals(numMediaKeysCreated(), 1, 'After gc()');
+                    assert_equals(numMediaKeySessionCreated(), 1, 'After gc()');
 
                     // Drop reference to the MediaKeys object and run gc()
                     // again. Object should be collected this time. Since
@@ -85,9 +78,8 @@
                 }).then(function(result) {
                     return createGCPromise();
                 }).then(function(result) {
-                    // No MediaKeySessions should remain.
-                    // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 0, 1, 'After final gc()');
+                    assert_equals(numMediaKeysCreated(), 0, 'After final gc()');
+                    assert_equals(numMediaKeySessionCreated(), 0, 'After final gc()');
 
                     test.done();
                 }).catch(function(error) {
diff --git a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-reference.html b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-reference.html
index 2736a46..b1235fb9 100644
--- a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-reference.html
+++ b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-reference.html
@@ -8,8 +8,6 @@
     </head>
     <body>
         <script>
-            // Since MediaKeySession (and MediaKeys) are SuspendableObjects,
-            // we can determine when they are garbage collected.
             // MediaKeySessions remain as long as:
             //   JavaScript has a reference to it
             //   OR (MediaKeys is around
@@ -17,17 +15,24 @@
 
             async_test(function(test)
             {
+                gc();
                 var mediaKeys;
                 var mediaKeySession1;
                 var mediaKeySession2;
                 var mediaKeySession3;
                 var initDataType;
                 var initData;
-                var startingSuspendableObjectCount = window.internals.suspendableObjectCount(document);
+                var startingMediaKeysCount = window.internals.mediaKeysCount();
+                var startingMediaKeySessionCount = window.internals.mediaKeySessionCount();
 
-                function numSuspendableObjectsCreated()
+                function numMediaKeysCreated()
                 {
-                    return window.internals.suspendableObjectCount(document) - startingSuspendableObjectCount;
+                    return window.internals.mediaKeysCount() - startingMediaKeysCount;
+                }
+
+                function numMediaKeySessionCreated()
+                {
+                    return window.internals.mediaKeySessionCount() - startingMediaKeySessionCount;
                 }
 
                 navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) {
@@ -38,14 +43,8 @@
                     mediaKeys = result;
                     assert_equals(typeof mediaKeys.createSession, 'function');
 
-                    // Verify MediaKeys is an SuspendableObject.
-                    // In non-Oilpan, numSuspendableObjectsCreate() == 1.
-                    // In Oilpan, numSuspendableObjectsCreate() <= 4.
-                    // (1 MediaKeys,
-                    //  1 MediaKeysInitializer and
-                    //  1 MediaKeySystemAccessInitializer (navigator.requestMediaKeySystemAccess() use above),
-                    //  1 MediaKeySystemAccessInitializer (isInitDataSupported() (via getSupportedInitDataType())))
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 1, 4, 'MediaKeys.create()');
+                    assert_equals(numMediaKeysCreated(), 1, 'MediaKeys.create()');
+                    assert_equals(numMediaKeySessionCreated(), 0, 'After final gc()');
 
                     // Create 3 sessions.
                     mediaKeySession1 = mediaKeys.createSession();
@@ -53,54 +52,32 @@
                 }).then(function() {
                     assert_true(mediaKeySession1.sessionId && mediaKeySession1.sessionId.length > 0);
 
-                    // Should be 1 MediaKeys + 1 MediaKeySession.
-                    // In non-Oilpan, numSuspendableObjectsCreate() == 2.
-                    // In Oilpan, numSuspendableObjectsCreate() <= 6.
-                    // (1 MediaKeys,
-                    //  1 MediaKeysInitializer and
-                    //  2 MediaKeySystemAccessInitializer,
-                    //  1 ContentDecryptionModuleResultPromise and
-                    //  1 MediaKeySession).
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 2, 6, 'MediaKeys.createSession(1)');
+                    assert_equals(numMediaKeysCreated(), 1, 'MediaKeys.createSession(1)');
+                    assert_equals(numMediaKeySessionCreated(), 1, 'MediaKeys.createSession(1)');
 
                     mediaKeySession2 = mediaKeys.createSession();
                     return mediaKeySession2.generateRequest(initDataType, initData);
                 }).then(function() {
                     assert_true(mediaKeySession2.sessionId && mediaKeySession2.sessionId.length > 0);
 
-                    // Should be 1 MediaKeys + 2 MediaKeySessions.
-                    // In non-Oilpan, numSuspendableObjectsCreate() == 3.
-                    // In Oilpan, numSuspendableObjectsCreate() <= 8.
-                    // (1 MediaKeys,
-                    //  1 MediaKeysInitializer and
-                    //  2 MediaKeySystemAccessInitializers,
-                    //  2 ContentDecryptionModuleResultPromise and
-                    //  2 MediaKeySession).
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 3, 8, 'mediaKeys.createSession(2)');
+                    assert_equals(numMediaKeysCreated(), 1, 'mediaKeys.createSession(2)');
+                    assert_equals(numMediaKeySessionCreated(), 2, 'mediaKeys.createSession(2)');
 
                     mediaKeySession3 = mediaKeys.createSession();
                     return mediaKeySession3.generateRequest(initDataType, initData);
                 }).then(function() {
                     assert_true(mediaKeySession3.sessionId && mediaKeySession3.sessionId.length > 0);
 
-                    // Should be 1 MediaKeys + 3 MediaKeySessions.
-                    // In non-Oilpan, numSuspendableObjectsCreate() == 4.
-                    // In Oilpan, numSuspendableObjectsCreate() <= 10.
-                    // (1 MediaKeys,
-                    //  1 MediaKeysInitializer and
-                    //  2 MediaKeySystemAccessInitializers,
-                    //  3 ContentDecryptionModuleResultPromise and
-                    //  3 MediaKeySession).
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 4, 10, 'mediaKeys.createSession(3)');
+                    assert_equals(numMediaKeysCreated(), 1, 'mediaKeys.createSession(3)');
+                    assert_equals(numMediaKeySessionCreated(), 3, 'mediaKeys.createSession(3)');
 
                     // Run gc(). All sessions should remain as we have a
                     // reference to each one. However, running gc()
                     // asynchronously should free up the last PromiseResolver.
                     return createGCPromise();
                 }).then(function(result) {
-                    // Only MediaKeys + 3 MediaKeySessions should remain.
-                    // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 4, 5, 'After gc()');
+                    assert_equals(numMediaKeysCreated(), 1, 'After gc()');
+                    assert_equals(numMediaKeySessionCreated(), 3, 'After gc()');
 
                     // Now drop references to 2 of the sessions. Even though we
                     // don't have a reference, MediaKeys is still around (and
@@ -112,9 +89,8 @@
                 }).then(function(result) {
                     return createGCPromise();
                 }).then(function(result) {
-                    // MediaKeys + 3 MediaKeySessions should remain.
-                    // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 4, 5, 'After second gc()');
+                    assert_equals(numMediaKeysCreated(), 1, 'After second gc()');
+                    assert_equals(numMediaKeySessionCreated(), 3, 'After second gc()');
 
                     // Now drop the reference to MediaKeys. It and the 2
                     // unreferenced sessions should be collected. Since
@@ -129,18 +105,16 @@
                 }).then(function(result) {
                     return createGCPromise();
                 }).then(function(result) {
-                    // Only 1 MediaKeySessions should remain.
-                    // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 1, 2, 'After mediaKeys = null');
+                    assert_equals(numMediaKeysCreated(), 0, 'After mediaKeys = null');
+                    assert_equals(numMediaKeySessionCreated(), 1, 'After mediaKeys = null');
 
                     // Drop the reference to the last session. It should get
                     // collected now since MediaKeys is gone.
                     mediaKeySession3 = null;
                     return createGCPromise();
                 }).then(function(result) {
-                    // No MediaKeySessions should remain.
-                    // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 0, 1, 'After final gc()');
+                    assert_equals(numMediaKeysCreated(), 0, 'After final gc()');
+                    assert_equals(numMediaKeySessionCreated(), 0, 'After final gc()');
 
                     test.done();
                 }).catch(function(error) {
diff --git a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-release-noreference.html b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-release-noreference.html
index bff8e23..60019a1 100644
--- a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-release-noreference.html
+++ b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-release-noreference.html
@@ -8,21 +8,26 @@
     </head>
     <body>
         <script>
-            // Since MediaKeySession (and MediaKeys) are SuspendableObjects,
-            // we can determine when they are garbage collected.
             // MediaKeySessions remain as long as:
             //   JavaScript has a reference to it
             //   OR (MediaKeys is around
             //       AND the session has not received a close() event)
             async_test(function(test)
             {
+                gc();
                 var initDataType;
                 var initData;
-                var startingSuspendableObjectCount = window.internals.suspendableObjectCount(document);
+                var startingMediaKeysCount = window.internals.mediaKeysCount();
+                var startingMediaKeySessionCount = window.internals.mediaKeySessionCount();
 
-                function numSuspendableObjectsCreated()
+                function numMediaKeysCreated()
                 {
-                    return window.internals.suspendableObjectCount(document) - startingSuspendableObjectCount;
+                    return window.internals.mediaKeysCount() - startingMediaKeysCount;
+                }
+
+                function numMediaKeySessionCreated()
+                {
+                    return window.internals.mediaKeySessionCount() - startingMediaKeySessionCount;
                 }
 
                 // Create 2 sessions.
@@ -37,52 +42,31 @@
                 }).then(function(result) {
                     mediaKeys = result;
 
-                    // Verify MediaKeys is an SuspendableObject.
-                    // In non-Oilpan, numSuspendableObjectsCreate() == 1.
-                    // In Oilpan, numSuspendableObjectsCreate() <= 4.
-                    // (1 MediaKeys,
-                    //  1 MediaKeysInitializer and
-                    //  1 MediaKeySystemAccessInitializer (navigator.requestMediaKeySystemAccess() use above),
-                    //  1 MediaKeySystemAccessInitializer (isInitDataSupported() (via getSupportedInitDataType())))
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 1, 4, 'MediaKeys.create()');
+                    assert_equals(numMediaKeysCreated(), 1, 'MediaKeys.create()');
+                    assert_equals(numMediaKeySessionCreated(), 0, 'MediaKeys.create()');
 
                     mediaKeySession1 = mediaKeys.createSession();
                     return mediaKeySession1.generateRequest(initDataType, initData);
                 }).then(function() {
                     assert_true(mediaKeySession1.sessionId && mediaKeySession1.sessionId.length > 0);
 
-                    // Should be 1 MediaKeys + 1 MediaKeySession.
-                    // In non-Oilpan, numSuspendableObjectsCreate() == 2.
-                    // In Oilpan, numSuspendableObjectsCreate() <= 6.
-                    // (1 MediaKeys,
-                    //  1 MediaKeysInitializer and
-                    //  2 MediaKeySystemAccessInitializer,
-                    //  1 ContentDecryptionModuleResultPromise and
-                    //  1 MediaKeySession).
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 2, 6, 'MediaKeys.createSession(1)');
+                    assert_equals(numMediaKeysCreated(), 1, 'MediaKeys.createSession(1)');
+                    assert_equals(numMediaKeySessionCreated(), 1, 'MediaKeys.createSession(1)');
 
                     mediaKeySession2 = mediaKeys.createSession();
                     return mediaKeySession2.generateRequest(initDataType, initData);
                 }).then(function() {
                     assert_true(mediaKeySession2.sessionId && mediaKeySession2.sessionId.length > 0);
 
-                    // Should be 1 MediaKeys + 2 MediaKeySessions.
-                    // In non-Oilpan, numSuspendableObjectsCreate() == 3.
-                    // In Oilpan, numSuspendableObjectsCreate() <= 8.
-                    // (1 MediaKeys,
-                    //  1 MediaKeysInitializer and
-                    //  2 MediaKeySystemAccessInitializers,
-                    //  2 ContentDecryptionModuleResultPromise and
-                    //  2 MediaKeySession).
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 3, 8, 'mediaKeys.createSession(2)');
+                    assert_equals(numMediaKeysCreated(), 1, 'mediaKeys.createSession(2)');
+                    assert_equals(numMediaKeySessionCreated(), 2, 'mediaKeys.createSession(2)');
                 }).then(function(result) {
                     // Run gc(). All sessions should remain as we have a
                     // reference to each one.
                     return createGCPromise();
                 }).then(function(result) {
-                    // Should be just 1 MediaKeys + 2 MediaKeySessions.
-                    // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 3, 4, 'After gc()');
+                    assert_equals(numMediaKeysCreated(), 1, 'After gc()');
+                    assert_equals(numMediaKeySessionCreated(), 2, 'After gc()');
 
                     // Close the sessions. Once the close() event is received,
                     // they should get garbage collected as there are no JS
@@ -97,9 +81,8 @@
                 }).then(function(result) {
                     return createGCPromise();
                 }).then(function(result) {
-                    // Only MediaKeys + mediaKeySession2 should remain.
-                    // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 2, 3, 'mediaKeySession1 not collected');
+                    assert_equals(numMediaKeysCreated(), 1, 'mediaKeySession1 not collected');
+                    assert_equals(numMediaKeySessionCreated(), 1, 'mediaKeySession1 not collected');
 
                     var promise = mediaKeySession2.close();
                     mediaKeySession2 = null;
@@ -111,9 +94,8 @@
                 }).then(function(result) {
                     return createGCPromise();
                 }).then(function(result) {
-                    // Only MediaKeys should remain.
-                    // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 1, 2, 'mediaKeySession2 not collected');
+                    assert_equals(numMediaKeysCreated(), 1, 'mediaKeySession2 not collected');
+                    assert_equals(numMediaKeySessionCreated(), 0, 'mediaKeySession2 not collected');
 
                     assert_not_equals(mediaKeys, null);
                     test.done();
diff --git a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-release.html b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-release.html
index e0bb9cb..39d3db1e 100644
--- a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-release.html
+++ b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-mediakeysession-release.html
@@ -8,24 +8,29 @@
     </head>
     <body>
         <script>
-            // Since MediaKeySession (and MediaKeys) are SuspendableObjects,
-            // we can determine when they are garbage collected.
             // MediaKeySessions remain as long as:
             //   JavaScript has a reference to it
             //   OR (MediaKeys is around
             //       AND the session has not received a close() event)
             async_test(function(test)
             {
+                gc();
                 var mediaKeys;
                 var mediaKeySession1;
                 var mediaKeySession2;
                 var initDataType;
                 var initData;
-                var startingSuspendableObjectCount = window.internals.suspendableObjectCount(document);
+                var startingMediaKeysCount = window.internals.mediaKeysCount();
+                var startingMediaKeySessionCount = window.internals.mediaKeySessionCount();
 
-                function numSuspendableObjectsCreated()
+                function numMediaKeysCreated()
                 {
-                    return window.internals.suspendableObjectCount(document) - startingSuspendableObjectCount;
+                    return window.internals.mediaKeysCount() - startingMediaKeysCount;
+                }
+
+                function numMediaKeySessionCreated()
+                {
+                    return window.internals.mediaKeySessionCount() - startingMediaKeySessionCount;
                 }
 
                 // Create 2 sessions.
@@ -36,40 +41,20 @@
                 }).then(function(result) {
                     mediaKeys = result;
 
-                    // Verify MediaKeys is an SuspendableObject.
-                    // In non-Oilpan, numSuspendableObjectsCreate() == 1.
-                    // In Oilpan, numSuspendableObjectsCreate() <= 4.
-                    // (1 MediaKeys,
-                    //  1 MediaKeysInitializer and
-                    //  1 MediaKeySystemAccessInitializer (navigator.requestMediaKeySystemAccess() use above),
-                    //  1 MediaKeySystemAccessInitializer (isInitDataSupported() (via getSupportedInitDataType())))
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 1, 4, 'MediaKeys.create()');
+                    assert_equals(numMediaKeysCreated(), 1, 'MediaKeys.create()');
+                    assert_equals(numMediaKeySessionCreated(), 0, 'MediaKeys.create()');
 
                     mediaKeySession1 = mediaKeys.createSession();
                     return mediaKeySession1.generateRequest(initDataType, initData);
                 }).then(function() {
-                    // Should be 1 MediaKeys + 1 MediaKeySession.
-                    // In non-Oilpan, numSuspendableObjectsCreate() == 2.
-                    // In Oilpan, numSuspendableObjectsCreate() <= 6.
-                    // (1 MediaKeys,
-                    //  1 MediaKeysInitializer,
-                    //  2 MediaKeySystemAccessInitializers,
-                    //  1 ContentDecryptionModuleResultPromise and
-                    //  1 MediaKeySession).
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 2, 6, 'MediaKeys.createSession(1)');
+                    assert_equals(numMediaKeysCreated(), 1, 'MediaKeys.createSession(1)');
+                    assert_equals(numMediaKeySessionCreated(), 1, 'MediaKeys.createSession(1)');
 
                     mediaKeySession2 = mediaKeys.createSession();
                     return mediaKeySession2.generateRequest(initDataType, initData);
                 }).then(function() {
-                    // Should be 1 MediaKeys + 2 MediaKeySessions.
-                    // In non-Oilpan, numSuspendableObjectsCreate() == 3.
-                    // In Oilpan, numSuspendableObjectsCreate() <= 8.
-                    // (1 MediaKeys,
-                    //  1 MediaKeysInitializer,
-                    //  2 MediaKeySystemAccessInitializers,
-                    //  2 ContentDecryptionModuleResultPromise and
-                    //  2 MediaKeySession).
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 3, 8, 'mediaKeys.createSession(2)');
+                    assert_equals(numMediaKeysCreated(), 1, 'mediaKeys.createSession(2)');
+                    assert_equals(numMediaKeySessionCreated(), 2, 'mediaKeys.createSession(2)');
 
                     // Close the sessions. Once completed, only the JS
                     // reference to them keeps them around.
@@ -80,29 +65,20 @@
                     // Since both sessions have been closed, dropping the
                     // reference to them from JS will result in the session
                     // being garbage-collected.
-                    // Should be 1 MediaKeys + 2 MediaKeySessions.
-                    // In non-Oilpan, numSuspendableObjectsCreate() == 3.
-                    // In Oilpan, numSuspendableObjectsCreate() <= 10.
-                    // (1 MediaKeys,
-                    //  1 MediaKeysInitializer,
-                    //  2 MediaKeySystemAccessInitializers,
-                    //  4 ContentDecryptionModuleResultPromise and
-                    //  2 MediaKeySession).
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 3, 10, 'after close');
+                    assert_equals(numMediaKeysCreated(), 1, 'after close');
+                    assert_equals(numMediaKeySessionCreated(), 2, 'after close');
 
                     mediaKeySession1 = null;
                     return createGCPromise();
                 }).then(function() {
-                    // Only MediaKeys + mediaKeySession2 should remain.
-                    // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 2, 3, 'mediaKeySession1 not collected');
+                    assert_equals(numMediaKeysCreated(), 1, 'mediaKeySession1 not collected');
+                    assert_equals(numMediaKeySessionCreated(), 1, 'mediaKeySession1 not collected');
 
                     mediaKeySession2 = null;
                     return createGCPromise();
                 }).then(function() {
-                    // Only MediaKeys should remain.
-                    // In non-Oilpan, there is also something from createGCPromise().
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 1, 2, 'mediaKeySession2 not collected');
+                    assert_equals(numMediaKeysCreated(), 1, 'mediaKeySession2 not collected');
+                    assert_equals(numMediaKeySessionCreated(), 0, 'mediaKeySession2 not collected');
                     test.done();
                 }).catch(function(error) {
                     forceTestFailureFromPromise(test, error);
diff --git a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-multiple-mediakeys.html b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-multiple-mediakeys.html
index c6f3f647..2ccba75e 100644
--- a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-multiple-mediakeys.html
+++ b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-lifetime-multiple-mediakeys.html
@@ -11,12 +11,13 @@
             // For this test, create several MediaKeys and verify lifetime.
             async_test(function(test)
             {
+                gc();
                 var mediaKeys;
-                var startingSuspendableObjectCount = window.internals.suspendableObjectCount(document);
+                var startingMediaKeysCount = window.internals.mediaKeysCount();
 
-                function numSuspendableObjectsCreated()
+                function numMediaKeysCreated()
                 {
-                    return window.internals.suspendableObjectCount(document) - startingSuspendableObjectCount;
+                    return window.internals.mediaKeysCount() - startingMediaKeysCount;
                 }
 
                 // Create a MediaKeys object. Returns a promise that resolves
@@ -33,54 +34,23 @@
                 // Create a few MediaKeys objects. Only keep a reference to the
                 // last one created.
                 createMediaKeys().then(function(result) {
-                    // Should be 1 MediaKeys.
-                    // In non-Oilpan, numSuspendableObjectsCreate() == 1.
-                    // In Oilpan, numSuspendableObjectsCreated() <= 4.
-                    // (1 MediaKeysInitializer,
-                    //  1 MediaKeySystemAccessInitializer (navigator.requestMediaKeySystemAccess() use above),
-                    //  1 MediaKeySystemAccessInitializer (isInitDataSupported() (via getSupportedInitDataType())) and
-                    //  1 ContentDecryptionModuleResultPromise).
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 1, 4);
+                    assert_equals(numMediaKeysCreated(), 1);
 
                     return createMediaKeys();
                 }).then(function(result) {
-                    // Should be 2 MediaKeys.
-                    // In non-Oilpan, numSuspendableObjectsCreate() == 2.
-                    // In Oilpan, numSuspendableObjectsCreate() <= 8.
-                    // (2 MediaKeysInitializer,
-                    //  4 MediaKeySystemAccessInitializer and
-                    //  2 ContentDecryptionModuleResultPromise).
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 2, 8);
+                    assert_equals(numMediaKeysCreated(), 2);
 
                     return createMediaKeys();
                 }).then(function(result) {
-                    // Should be 3 MediaKeys.
-                    // In non-Oilpan, numSuspendableObjectsCreate() == 3.
-                    // In Oilpan, numSuspendableObjectsCreate() <= 12.
-                    // (3 MediaKeysInitializer,
-                    //  6 MediaKeySystemAccessInitializer and
-                    //  3 ContentDecryptionModuleResultPromise).
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 3, 12);
+                    assert_equals(numMediaKeysCreated(), 3);
 
                     return createMediaKeys();
                 }).then(function(result) {
-                    // Should be 4 MediaKeys.
-                    // In non-Oilpan, numSuspendableObjectsCreate() == 4.
-                    // In Oilpan, numSuspendableObjectsCreate() <= 16.
-                    // (4 MediaKeysInitializer,
-                    //  8 MediaKeySystemAccessInitializer and
-                    //  4 ContentDecryptionModuleResultPromise).
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 4, 16);
+                    assert_equals(numMediaKeysCreated(), 4);
 
                     return createMediaKeys();
                 }).then(function(result) {
-                    // Should be 5 MediaKeys.
-                    // In non-Oilpan, numSuspendableObjectsCreate() == 5.
-                    // In Oilpan, numSuspendableObjectsCreate() <= 20.
-                    // (5 MediaKeysInitializer,
-                    //  10 MediaKeySystemAccessInitializer and
-                    //  5 ContentDecryptionModuleResultPromise).
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 5, 20);
+                    assert_equals(numMediaKeysCreated(), 5);
 
                     // |mediaKeys| refers to the most recently created MediaKeys
                     // object.
@@ -90,22 +60,14 @@
                     // collected, it needs time to process any pending events.
                     return delayToAllowEventProcessingPromise();
                 }).then(function(result) {
-                    // In non-Oilpan, numSuspendableObjectsCreated() == 5
-                    // (5 MediaKeySession objects).
-                    // In Oilpan, numSuspendableObjectsCreated() <= 23
-                    // (5 MediaKeysInitializer,
-                    //  12 MediaKeySystemAccessInitializer,
-                    //  5 ContentDecryptionModuleResultPromise and
-                    //  1 DOMTimer (in delayToAllowEventProcessingPromise))
-                    assert_between_inclusive(numSuspendableObjectsCreated(), 5, 23);
+                    assert_equals(numMediaKeysCreated(), 5);
 
                     // As we only have a reference (|mediaKeys|) to the last
                     // created MediaKeys object, the other 4 MediaKeys objects
                     // are available to be garbage collected.
                     return createGCPromise();
                 }).then(function(result) {
-                    // Should be 1 MediaKeys and DOMTimer.
-                    assert_less_than_equal(numSuspendableObjectsCreated(), 2);
+                    assert_equals(numMediaKeysCreated(), 1);
                     assert_equals(typeof mediaKeys.createSession, 'function');
 
                     // Release the last MediaKeys object created.
@@ -114,8 +76,7 @@
                     // Run gc() again to reclaim the remaining MediaKeys object.
                     return createGCPromise();
                 }).then(function(result) {
-                    // Should be just a DOMTimer.
-                    assert_less_than_equal(numSuspendableObjectsCreated(), 1);
+                    assert_equals(numMediaKeysCreated(), 0);
                     test.done();
                 }).catch(function(error) {
                     forceTestFailureFromPromise(test, error);
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp
index 1e8ba46..c9c3ea6 100644
--- a/third_party/WebKit/Source/core/testing/Internals.cpp
+++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -1481,6 +1481,15 @@
   overrideUserPreferredLanguages(atomicLanguages);
 }
 
+unsigned Internals::mediaKeysCount() {
+  return InstanceCounters::counterValue(InstanceCounters::MediaKeysCounter);
+}
+
+unsigned Internals::mediaKeySessionCount() {
+  return InstanceCounters::counterValue(
+      InstanceCounters::MediaKeySessionCounter);
+}
+
 unsigned Internals::suspendableObjectCount(Document* document) {
   DCHECK(document);
   return document->suspendableObjectCount();
diff --git a/third_party/WebKit/Source/core/testing/Internals.h b/third_party/WebKit/Source/core/testing/Internals.h
index f5ac99d..6555c780 100644
--- a/third_party/WebKit/Source/core/testing/Internals.h
+++ b/third_party/WebKit/Source/core/testing/Internals.h
@@ -258,6 +258,8 @@
   Vector<AtomicString> userPreferredLanguages() const;
   void setUserPreferredLanguages(const Vector<String>&);
 
+  unsigned mediaKeysCount();
+  unsigned mediaKeySessionCount();
   unsigned suspendableObjectCount(Document*);
   unsigned wheelEventHandlerCount(Document*);
   unsigned scrollEventHandlerCount(Document*);
diff --git a/third_party/WebKit/Source/core/testing/Internals.idl b/third_party/WebKit/Source/core/testing/Internals.idl
index 0c056a4..42ca8c2 100644
--- a/third_party/WebKit/Source/core/testing/Internals.idl
+++ b/third_party/WebKit/Source/core/testing/Internals.idl
@@ -145,6 +145,8 @@
     sequence<DOMString> userPreferredLanguages();
     void setUserPreferredLanguages(sequence<DOMString> languages);
 
+    unsigned long mediaKeysCount();
+    unsigned long mediaKeySessionCount();
     unsigned long suspendableObjectCount(Document document);
     unsigned long wheelEventHandlerCount(Document document);
     unsigned long scrollEventHandlerCount(Document document);
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp
index 81fe924..69f525f 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp
+++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp
@@ -40,6 +40,7 @@
 #include "modules/encryptedmedia/MediaKeyMessageEvent.h"
 #include "modules/encryptedmedia/MediaKeys.h"
 #include "platform/ContentDecryptionModuleResult.h"
+#include "platform/InstanceCounters.h"
 #include "platform/Timer.h"
 #include "platform/network/mime/ContentType.h"
 #include "public/platform/WebContentDecryptionModule.h"
@@ -378,6 +379,7 @@
                                         ClosedPromise::Closed)),
       m_actionTimer(this, &MediaKeySession::actionTimerFired) {
   DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")";
+  InstanceCounters::incrementCounter(InstanceCounters::MediaKeySessionCounter);
 
   // Create the matching Chromium object. It will not be usable until
   // initializeNewSession() is called in response to the user calling
@@ -419,6 +421,7 @@
 
 MediaKeySession::~MediaKeySession() {
   DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")";
+  InstanceCounters::decrementCounter(InstanceCounters::MediaKeySessionCounter);
 }
 
 void MediaKeySession::dispose() {
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp
index 7cbe44c..039d7ac 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp
+++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp
@@ -36,6 +36,7 @@
 #include "modules/encryptedmedia/ContentDecryptionModuleResultPromise.h"
 #include "modules/encryptedmedia/EncryptedMediaUtils.h"
 #include "modules/encryptedmedia/MediaKeySession.h"
+#include "platform/InstanceCounters.h"
 #include "platform/Timer.h"
 #include "public/platform/WebContentDecryptionModule.h"
 #include "wtf/RefPtr.h"
@@ -146,10 +147,12 @@
       m_reservedForMediaElement(false),
       m_timer(this, &MediaKeys::timerFired) {
   DVLOG(MEDIA_KEYS_LOG_LEVEL) << __func__ << "(" << this << ")";
+  InstanceCounters::incrementCounter(InstanceCounters::MediaKeysCounter);
 }
 
 MediaKeys::~MediaKeys() {
   DVLOG(MEDIA_KEYS_LOG_LEVEL) << __func__ << "(" << this << ")";
+  InstanceCounters::decrementCounter(InstanceCounters::MediaKeysCounter);
 }
 
 MediaKeySession* MediaKeys::createSession(ScriptState* scriptState,
diff --git a/third_party/WebKit/Source/modules/mediasession/MediaSession.cpp b/third_party/WebKit/Source/modules/mediasession/MediaSession.cpp
index 50c4613..90b46c9 100644
--- a/third_party/WebKit/Source/modules/mediasession/MediaSession.cpp
+++ b/third_party/WebKit/Source/modules/mediasession/MediaSession.cpp
@@ -93,7 +93,7 @@
 }  // anonymous namespace
 
 MediaSession::MediaSession(ExecutionContext* executionContext)
-    : ContextLifecycleObserver(executionContext),
+    : ContextClient(executionContext),
       m_playbackState(mojom::blink::MediaSessionPlaybackState::NONE),
       m_clientBinding(this) {}
 
@@ -145,7 +145,7 @@
 }
 
 ExecutionContext* MediaSession::getExecutionContext() const {
-  return ContextLifecycleObserver::getExecutionContext();
+  return ContextClient::getExecutionContext();
 }
 
 mojom::blink::MediaSessionService* MediaSession::getService() {
@@ -207,7 +207,7 @@
 DEFINE_TRACE(MediaSession) {
   visitor->trace(m_metadata);
   EventTargetWithInlineData::trace(visitor);
-  ContextLifecycleObserver::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/mediasession/MediaSession.h b/third_party/WebKit/Source/modules/mediasession/MediaSession.h
index 00a7ba80..afe12e4 100644
--- a/third_party/WebKit/Source/modules/mediasession/MediaSession.h
+++ b/third_party/WebKit/Source/modules/mediasession/MediaSession.h
@@ -21,7 +21,7 @@
 
 class MODULES_EXPORT MediaSession final
     : public EventTargetWithInlineData,
-      public ContextLifecycleObserver,
+      public ContextClient,
       blink::mojom::blink::MediaSessionClient {
   USING_GARBAGE_COLLECTED_MIXIN(MediaSession);
   DEFINE_WRAPPERTYPEINFO();
diff --git a/third_party/WebKit/Source/platform/InstanceCounters.h b/third_party/WebKit/Source/platform/InstanceCounters.h
index fe756f5..0a55ef35 100644
--- a/third_party/WebKit/Source/platform/InstanceCounters.h
+++ b/third_party/WebKit/Source/platform/InstanceCounters.h
@@ -42,15 +42,17 @@
 
  public:
   enum CounterType {
-    SuspendableObjectCounter,
     AudioHandlerCounter,
     DocumentCounter,
     FrameCounter,
     JSEventListenerCounter,
     LayoutObjectCounter,
+    MediaKeySessionCounter,
+    MediaKeysCounter,
     NodeCounter,
     ResourceCounter,
     ScriptPromiseCounter,
+    SuspendableObjectCounter,
     V8PerContextDataCounter,
     WorkerGlobalScopeCounter,
 
diff --git a/third_party/WebKit/Source/platform/heap/BlinkGC.h b/third_party/WebKit/Source/platform/heap/BlinkGC.h
index a6f9995c..d05033f 100644
--- a/third_party/WebKit/Source/platform/heap/BlinkGC.h
+++ b/third_party/WebKit/Source/platform/heap/BlinkGC.h
@@ -68,22 +68,10 @@
     // Only the marking task runs in ThreadHeap::collectGarbage().
     // The sweeping task is split into chunks and scheduled lazily.
     GCWithoutSweep,
-    // After the marking task has run in ThreadHeap::collectGarbage(),
-    // sweep compaction of some heap arenas is performed. The sweeping
-    // of the remaining arenas is split into chunks and scheduled lazily.
-    GCWithSweepCompaction,
     // Only the marking task runs just to take a heap snapshot.
     // The sweeping task doesn't run. The marks added in the marking task
     // are just cleared.
     TakeSnapshot,
-    // The marking task does not mark objects outside the heap of the GCing
-    // thread.
-    ThreadTerminationGC,
-    // Just run thread-local weak processing. The weak processing may trace
-    // already marked objects but it must not trace any unmarked object.
-    // It's unfortunate that the thread-local weak processing requires
-    // a marking visitor. See TODO in HashTable::process.
-    ThreadLocalWeakProcessing,
   };
 
   enum GCReason {
diff --git a/third_party/WebKit/Source/platform/heap/HeapCompact.cpp b/third_party/WebKit/Source/platform/heap/HeapCompact.cpp
index 43f2d22..24d47af 100644
--- a/third_party/WebKit/Source/platform/heap/HeapCompact.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapCompact.cpp
@@ -343,7 +343,7 @@
 #endif
 }
 
-BlinkGC::GCType HeapCompact::initialize(ThreadState* state) {
+void HeapCompact::initialize(ThreadState* state) {
   DCHECK(RuntimeEnabledFeatures::heapCompactionEnabled());
   LOG_HEAP_COMPACTION("Compacting: free=%zu\n", m_freeListSize);
   m_doCompact = true;
@@ -353,7 +353,6 @@
   m_fixups.reset();
   m_gcCountSinceLastCompaction = 0;
   s_forceCompactionGC = false;
-  return BlinkGC::GCWithSweepCompaction;
 }
 
 void HeapCompact::registerMovingObjectReference(MovableReference* slot) {
diff --git a/third_party/WebKit/Source/platform/heap/HeapCompact.h b/third_party/WebKit/Source/platform/heap/HeapCompact.h
index 8565eb9..23afccda 100644
--- a/third_party/WebKit/Source/platform/heap/HeapCompact.h
+++ b/third_party/WebKit/Source/platform/heap/HeapCompact.h
@@ -55,7 +55,7 @@
   // Compaction should be performed as part of the ongoing GC, initialize
   // the heap compaction pass. Returns the appropriate visitor type to
   // use when running the marking phase.
-  BlinkGC::GCType initialize(ThreadState*);
+  void initialize(ThreadState*);
 
   // Returns true if the ongoing GC will perform compaction.
   bool isCompacting() const { return m_doCompact; }
diff --git a/third_party/WebKit/Source/platform/heap/MarkingVisitor.h b/third_party/WebKit/Source/platform/heap/MarkingVisitor.h
index b5eb0b4..9416e4d 100644
--- a/third_party/WebKit/Source/platform/heap/MarkingVisitor.h
+++ b/third_party/WebKit/Source/platform/heap/MarkingVisitor.h
@@ -9,14 +9,14 @@
 
 namespace blink {
 
-template <Visitor::MarkingMode Mode>
 class MarkingVisitor final : public Visitor,
-                             public MarkingVisitorImpl<MarkingVisitor<Mode>> {
+                             public MarkingVisitorImpl<MarkingVisitor> {
  public:
-  using Impl = MarkingVisitorImpl<MarkingVisitor<Mode>>;
-  friend class MarkingVisitorImpl<MarkingVisitor<Mode>>;
+  using Impl = MarkingVisitorImpl<MarkingVisitor>;
+  friend class MarkingVisitorImpl<MarkingVisitor>;
 
-  explicit MarkingVisitor(ThreadState* state) : Visitor(state, Mode) {}
+  explicit MarkingVisitor(ThreadState* state, Visitor::MarkingMode mode)
+      : Visitor(state, mode) {}
 
   void markHeader(HeapObjectHeader* header, TraceCallback callback) override {
     Impl::markHeader(header, header->payload(), callback);
@@ -69,7 +69,7 @@
 
  protected:
   inline bool shouldMarkObject(const void* objectPointer) const {
-    if (Mode != ThreadLocalMarking)
+    if (getMarkingMode() != ThreadLocalMarking)
       return true;
 
     BasePage* page = pageFromObject(objectPointer);
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.cpp b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
index fa5ef1d..53497e7 100644
--- a/third_party/WebKit/Source/platform/heap/ThreadState.cpp
+++ b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
@@ -507,7 +507,7 @@
 
   GCForbiddenScope gcForbiddenScope(this);
   std::unique_ptr<Visitor> visitor =
-      Visitor::create(this, BlinkGC::ThreadLocalWeakProcessing);
+      Visitor::create(this, Visitor::WeakProcessing);
 
   // Perform thread-specific weak processing.
   while (popAndInvokeThreadLocalWeakCallback(visitor.get())) {
@@ -1708,8 +1708,6 @@
 void ThreadState::collectGarbage(BlinkGC::StackState stackState,
                                  BlinkGC::GCType gcType,
                                  BlinkGC::GCReason reason) {
-  DCHECK_NE(gcType, BlinkGC::ThreadTerminationGC);
-
   // Nested collectGarbage() invocations aren't supported.
   RELEASE_ASSERT(!isGCForbidden());
   completeSweep();
@@ -1725,11 +1723,18 @@
   if (!parkThreadsScope.parkThreads())
     return;
 
-  BlinkGC::GCType visitorType = gcType;
-  if (heap().compaction()->shouldCompact(this, gcType, reason))
-    visitorType = heap().compaction()->initialize(this);
-
-  std::unique_ptr<Visitor> visitor = Visitor::create(this, visitorType);
+  std::unique_ptr<Visitor> visitor;
+  if (gcType == BlinkGC::TakeSnapshot) {
+    visitor = Visitor::create(this, Visitor::SnapshotMarking);
+  } else {
+    DCHECK(gcType == BlinkGC::GCWithSweep || gcType == BlinkGC::GCWithoutSweep);
+    if (heap().compaction()->shouldCompact(this, gcType, reason)) {
+      heap().compaction()->initialize(this);
+      visitor = Visitor::create(this, Visitor::GlobalMarkingWithCompaction);
+    } else {
+      visitor = Visitor::create(this, Visitor::GlobalMarking);
+    }
+  }
 
   ScriptForbiddenIfMainThreadScope scriptForbidden;
 
@@ -1833,7 +1838,7 @@
     // ThreadTerminationGC.
     GCForbiddenScope gcForbiddenScope(this);
     std::unique_ptr<Visitor> visitor =
-        Visitor::create(this, BlinkGC::ThreadTerminationGC);
+        Visitor::create(this, Visitor::ThreadLocalMarking);
 
     NoAllocationScope noAllocationScope(this);
 
diff --git a/third_party/WebKit/Source/platform/heap/Visitor.cpp b/third_party/WebKit/Source/platform/heap/Visitor.cpp
index 51ff206..c577969 100644
--- a/third_party/WebKit/Source/platform/heap/Visitor.cpp
+++ b/third_party/WebKit/Source/platform/heap/Visitor.cpp
@@ -12,26 +12,8 @@
 
 namespace blink {
 
-std::unique_ptr<Visitor> Visitor::create(ThreadState* state,
-                                         BlinkGC::GCType gcType) {
-  switch (gcType) {
-    case BlinkGC::GCWithSweep:
-    case BlinkGC::GCWithoutSweep:
-      return WTF::makeUnique<MarkingVisitor<Visitor::GlobalMarking>>(state);
-    case BlinkGC::GCWithSweepCompaction:
-      return WTF::makeUnique<
-          MarkingVisitor<Visitor::GlobalMarkingWithCompaction>>(state);
-    case BlinkGC::TakeSnapshot:
-      return WTF::makeUnique<MarkingVisitor<Visitor::SnapshotMarking>>(state);
-    case BlinkGC::ThreadTerminationGC:
-      return WTF::makeUnique<MarkingVisitor<Visitor::ThreadLocalMarking>>(
-          state);
-    case BlinkGC::ThreadLocalWeakProcessing:
-      return WTF::makeUnique<MarkingVisitor<Visitor::WeakProcessing>>(state);
-    default:
-      ASSERT_NOT_REACHED();
-  }
-  return nullptr;
+std::unique_ptr<Visitor> Visitor::create(ThreadState* state, MarkingMode mode) {
+  return WTF::makeUnique<MarkingVisitor>(state, mode);
 }
 
 Visitor::Visitor(ThreadState* state, MarkingMode markingMode)
diff --git a/third_party/WebKit/Source/platform/heap/Visitor.h b/third_party/WebKit/Source/platform/heap/Visitor.h
index 54b74dc5..8da6dc1 100644
--- a/third_party/WebKit/Source/platform/heap/Visitor.h
+++ b/third_party/WebKit/Source/platform/heap/Visitor.h
@@ -318,7 +318,7 @@
     GlobalMarkingWithCompaction,
   };
 
-  static std::unique_ptr<Visitor> create(ThreadState*, BlinkGC::GCType);
+  static std::unique_ptr<Visitor> create(ThreadState*, MarkingMode);
 
   virtual ~Visitor();
 
diff --git a/ui/file_manager/audio_player/js/compiled_resources.gyp b/ui/file_manager/audio_player/js/compiled_resources.gyp
index 1f858764..05df70c 100644
--- a/ui/file_manager/audio_player/js/compiled_resources.gyp
+++ b/ui/file_manager/audio_player/js/compiled_resources.gyp
@@ -107,6 +107,7 @@
           '<(EXTERNS_DIR)/file_manager_private.js',
           '<(EXTERNS_DIR)/metrics_private.js',
           '../../../../third_party/analytics/externs.js',
+          '../../externs/app_window_common.js',
           '../../externs/audio_player_foreground.js',
           '../../externs/background_window_common.js',
           '../../externs/chrome_test.js',
diff --git a/ui/file_manager/externs/video_player_foreground.js b/ui/file_manager/externs/app_window_common.js
similarity index 79%
rename from ui/file_manager/externs/video_player_foreground.js
rename to ui/file_manager/externs/app_window_common.js
index 40ab0be..302966d 100644
--- a/ui/file_manager/externs/video_player_foreground.js
+++ b/ui/file_manager/externs/app_window_common.js
@@ -1,4 +1,4 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -7,4 +7,4 @@
  * ui/file_manager/file_manager/common/js/util.js.
  * @type {string}
  */
-Window.prototype.appID;
+Window.prototype.appID;
\ No newline at end of file
diff --git a/ui/file_manager/externs/audio_player_foreground.js b/ui/file_manager/externs/audio_player_foreground.js
index 3841996..6083f65 100644
--- a/ui/file_manager/externs/audio_player_foreground.js
+++ b/ui/file_manager/externs/audio_player_foreground.js
@@ -3,13 +3,6 @@
 // found in the LICENSE file.
 
 /**
- * This definition is required by
- * ui/file_manager/file_manager/common/js/util.js.
- * @type {string}
- */
-Window.prototype.appID;
-
-/**
  * @typedef {?{
  *   position: (number|undefined),
  *   time: (number|undefined),
diff --git a/ui/file_manager/externs/compiled_resources2.gyp b/ui/file_manager/externs/compiled_resources2.gyp
index 1ff75bdb..5f12e5c 100644
--- a/ui/file_manager/externs/compiled_resources2.gyp
+++ b/ui/file_manager/externs/compiled_resources2.gyp
@@ -4,6 +4,10 @@
 {
   'targets': [
     {
+      'target_name': 'app_window_common',
+      'includes': ['../../../third_party/closure_compiler/include_js.gypi'],
+    },
+    {
       'target_name': 'audio_player_foreground',
       'includes': ['../../../third_party/closure_compiler/include_js.gypi'],
     },
@@ -48,6 +52,10 @@
       'includes': ['../../../third_party/closure_compiler/include_js.gypi'],
     },
     {
+      'target_name': 'entry_location',
+      'includes': ['../../../third_party/closure_compiler/include_js.gypi'],
+    },
+    {
       'target_name': 'es6_workaround',
       'includes': ['../../../third_party/closure_compiler/include_js.gypi'],
     },
diff --git a/ui/file_manager/externs/gallery_background.js b/ui/file_manager/externs/gallery_background.js
index 099e8b4..b7486cbc 100644
--- a/ui/file_manager/externs/gallery_background.js
+++ b/ui/file_manager/externs/gallery_background.js
@@ -14,10 +14,3 @@
  * @type {Promise}
  */
 window.initializePromise;
-
-/**
- * This definition is required by
- * ui/file_manager/file_manager/common/js/util.js.
- * @type {string}
- */
-Window.prototype.appID;
diff --git a/ui/file_manager/externs/gallery_foreground.js b/ui/file_manager/externs/gallery_foreground.js
index 1bf5054..552490b 100644
--- a/ui/file_manager/externs/gallery_foreground.js
+++ b/ui/file_manager/externs/gallery_foreground.js
@@ -29,13 +29,6 @@
 function FileManager() {}
 
 /**
- * This definition is required by
- * ui/file_manager/file_manager/common/js/util.js.
- * @type {string}
- */
-Window.prototype.appID;
-
-/**
  * A global flag which indicates whether it is in tests or not. This is set in
  * gallery/js/background.js.
  *
diff --git a/ui/file_manager/file_manager/common/js/compiled_resources2.gyp b/ui/file_manager/file_manager/common/js/compiled_resources2.gyp
index 60b3ad1..02011536 100644
--- a/ui/file_manager/file_manager/common/js/compiled_resources2.gyp
+++ b/ui/file_manager/file_manager/common/js/compiled_resources2.gyp
@@ -35,18 +35,26 @@
 #      'target_name': 'metrics_events',
 #      'includes': ['../../../compile_js2.gypi'],
 #    },
-#    {
-#      'target_name': 'progress_center_common',
-#      'includes': ['../../../compile_js2.gypi'],
-#    },
-#    {
-#      'target_name': 'test_importer_common',
-#      'includes': ['../../../compile_js2.gypi'],
-#    },
-#    {
-#      'target_name': 'util',
-#      'includes': ['../../../compile_js2.gypi'],
-#    },
+    {
+      'target_name': 'progress_center_common',
+      'includes': ['../../../compile_js2.gypi'],
+    },
+    {
+      'target_name': 'util',
+      'dependencies': [
+        '<(DEPTH)/ui/file_manager/externs/compiled_resources2.gyp:app_window_common',
+        '<(DEPTH)/ui/file_manager/externs/compiled_resources2.gyp:entry_location',
+        '<(DEPTH)/ui/file_manager/externs/compiled_resources2.gyp:platform',
+        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data',
+        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util',
+        '<(DEPTH)/ui/webui/resources/js/cr/compiled_resources2.gyp:event_target',
+        '<(DEPTH)/ui/webui/resources/js/cr/compiled_resources2.gyp:ui',
+        '<(EXTERNS_GYP):chrome_extensions',
+        '<(EXTERNS_GYP):file_manager_private',
+        'volume_manager_common',
+      ],
+      'includes': ['../../../compile_js2.gypi'],
+    },
     {
       'target_name': 'volume_manager_common',
       'dependencies': [
diff --git a/ui/file_manager/gallery/js/compiled_resources.gyp b/ui/file_manager/gallery/js/compiled_resources.gyp
index da3dc667..1757186 100644
--- a/ui/file_manager/gallery/js/compiled_resources.gyp
+++ b/ui/file_manager/gallery/js/compiled_resources.gyp
@@ -38,6 +38,7 @@
           '<(EXTERNS_DIR)/file_manager_private.js',
           '<(EXTERNS_DIR)/metrics_private.js',
           '../../../../third_party/analytics/externs.js',
+          '../../externs/app_window_common.js',
           '../../externs/chrome_test.js',
           '../../externs/entry_location.js',
           '../../externs/es6_workaround.js',
@@ -149,6 +150,7 @@
           '<(EXTERNS_DIR)/metrics_private.js',
           '../../../../third_party/analytics/externs.js',
           '../../../../third_party/closure_compiler/externs/polymer-1.0.js',
+          '../../externs/app_window_common.js',
           '../../externs/background_window_common.js',
           '../../externs/chrome_test.js',
           '../../externs/entry_location.js',
diff --git a/ui/file_manager/video_player/js/compiled_resources.gyp b/ui/file_manager/video_player/js/compiled_resources.gyp
index a28ef81..41d4ea21 100644
--- a/ui/file_manager/video_player/js/compiled_resources.gyp
+++ b/ui/file_manager/video_player/js/compiled_resources.gyp
@@ -114,6 +114,7 @@
           '<(EXTERNS_DIR)/media_player_private.js',
           '<(EXTERNS_DIR)/metrics_private.js',
           '../../../../third_party/analytics/externs.js',
+          '../../externs/app_window_common.js',
           '../../externs/background_window_common.js',
           '../../externs/chrome_test.js',
           '../../externs/chrome_cast.js',
@@ -121,7 +122,6 @@
           '../../externs/entry_location.js',
           '../../externs/es6_workaround.js',
           '../../externs/platform.js',
-          '../../externs/video_player_foreground.js',
           '../../externs/volume_info.js',
           '../../externs/volume_info_list.js',
           '../../externs/volume_manager.js',