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.