Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(723)

Unified Diff: src/json-parser.cc

Issue 2887653002: [json] Specialize parsed arrays to most specific kind (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | test/cctest/test-api.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/json-parser.cc
diff --git a/src/json-parser.cc b/src/json-parser.cc
index ec1329a1c74c53d9c5f293f53b78d9d27f8b5be5..93d305df7ade2c9486b060148c23b7583c519457 100644
--- a/src/json-parser.cc
+++ b/src/json-parser.cc
@@ -488,6 +488,46 @@ void JsonParser<seq_one_byte>::CommitStateToJsonObject(
}
}
+class ElementKindLattice {
+ private:
+ enum {
+ SMI_ELEMENTS,
+ NUMBER_ELEMENTS,
+ OBJECT_ELEMENTS,
+ };
+
+ public:
+ ElementKindLattice() : value_(SMI_ELEMENTS) {}
+
+ void Update(Handle<Object> o) {
+ if (o->IsSmi()) {
+ return;
+ } else if (o->IsHeapNumber()) {
+ if (value_ < NUMBER_ELEMENTS) value_ = NUMBER_ELEMENTS;
+ } else {
+ DCHECK(!o->IsNumber());
+ value_ = OBJECT_ELEMENTS;
+ }
+ }
+
+ ElementsKind GetElementsKind() const {
+ switch (value_) {
+ case SMI_ELEMENTS:
+ return FAST_SMI_ELEMENTS;
+ case NUMBER_ELEMENTS:
+ return FAST_DOUBLE_ELEMENTS;
+ case OBJECT_ELEMENTS:
+ return FAST_ELEMENTS;
+ default:
+ UNREACHABLE();
+ return FAST_ELEMENTS;
+ }
+ }
+
+ private:
+ int value_;
+};
+
// Parse a JSON array. Position must be right at '['.
template <bool seq_one_byte>
Handle<Object> JsonParser<seq_one_byte>::ParseJsonArray() {
@@ -495,26 +535,49 @@ Handle<Object> JsonParser<seq_one_byte>::ParseJsonArray() {
ZoneList<Handle<Object> > elements(4, zone());
DCHECK_EQ(c0_, '[');
+ ElementKindLattice lattice;
+
AdvanceSkipWhitespace();
if (c0_ != ']') {
do {
Handle<Object> element = ParseJsonValue();
if (element.is_null()) return ReportUnexpectedCharacter();
elements.Add(element, zone());
+ lattice.Update(element);
} while (MatchSkipWhiteSpace(','));
if (c0_ != ']') {
return ReportUnexpectedCharacter();
}
}
AdvanceSkipWhitespace();
+
// Allocate a fixed array with all the elements.
- Handle<FixedArray> fast_elements =
- factory()->NewFixedArray(elements.length(), pretenure_);
- for (int i = 0, n = elements.length(); i < n; i++) {
- fast_elements->set(i, *elements[i]);
+
+ Handle<Object> json_array;
+ const ElementsKind kind = lattice.GetElementsKind();
+
+ switch (kind) {
+ case FAST_ELEMENTS:
+ case FAST_SMI_ELEMENTS: {
+ Handle<FixedArray> elems =
+ factory()->NewFixedArray(elements.length(), pretenure_);
+ for (int i = 0; i < elements.length(); i++) elems->set(i, *elements[i]);
+ json_array = factory()->NewJSArrayWithElements(elems, kind, pretenure_);
+ break;
+ }
+ case FAST_DOUBLE_ELEMENTS: {
+ Handle<FixedDoubleArray> elems = Handle<FixedDoubleArray>::cast(
+ factory()->NewFixedDoubleArray(elements.length(), pretenure_));
+ for (int i = 0; i < elements.length(); i++) {
+ elems->set(i, elements[i]->Number());
+ }
+ json_array = factory()->NewJSArrayWithElements(elems, kind, pretenure_);
+ break;
+ }
+ default:
+ UNREACHABLE();
}
- Handle<Object> json_array = factory()->NewJSArrayWithElements(
- fast_elements, FAST_ELEMENTS, pretenure_);
+
return scope.CloseAndEscape(json_array);
}
« no previous file with comments | « no previous file | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698