From d33cda933827f255a7fb3224397c5fe1cf277bdc Mon Sep 17 00:00:00 2001 From: "verwaest@chromium.org" Date: Fri, 19 Oct 2012 15:37:28 +0000 Subject: [PATCH] Micro-optimizing the json parser Review URL: https://chromiumcodereview.appspot.com/11237002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12779 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/json-parser.h | 99 ++++++++++++++++++++--------------------------- 1 file changed, 43 insertions(+), 56 deletions(-) diff --git a/src/json-parser.h b/src/json-parser.h index 245dfbfecb..40116fa59a 100644 --- a/src/json-parser.h +++ b/src/json-parser.h @@ -149,6 +149,8 @@ class JsonParser BASE_EMBEDDED { } inline Isolate* isolate() { return isolate_; } + inline Factory* factory() { return factory_; } + inline Handle object_constructor() { return object_constructor_; } inline Zone* zone() const { return zone_; } static const int kInitialSpecialStringLength = 1024; @@ -160,6 +162,8 @@ class JsonParser BASE_EMBEDDED { Handle seq_source_; Isolate* isolate_; + Factory* factory_; + Handle object_constructor_; uc32 c0_; int position_; Zone* zone_; @@ -169,6 +173,9 @@ template Handle JsonParser::ParseJson(Handle source, Zone* zone) { isolate_ = source->map()->GetHeap()->isolate(); + factory_ = isolate_->factory(); + object_constructor_ = + Handle(isolate()->native_context()->object_function()); zone_ = zone; FlattenString(source); source_ = source; @@ -188,7 +195,7 @@ Handle JsonParser::ParseJson(Handle source, // Parse failed. Current character is the unexpected token. const char* message; - Factory* factory = isolate()->factory(); + Factory* factory = this->factory(); Handle array; switch (c0_) { @@ -237,52 +244,35 @@ Handle JsonParser::ParseJson(Handle source, // Parse any JSON value. template Handle JsonParser::ParseJsonValue() { - switch (c0_) { - case '"': - return ParseJsonString(); - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - return ParseJsonNumber(); - case 'f': - if (AdvanceGetChar() == 'a' && AdvanceGetChar() == 'l' && - AdvanceGetChar() == 's' && AdvanceGetChar() == 'e') { - AdvanceSkipWhitespace(); - return isolate()->factory()->false_value(); - } else { - return ReportUnexpectedCharacter(); - } - case 't': - if (AdvanceGetChar() == 'r' && AdvanceGetChar() == 'u' && - AdvanceGetChar() == 'e') { - AdvanceSkipWhitespace(); - return isolate()->factory()->true_value(); - } else { - return ReportUnexpectedCharacter(); - } - case 'n': - if (AdvanceGetChar() == 'u' && AdvanceGetChar() == 'l' && - AdvanceGetChar() == 'l') { - AdvanceSkipWhitespace(); - return isolate()->factory()->null_value(); - } else { - return ReportUnexpectedCharacter(); - } - case '{': - return ParseJsonObject(); - case '[': - return ParseJsonArray(); - default: - return ReportUnexpectedCharacter(); + if (c0_ == '"') return ParseJsonString(); + if ((c0_ >= '0' && c0_ <= '9') || c0_ == '-') return ParseJsonNumber(); + if (c0_ == '{') return ParseJsonObject(); + if (c0_ == '[') return ParseJsonArray(); + if (c0_ == 'f') { + if (AdvanceGetChar() == 'a' && AdvanceGetChar() == 'l' && + AdvanceGetChar() == 's' && AdvanceGetChar() == 'e') { + AdvanceSkipWhitespace(); + return factory()->false_value(); + } + return ReportUnexpectedCharacter(); } + if (c0_ == 't') { + if (AdvanceGetChar() == 'r' && AdvanceGetChar() == 'u' && + AdvanceGetChar() == 'e') { + AdvanceSkipWhitespace(); + return factory()->true_value(); + } + return ReportUnexpectedCharacter(); + } + if (c0_ == 'n') { + if (AdvanceGetChar() == 'u' && AdvanceGetChar() == 'l' && + AdvanceGetChar() == 'l') { + AdvanceSkipWhitespace(); + return factory()->null_value(); + } + return ReportUnexpectedCharacter(); + } + return ReportUnexpectedCharacter(); } @@ -290,10 +280,8 @@ Handle JsonParser::ParseJsonValue() { template Handle JsonParser::ParseJsonObject() { Handle prototype; - Handle object_constructor( - isolate()->native_context()->object_function()); Handle json_object = - isolate()->factory()->NewJSObject(object_constructor); + factory()->NewJSObject(object_constructor()); ASSERT_EQ(c0_, '{'); AdvanceSkipWhitespace(); @@ -377,11 +365,11 @@ Handle JsonParser::ParseJsonArray() { AdvanceSkipWhitespace(); // Allocate a fixed array with all the elements. Handle fast_elements = - isolate()->factory()->NewFixedArray(elements.length()); + factory()->NewFixedArray(elements.length()); for (int i = 0, n = elements.length(); i < n; i++) { fast_elements->set(i, *elements[i]); } - return isolate()->factory()->NewJSArrayWithElements(fast_elements); + return factory()->NewJSArrayWithElements(fast_elements); } @@ -448,7 +436,7 @@ Handle JsonParser::ParseJsonNumber() { buffer.Dispose(); } SkipWhitespace(); - return isolate()->factory()->NewNumber(number); + return factory()->NewNumber(number); } @@ -489,8 +477,7 @@ Handle JsonParser::SlowScanJsonString( int count = end - start; int max_length = count + source_length_ - position_; int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count)); - Handle seq_str = NewRawString(isolate()->factory(), - length); + Handle seq_str = NewRawString(factory(), length); // Copy prefix into seq_str. SinkChar* dest = seq_str->GetChars(); String::WriteToFlat(*prefix, dest, start, end); @@ -668,11 +655,11 @@ Handle JsonParser::ScanJsonString() { int length = position_ - beg_pos; Handle result; if (seq_ascii && is_symbol) { - result = isolate()->factory()->LookupAsciiSymbol(seq_source_, + result = factory()->LookupAsciiSymbol(seq_source_, beg_pos, length); } else { - result = isolate()->factory()->NewRawAsciiString(length); + result = factory()->NewRawAsciiString(length); char* dest = SeqAsciiString::cast(*result)->GetChars(); String::WriteToFlat(*source_, dest, beg_pos, position_); }