Revision: 22452
Author:   [email protected]
Date:     Thu Jul 17 15:07:59 2014 UTC
Log:      Expose the content of Maps and WeakMaps through MapMirror.

BUG=v8:3291
LOG=N
[email protected], [email protected]

Review URL: https://codereview.chromium.org/398513005

Patch from Alexandra Mikhaylova <[email protected]>.
http://code.google.com/p/v8/source/detail?r=22452

Added:
 /branches/bleeding_edge/test/mjsunit/harmony/mirror-collections.js
 /branches/bleeding_edge/test/mjsunit/runtime-gen/getweakmapentries.js
Modified:
 /branches/bleeding_edge/src/mirror-debugger.js
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/runtime.h
 /branches/bleeding_edge/tools/generate-runtime-tests.py

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/harmony/mirror-collections.js Thu Jul 17 15:07:59 2014 UTC
@@ -0,0 +1,95 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --expose-gc --harmony-collections
+
+function testMapMirror(mirror) {
+  // Create JSON representation.
+  var serializer = debug.MakeMirrorSerializer();
+  var json = JSON.stringify(serializer.serializeValue(mirror));
+
+  // Check the mirror hierachy.
+  assertTrue(mirror instanceof debug.Mirror);
+  assertTrue(mirror instanceof debug.ValueMirror);
+  assertTrue(mirror instanceof debug.ObjectMirror);
+  assertTrue(mirror instanceof debug.MapMirror);
+
+  assertTrue(mirror.isMap());
+
+  // Parse JSON representation and check.
+  var fromJSON = eval('(' + json + ')');
+  assertEquals('map', fromJSON.type);
+}
+
+var o1 = new Object();
+var o2 = new Object();
+var o3 = new Object();
+
+// Test the mirror object for Maps
+var map = new Map();
+map.set(o1, 11);
+map.set(o2, 22);
+map.delete(o1);
+var mapMirror = debug.MakeMirror(map);
+testMapMirror(mapMirror);
+var entries = mapMirror.entries();
+assertEquals(1, entries.length);
+assertSame(o2, entries[0].key);
+assertEquals(22, entries[0].value);
+map.set(o1, 33);
+map.set(o3, o2);
+map.delete(o2);
+map.set(undefined, 44);
+entries = mapMirror.entries();
+assertEquals(3, entries.length);
+assertSame(o1, entries[0].key);
+assertEquals(33, entries[0].value);
+assertSame(o3, entries[1].key);
+assertSame(o2, entries[1].value);
+assertEquals(undefined, entries[2].key);
+assertEquals(44, entries[2].value);
+
+// Test the mirror object for WeakMaps
+var weakMap = new WeakMap();
+weakMap.set(o1, 11);
+weakMap.set(new Object(), 22);
+weakMap.set(o3, 33);
+var weakMapMirror = debug.MakeMirror(weakMap);
+testMapMirror(weakMapMirror);
+
+function testWeakMapEntries(entries, gcDone) {
+  var found = 0;
+  for (var i = 0; i < entries.length; i++) {
+    if (Object.is(entries[i].key, o1)) {
+      assertEquals(11, entries[i].value);
+      found++;
+      continue;
+    }
+    if (Object.is(entries[i].key, o3)) {
+      assertEquals(33, entries[i].value);
+      found++;
+      continue;
+    }
+    if (!gcDone && entries[i].value == 22)
+      found++;
+  }
+  return found;
+}
+
+function testWeakMapMirrorBeforeGC(mirror) {
+  var entries = mirror.entries();
+  assertEquals(3, entries.length);
+  assertEquals(3, testWeakMapEntries(entries, false));
+}
+
+testWeakMapMirrorBeforeGC(weakMapMirror);
+gc();
+
+function testWeakMapMirrorAfterGC(mirror) {
+  var entries = mirror.entries();
+  assertEquals(2, entries.length);
+  assertEquals(2, testWeakMapEntries(entries, true));
+}
+
+testWeakMapMirrorAfterGC(weakMapMirror);
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/runtime-gen/getweakmapentries.js Thu Jul 17 15:07:59 2014 UTC
@@ -0,0 +1,5 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony
+var _holder = new WeakMap();
+%GetWeakMapEntries(_holder);
=======================================
--- /branches/bleeding_edge/src/mirror-debugger.js Tue Jun 10 09:42:41 2014 UTC +++ /branches/bleeding_edge/src/mirror-debugger.js Thu Jul 17 15:07:59 2014 UTC
@@ -81,6 +81,8 @@
     mirror = new ErrorMirror(value);
   } else if (IS_SCRIPT(value)) {
     mirror = new ScriptMirror(value);
+  } else if (IS_MAP(value) || IS_WEAKMAP(value)) {
+    mirror = new MapMirror(value);
   } else if (ObjectIsPromise(value)) {
     mirror = new PromiseMirror(value);
   } else {
@@ -155,6 +157,7 @@
 var CONTEXT_TYPE = 'context';
 var SCOPE_TYPE = 'scope';
 var PROMISE_TYPE = 'promise';
+var MAP_TYPE = 'map';

 // Maximum length when sending strings through the JSON protocol.
 var kMaxProtocolStringLength = 80;
@@ -210,6 +213,7 @@
 //         - RegExpMirror
 //         - ErrorMirror
 //         - PromiseMirror
+//         - MapMirror
 //     - PropertyMirror
 //     - InternalPropertyMirror
 //     - FrameMirror
@@ -420,6 +424,15 @@
 };


+/**
+ * Check whether the mirror reflects a map.
+ * @returns {boolean} True if the mirror reflects a map
+ */
+Mirror.prototype.isMap = function() {
+  return this instanceof MapMirror;
+};
+
+
 /**
  * Allocate a handle id for this object.
  */
@@ -1253,6 +1266,44 @@
 };


+function MapMirror(value) {
+  %_CallFunction(this, value, MAP_TYPE, ObjectMirror);
+}
+inherits(MapMirror, ObjectMirror);
+
+
+/**
+ * Returns an array of key/value pairs of a map.
+ * This will keep keys alive for WeakMaps.
+ *
+ * @returns {Array.<Object>} Array of key/value pairs of a map.
+ */
+MapMirror.prototype.entries = function() {
+  var result = [];
+
+  if (IS_WEAKMAP(this.value_)) {
+    var entries = %GetWeakMapEntries(this.value_);
+    for (var i = 0; i < entries.length; i += 2) {
+      result.push({
+        key: entries[i],
+        value: entries[i + 1]
+      });
+    }
+    return result;
+  }
+
+  var iter = %_CallFunction(this.value_, builtins.MapEntries);
+  var next;
+  while (!(next = iter.next()).done) {
+    result.push({
+      key: next.value[0],
+      value: next.value[1]
+    });
+  }
+  return result;
+};
+
+
 /**
  * Base mirror object for properties.
  * @param {ObjectMirror} mirror The mirror object having this property
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Thu Jul 17 09:44:37 2014 UTC
+++ /branches/bleeding_edge/src/runtime.cc      Thu Jul 17 15:07:59 2014 UTC
@@ -1704,6 +1704,29 @@
   holder->set_kind(Smi::FromInt(kind));
   return isolate->heap()->undefined_value();
 }
+
+
+RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
+  Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+  Handle<FixedArray> entries =
+      isolate->factory()->NewFixedArray(table->NumberOfElements() * 2);
+  {
+    DisallowHeapAllocation no_gc;
+    int number_of_non_hole_elements = 0;
+    for (int i = 0; i < table->Capacity(); i++) {
+      Handle<Object> key(table->KeyAt(i), isolate);
+      if (table->IsKey(*key)) {
+        entries->set(number_of_non_hole_elements++, *key);
+        entries->set(number_of_non_hole_elements++, table->Lookup(key));
+      }
+    }
+    ASSERT_EQ(table->NumberOfElements() * 2, number_of_non_hole_elements);
+  }
+  return *isolate->factory()->NewJSArrayWithElements(entries);
+}


 RUNTIME_FUNCTION(Runtime_MapIteratorNext) {
=======================================
--- /branches/bleeding_edge/src/runtime.h       Wed Jul 16 12:03:33 2014 UTC
+++ /branches/bleeding_edge/src/runtime.h       Thu Jul 17 15:07:59 2014 UTC
@@ -296,6 +296,8 @@
   F(WeakCollectionDelete, 2, 1)                        \
   F(WeakCollectionSet, 3, 1)                           \
                                                        \
+  F(GetWeakMapEntries, 1, 1)                           \
+                                                       \
   /* Harmony events */                                 \
   F(EnqueueMicrotask, 1, 1)                            \
   F(RunMicrotasks, 0, 1)                               \
=======================================
--- /branches/bleeding_edge/tools/generate-runtime-tests.py Wed Jul 16 14:00:15 2014 UTC +++ /branches/bleeding_edge/tools/generate-runtime-tests.py Thu Jul 17 15:07:59 2014 UTC
@@ -47,11 +47,11 @@
# that the parser doesn't bit-rot. Change the values as needed when you add, # remove or change runtime functions, but make sure we don't lose our ability
 # to parse them!
-EXPECTED_FUNCTION_COUNT = 417
-EXPECTED_FUZZABLE_COUNT = 332
+EXPECTED_FUNCTION_COUNT = 418
+EXPECTED_FUZZABLE_COUNT = 333
 EXPECTED_CCTEST_COUNT = 8
 EXPECTED_UNKNOWN_COUNT = 4
-EXPECTED_BUILTINS_COUNT = 809
+EXPECTED_BUILTINS_COUNT = 810


 # Don't call these at all.

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to