| Index: src/value-serializer.cc
|
| diff --git a/src/value-serializer.cc b/src/value-serializer.cc
|
| index 56d8fa5d059602ed39496a138e237b709cfd602a..a3e031f7ca587042cc3390e8dc990d584a83fec1 100644
|
| --- a/src/value-serializer.cc
|
| +++ b/src/value-serializer.cc
|
| @@ -459,7 +459,46 @@ Maybe<bool> ValueSerializer::WriteJSArray(Handle<JSArray> array) {
|
| // format changes.
|
| WriteTag(SerializationTag::kBeginDenseJSArray);
|
| WriteVarint<uint32_t>(length);
|
| - for (uint32_t i = 0; i < length; i++) {
|
| + uint32_t i = 0;
|
| +
|
| + // Fast paths. Note that FAST_ELEMENTS in particular can bail due to the
|
| + // structure of the elements changing.
|
| + switch (array->GetElementsKind()) {
|
| + case FAST_SMI_ELEMENTS: {
|
| + Handle<FixedArray> elements(FixedArray::cast(array->elements()),
|
| + isolate_);
|
| + for (; i < length; i++) WriteSmi(Smi::cast(elements->get(i)));
|
| + break;
|
| + }
|
| + case FAST_DOUBLE_ELEMENTS: {
|
| + Handle<FixedDoubleArray> elements(
|
| + FixedDoubleArray::cast(array->elements()), isolate_);
|
| + for (; i < length; i++) {
|
| + WriteTag(SerializationTag::kDouble);
|
| + WriteDouble(elements->get_scalar(i));
|
| + }
|
| + break;
|
| + }
|
| + case FAST_ELEMENTS: {
|
| + Handle<Object> old_length(array->length(), isolate_);
|
| + for (; i < length; i++) {
|
| + if (array->length() != *old_length ||
|
| + array->GetElementsKind() != FAST_ELEMENTS) {
|
| + // Fall back to slow path.
|
| + break;
|
| + }
|
| + Handle<Object> element(FixedArray::cast(array->elements())->get(i),
|
| + isolate_);
|
| + if (!WriteObject(element).FromMaybe(false)) return Nothing<bool>();
|
| + }
|
| + break;
|
| + }
|
| + default:
|
| + break;
|
| + }
|
| +
|
| + // If there are elements remaining, serialize them slowly.
|
| + for (; i < length; i++) {
|
| // Serializing the array's elements can have arbitrary side effects, so we
|
| // cannot rely on still having fast elements, even if it did to begin
|
| // with.
|
| @@ -470,6 +509,7 @@ Maybe<bool> ValueSerializer::WriteJSArray(Handle<JSArray> array) {
|
| return Nothing<bool>();
|
| }
|
| }
|
| +
|
| KeyAccumulator accumulator(isolate_, KeyCollectionMode::kOwnOnly,
|
| ENUMERABLE_STRINGS);
|
| if (!accumulator.CollectOwnPropertyNames(array, array).FromMaybe(false)) {
|
|
|