diff --git a/test/cctest/test-weakmaps.cc b/test/cctest/test-weakmaps.cc
index 56d5936..bb412a8 100644
--- a/test/cctest/test-weakmaps.cc
+++ b/test/cctest/test-weakmaps.cc
@@ -25,70 +25,89 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include "v8.h"
+#include <utility>
 
-#include "global-handles.h"
-#include "snapshot.h"
-#include "cctest.h"
+#include "src/v8.h"
+
+#include "src/global-handles.h"
+#include "src/snapshot.h"
+#include "test/cctest/cctest.h"
 
 using namespace v8::internal;
 
 
-static Handle<JSWeakMap> AllocateJSWeakMap() {
-  Handle<Map> map = FACTORY->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
-  Handle<JSObject> weakmap_obj = FACTORY->NewJSObjectFromMap(map);
+static Isolate* GetIsolateFrom(LocalContext* context) {
+  return reinterpret_cast<Isolate*>((*context)->GetIsolate());
+}
+
+
+static Handle<JSWeakMap> AllocateJSWeakMap(Isolate* isolate) {
+  Factory* factory = isolate->factory();
+  Handle<Map> map = factory->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
+  Handle<JSObject> weakmap_obj = factory->NewJSObjectFromMap(map);
   Handle<JSWeakMap> weakmap(JSWeakMap::cast(*weakmap_obj));
-  // Do not use handles for the hash table, it would make entries strong.
-  Object* table_obj = ObjectHashTable::Allocate(1)->ToObjectChecked();
-  ObjectHashTable* table = ObjectHashTable::cast(table_obj);
-  weakmap->set_table(table);
-  weakmap->set_next(Smi::FromInt(0));
+  // Do not leak handles for the hash table, it would make entries strong.
+  {
+    HandleScope scope(isolate);
+    Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 1);
+    weakmap->set_table(*table);
+  }
   return weakmap;
 }
 
 static void PutIntoWeakMap(Handle<JSWeakMap> weakmap,
                            Handle<JSObject> key,
-                           int value) {
-  Handle<ObjectHashTable> table = PutIntoObjectHashTable(
+                           Handle<Object> value) {
+  Handle<ObjectHashTable> table = ObjectHashTable::Put(
       Handle<ObjectHashTable>(ObjectHashTable::cast(weakmap->table())),
       Handle<JSObject>(JSObject::cast(*key)),
-      Handle<Smi>(Smi::FromInt(value)));
+      value);
   weakmap->set_table(*table);
 }
 
 static int NumberOfWeakCalls = 0;
-static void WeakPointerCallback(v8::Persistent<v8::Value> handle, void* id) {
-  ASSERT(id == reinterpret_cast<void*>(1234));
+static void WeakPointerCallback(
+    const v8::WeakCallbackData<v8::Value, void>& data) {
+  std::pair<v8::Persistent<v8::Value>*, int>* p =
+      reinterpret_cast<std::pair<v8::Persistent<v8::Value>*, int>*>(
+          data.GetParameter());
+  DCHECK_EQ(1234, p->second);
   NumberOfWeakCalls++;
-  handle.Dispose();
+  p->first->Reset();
 }
 
 
 TEST(Weakness) {
+  FLAG_incremental_marking = false;
   LocalContext context;
-  v8::HandleScope scope;
-  Handle<JSWeakMap> weakmap = AllocateJSWeakMap();
-  GlobalHandles* global_handles = Isolate::Current()->global_handles();
+  Isolate* isolate = GetIsolateFrom(&context);
+  Factory* factory = isolate->factory();
+  Heap* heap = isolate->heap();
+  HandleScope scope(isolate);
+  Handle<JSWeakMap> weakmap = AllocateJSWeakMap(isolate);
+  GlobalHandles* global_handles = isolate->global_handles();
 
   // Keep global reference to the key.
   Handle<Object> key;
   {
-    v8::HandleScope scope;
-    Handle<Map> map = FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
-    Handle<JSObject> object = FACTORY->NewJSObjectFromMap(map);
+    HandleScope scope(isolate);
+    Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
+    Handle<JSObject> object = factory->NewJSObjectFromMap(map);
     key = global_handles->Create(*object);
   }
   CHECK(!global_handles->IsWeak(key.location()));
 
   // Put entry into weak map.
   {
-    v8::HandleScope scope;
-    PutIntoWeakMap(weakmap, Handle<JSObject>(JSObject::cast(*key)), 23);
+    HandleScope scope(isolate);
+    PutIntoWeakMap(weakmap,
+                   Handle<JSObject>(JSObject::cast(*key)),
+                   Handle<Smi>(Smi::FromInt(23), isolate));
   }
   CHECK_EQ(1, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
 
   // Force a full GC.
-  HEAP->CollectAllGarbage(false);
+  heap->CollectAllGarbage(false);
   CHECK_EQ(0, NumberOfWeakCalls);
   CHECK_EQ(1, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
   CHECK_EQ(
@@ -96,22 +115,23 @@
 
   // Make the global reference to the key weak.
   {
-    v8::HandleScope scope;
-    global_handles->MakeWeak(key.location(),
-                             reinterpret_cast<void*>(1234),
-                             &WeakPointerCallback);
+    HandleScope scope(isolate);
+    std::pair<Handle<Object>*, int> handle_and_id(&key, 1234);
+    GlobalHandles::MakeWeak(key.location(),
+                            reinterpret_cast<void*>(&handle_and_id),
+                            &WeakPointerCallback);
   }
   CHECK(global_handles->IsWeak(key.location()));
 
   // Force a full GC.
   // Perform two consecutive GCs because the first one will only clear
   // weak references whereas the second one will also clear weak maps.
-  HEAP->CollectAllGarbage(false);
+  heap->CollectAllGarbage(false);
   CHECK_EQ(1, NumberOfWeakCalls);
   CHECK_EQ(1, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
   CHECK_EQ(
       0, ObjectHashTable::cast(weakmap->table())->NumberOfDeletedElements());
-  HEAP->CollectAllGarbage(false);
+  heap->CollectAllGarbage(false);
   CHECK_EQ(1, NumberOfWeakCalls);
   CHECK_EQ(0, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
   CHECK_EQ(
@@ -121,19 +141,22 @@
 
 TEST(Shrinking) {
   LocalContext context;
-  v8::HandleScope scope;
-  Handle<JSWeakMap> weakmap = AllocateJSWeakMap();
+  Isolate* isolate = GetIsolateFrom(&context);
+  Factory* factory = isolate->factory();
+  Heap* heap = isolate->heap();
+  HandleScope scope(isolate);
+  Handle<JSWeakMap> weakmap = AllocateJSWeakMap(isolate);
 
   // Check initial capacity.
   CHECK_EQ(32, ObjectHashTable::cast(weakmap->table())->Capacity());
 
   // Fill up weak map to trigger capacity change.
   {
-    v8::HandleScope scope;
-    Handle<Map> map = FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
+    HandleScope scope(isolate);
+    Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
     for (int i = 0; i < 32; i++) {
-      Handle<JSObject> object = FACTORY->NewJSObjectFromMap(map);
-      PutIntoWeakMap(weakmap, object, i);
+      Handle<JSObject> object = factory->NewJSObjectFromMap(map);
+      PutIntoWeakMap(weakmap, object, Handle<Smi>(Smi::FromInt(i), isolate));
     }
   }
 
@@ -144,7 +167,7 @@
   CHECK_EQ(32, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
   CHECK_EQ(
       0, ObjectHashTable::cast(weakmap->table())->NumberOfDeletedElements());
-  HEAP->CollectAllGarbage(false);
+  heap->CollectAllGarbage(false);
   CHECK_EQ(0, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
   CHECK_EQ(
       32, ObjectHashTable::cast(weakmap->table())->NumberOfDeletedElements());
@@ -152,3 +175,100 @@
   // Check shrunk capacity.
   CHECK_EQ(32, ObjectHashTable::cast(weakmap->table())->Capacity());
 }
+
+
+// Test that weak map values on an evacuation candidate which are not reachable
+// by other paths are correctly recorded in the slots buffer.
+TEST(Regress2060a) {
+  if (i::FLAG_never_compact) return;
+  FLAG_always_compact = true;
+  LocalContext context;
+  Isolate* isolate = GetIsolateFrom(&context);
+  Factory* factory = isolate->factory();
+  Heap* heap = isolate->heap();
+  HandleScope scope(isolate);
+  Handle<JSFunction> function = factory->NewFunction(
+      factory->function_string());
+  Handle<JSObject> key = factory->NewJSObject(function);
+  Handle<JSWeakMap> weakmap = AllocateJSWeakMap(isolate);
+
+  // Start second old-space page so that values land on evacuation candidate.
+  Page* first_page = heap->old_pointer_space()->anchor()->next_page();
+  factory->NewFixedArray(900 * KB / kPointerSize, TENURED);
+
+  // Fill up weak map with values on an evacuation candidate.
+  {
+    HandleScope scope(isolate);
+    for (int i = 0; i < 32; i++) {
+      Handle<JSObject> object = factory->NewJSObject(function, TENURED);
+      CHECK(!heap->InNewSpace(object->address()));
+      CHECK(!first_page->Contains(object->address()));
+      PutIntoWeakMap(weakmap, key, object);
+    }
+  }
+
+  // Force compacting garbage collection.
+  CHECK(FLAG_always_compact);
+  heap->CollectAllGarbage(Heap::kNoGCFlags);
+}
+
+
+// Test that weak map keys on an evacuation candidate which are reachable by
+// other strong paths are correctly recorded in the slots buffer.
+TEST(Regress2060b) {
+  if (i::FLAG_never_compact) return;
+  FLAG_always_compact = true;
+#ifdef VERIFY_HEAP
+  FLAG_verify_heap = true;
+#endif
+
+  LocalContext context;
+  Isolate* isolate = GetIsolateFrom(&context);
+  Factory* factory = isolate->factory();
+  Heap* heap = isolate->heap();
+  HandleScope scope(isolate);
+  Handle<JSFunction> function = factory->NewFunction(
+      factory->function_string());
+
+  // Start second old-space page so that keys land on evacuation candidate.
+  Page* first_page = heap->old_pointer_space()->anchor()->next_page();
+  factory->NewFixedArray(900 * KB / kPointerSize, TENURED);
+
+  // Fill up weak map with keys on an evacuation candidate.
+  Handle<JSObject> keys[32];
+  for (int i = 0; i < 32; i++) {
+    keys[i] = factory->NewJSObject(function, TENURED);
+    CHECK(!heap->InNewSpace(keys[i]->address()));
+    CHECK(!first_page->Contains(keys[i]->address()));
+  }
+  Handle<JSWeakMap> weakmap = AllocateJSWeakMap(isolate);
+  for (int i = 0; i < 32; i++) {
+    PutIntoWeakMap(weakmap,
+                   keys[i],
+                   Handle<Smi>(Smi::FromInt(i), isolate));
+  }
+
+  // Force compacting garbage collection. The subsequent collections are used
+  // to verify that key references were actually updated.
+  CHECK(FLAG_always_compact);
+  heap->CollectAllGarbage(Heap::kNoGCFlags);
+  heap->CollectAllGarbage(Heap::kNoGCFlags);
+  heap->CollectAllGarbage(Heap::kNoGCFlags);
+}
+
+
+TEST(Regress399527) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+  Isolate* isolate = CcTest::i_isolate();
+  Heap* heap = isolate->heap();
+  {
+    HandleScope scope(isolate);
+    AllocateJSWeakMap(isolate);
+    SimulateIncrementalMarking(heap);
+  }
+  // The weak map is marked black here but leaving the handle scope will make
+  // the object unreachable. Aborting incremental marking will clear all the
+  // marking bits which makes the weak map garbage.
+  heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
+}
