Index: src/json-stringifier.h |
diff --git a/src/json-stringifier.h b/src/json-stringifier.h |
index 0dd54c403cda9ac8d60ed01f7298972d1fa916e7..a9fc2e1c51577568e105dfad4c3be3062cb25bad 100644 |
--- a/src/json-stringifier.h |
+++ b/src/json-stringifier.h |
@@ -82,7 +82,8 @@ class BasicJsonStringifier BASE_EMBEDDED { |
INLINE(Result SerializeJSArray(Handle<JSArray> object)); |
INLINE(Result SerializeJSObject(Handle<JSObject> object)); |
- Result SerializeJSArraySlow(Handle<JSArray> object, uint32_t length); |
+ Result SerializeJSArraySlow(Handle<JSArray> object, uint32_t start, |
+ uint32_t length); |
void SerializeString(Handle<String> object); |
@@ -435,8 +436,65 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray( |
uint32_t length = 0; |
CHECK(object->length()->ToArrayLength(&length)); |
builder_.AppendCharacter('['); |
- Result result = SerializeJSArraySlow(object, length); |
- if (result != SUCCESS) return result; |
+ switch (object->GetElementsKind()) { |
+ case FAST_SMI_ELEMENTS: { |
+ DisallowJavascriptExecution no_js(isolate_); |
+ Handle<FixedArray> elements(FixedArray::cast(object->elements()), |
+ isolate_); |
+ for (uint32_t i = 0; i < length; i++) { |
+ if (i > 0) builder_.AppendCharacter(','); |
+ SerializeSmi(Smi::cast(elements->get(i))); |
+ } |
+ break; |
+ } |
+ case FAST_DOUBLE_ELEMENTS: { |
+ DisallowJavascriptExecution no_js(isolate_); |
+ // Empty array is FixedArray but not FixedDoubleArray. |
+ if (length == 0) break; |
+ Handle<FixedDoubleArray> elements( |
+ FixedDoubleArray::cast(object->elements()), isolate_); |
+ for (uint32_t i = 0; i < length; i++) { |
+ if (i > 0) builder_.AppendCharacter(','); |
+ SerializeDouble(elements->get_scalar(i)); |
+ } |
+ break; |
+ } |
+ case FAST_ELEMENTS: { |
+ Handle<FixedArray> elements(FixedArray::cast(object->elements()), |
+ isolate_); |
+ Result result; |
+ if (elements->length() < length) { |
+ result = SerializeJSArraySlow(object, 0, length); |
+ if (result != SUCCESS) return result; |
+ } else { |
+ JavascriptExecutionObserver observer(isolate_); |
+ for (uint32_t i = 0; i < length; i++) { |
+ if (observer.observed()) { |
+ result = SerializeJSArraySlow(object, i, length); |
+ if (result != SUCCESS) return result; |
+ break; |
+ } |
+ if (i > 0) builder_.AppendCharacter(','); |
+ result = SerializeElement( |
+ isolate_, Handle<Object>(elements->get(i), isolate_), i); |
+ if (result == SUCCESS) continue; |
+ if (result == UNCHANGED) { |
+ builder_.AppendCString("null"); |
+ } else { |
+ return result; |
+ } |
+ } |
+ } |
+ break; |
+ } |
+ // The FAST_HOLEY_* cases could be handled in a faster way. They resemble |
+ // the non-holey cases except that a lookup is necessary for holes. |
+ default: { |
+ Result result = SerializeJSArraySlow(object, 0, length); |
+ if (result != SUCCESS) return result; |
+ break; |
+ } |
+ } |
builder_.AppendCharacter(']'); |
StackPop(); |
return SUCCESS; |
@@ -444,8 +502,8 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray( |
BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArraySlow( |
- Handle<JSArray> object, uint32_t length) { |
- for (uint32_t i = 0; i < length; i++) { |
+ Handle<JSArray> object, uint32_t start, uint32_t length) { |
+ for (uint32_t i = start; i < length; i++) { |
if (i > 0) builder_.AppendCharacter(','); |
Handle<Object> element; |
ASSIGN_RETURN_ON_EXCEPTION_VALUE( |