Reviewers: arv, jochen,

Description:
Flatten the Arrays returned and consumed by the v8::Map API

This will significantly simplify the serialization code, as well
as speeding it up (by triggering only a single allocation instead of O(size)
allocations).

BUG=chromium:478263

Please review this at https://codereview.chromium.org/1157843006/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+21, -28 lines):
  M include/v8.h
  M src/api.cc
  M src/collection.js
  M test/cctest/test-api.cc


Index: include/v8.h
diff --git a/include/v8.h b/include/v8.h
index 3bd3dfbbd83cdf82c195aff85e4ae9c04b13861f..3c399a47eb5219e035c01243251d8a422f31f0f4 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -2977,8 +2977,8 @@ class V8_EXPORT Map : public Object {
   size_t Size() const;

   /**
-   * Returns an array of [key, value] arrays representing the contents
-   * of this Map.
+ * Returns an array of length Size() * 2, where index N is the Nth key and
+   * index N + 1 is the Nth value.
    */
   Local<Array> AsArray() const;

@@ -2988,8 +2988,8 @@ class V8_EXPORT Map : public Object {
   static Local<Map> New(Isolate* isolate);

   /**
- * Creates a new Map containing the elements of array, which must be comprised
-   * of [key, value] arrays.
+ * Creates a new Map containing the elements of array, which must be formatted
+   * in the same manner as the array returned from AsArray().
    * Guaranteed to be side-effect free if the array contains no holes.
    */
static V8_WARN_UNUSED_RESULT MaybeLocal<Map> FromArray(Local<Context> context,
Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index 6ecdb4d4a207a2bcc6308d99773d363252456073..985daacef4d2175280681a3174cf9a5f2332b03b 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -6272,17 +6272,13 @@ Local<Array> Map::AsArray() const {
   LOG_API(isolate, "Map::AsArray");
   ENTER_V8(isolate);
i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(obj->table()));
-  int length = table->NumberOfElements();
+  int size = table->NumberOfElements();
+  int length = size * 2;
   i::Handle<i::FixedArray> result = factory->NewFixedArray(length);
-  for (int i = 0; i < length; ++i) {
+  for (int i = 0; i < size; ++i) {
     if (table->KeyAt(i)->IsTheHole()) continue;
-    i::HandleScope handle_scope(isolate);
-    i::Handle<i::FixedArray> entry = factory->NewFixedArray(2);
-    entry->set(0, table->KeyAt(i));
-    entry->set(1, table->ValueAt(i));
-    i::Handle<i::JSArray> entry_array =
-        factory->NewJSArrayWithElements(entry, i::FAST_ELEMENTS, 2);
-    result->set(i, *entry_array);
+    result->set(i * 2, table->KeyAt(i));
+    result->set(i * 2 + 1, table->ValueAt(i));
   }
   i::Handle<i::JSArray> result_array =
       factory->NewJSArrayWithElements(result, i::FAST_ELEMENTS, length);
Index: src/collection.js
diff --git a/src/collection.js b/src/collection.js
index 1c6b475df6cf4761f4d25738150b1d3bfa3c44d5..9dd5bfb7f923cb4d2169af4f8cb96f1afff43d07 100644
--- a/src/collection.js
+++ b/src/collection.js
@@ -485,9 +485,10 @@ $getExistingHash = GetExistingHash;
 $mapFromArray = function(array) {
   var map = new GlobalMap;
   var length = array.length;
-  for (var i = 0; i < length; ++i) {
-    var entry = array[i];
-    %_CallFunction(map, entry[0], entry[1], MapSet);
+  for (var i = 0; i + 1 < length; i += 2) {
+    var key = array[i];
+    var value = array[i + 1];
+    %_CallFunction(map, key, value, MapSet);
   }
   return map;
 };
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 93ed66b2180fa6ab8410a2de300ee36aca9e27cb..f92e3f5dbe2f09d7e108561c3caf86f2ef381c3e 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -21384,18 +21384,14 @@ TEST(Map) {
   map = v8::Local<v8::Map>::Cast(val);
   CHECK_EQ(2, map->Size());

-  v8::Local<v8::Array> entries = map->AsArray();
-  CHECK_EQ(2, entries->Length());
-  v8::Local<v8::Array> entry = entries->Get(0).As<v8::Array>();
-  CHECK_EQ(2, entry->Length());
-  CHECK_EQ(1, entry->Get(0).As<v8::Int32>()->Value());
-  CHECK_EQ(2, entry->Get(1).As<v8::Int32>()->Value());
-  entry = entries->Get(1).As<v8::Array>();
-  CHECK_EQ(2, entry->Length());
-  CHECK_EQ(3, entry->Get(0).As<v8::Int32>()->Value());
-  CHECK_EQ(4, entry->Get(1).As<v8::Int32>()->Value());
-
-  map = v8::Map::FromArray(env.local(), entries).ToLocalChecked();
+  v8::Local<v8::Array> contents = map->AsArray();
+  CHECK_EQ(4, contents->Length());
+  CHECK_EQ(1, contents->Get(0).As<v8::Int32>()->Value());
+  CHECK_EQ(2, contents->Get(1).As<v8::Int32>()->Value());
+  CHECK_EQ(3, contents->Get(2).As<v8::Int32>()->Value());
+  CHECK_EQ(4, contents->Get(3).As<v8::Int32>()->Value());
+
+  map = v8::Map::FromArray(env.local(), contents).ToLocalChecked();
   CHECK_EQ(2, map->Size());
 }



--
--
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