Micro-optimizing the json parser
authorverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 19 Oct 2012 15:37:28 +0000 (15:37 +0000)
committerverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 19 Oct 2012 15:37:28 +0000 (15:37 +0000)
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

index 245dfbf..40116fa 100644 (file)
@@ -149,6 +149,8 @@ class JsonParser BASE_EMBEDDED {
   }
 
   inline Isolate* isolate() { return isolate_; }
+  inline Factory* factory() { return factory_; }
+  inline Handle<JSFunction> 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<SeqAsciiString> seq_source_;
 
   Isolate* isolate_;
+  Factory* factory_;
+  Handle<JSFunction> object_constructor_;
   uc32 c0_;
   int position_;
   Zone* zone_;
@@ -169,6 +173,9 @@ template <bool seq_ascii>
 Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source,
                                                 Zone* zone) {
   isolate_ = source->map()->GetHeap()->isolate();
+  factory_ = isolate_->factory();
+  object_constructor_ =
+      Handle<JSFunction>(isolate()->native_context()->object_function());
   zone_ = zone;
   FlattenString(source);
   source_ = source;
@@ -188,7 +195,7 @@ Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source,
     // Parse failed. Current character is the unexpected token.
 
     const char* message;
-    Factory* factory = isolate()->factory();
+    Factory* factory = this->factory();
     Handle<JSArray> array;
 
     switch (c0_) {
@@ -237,52 +244,35 @@ Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source,
 // Parse any JSON value.
 template <bool seq_ascii>
 Handle<Object> JsonParser<seq_ascii>::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<Object> JsonParser<seq_ascii>::ParseJsonValue() {
 template <bool seq_ascii>
 Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
   Handle<Object> prototype;
-  Handle<JSFunction> object_constructor(
-      isolate()->native_context()->object_function());
   Handle<JSObject> json_object =
-      isolate()->factory()->NewJSObject(object_constructor);
+      factory()->NewJSObject(object_constructor());
   ASSERT_EQ(c0_, '{');
 
   AdvanceSkipWhitespace();
@@ -377,11 +365,11 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonArray() {
   AdvanceSkipWhitespace();
   // Allocate a fixed array with all the elements.
   Handle<FixedArray> 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<Object> JsonParser<seq_ascii>::ParseJsonNumber() {
     buffer.Dispose();
   }
   SkipWhitespace();
-  return isolate()->factory()->NewNumber(number);
+  return factory()->NewNumber(number);
 }
 
 
@@ -489,8 +477,7 @@ Handle<String> JsonParser<seq_ascii>::SlowScanJsonString(
   int count = end - start;
   int max_length = count + source_length_ - position_;
   int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count));
-  Handle<StringType> seq_str = NewRawString<StringType>(isolate()->factory(),
-                                                        length);
+  Handle<StringType> seq_str = NewRawString<StringType>(factory(), length);
   // Copy prefix into seq_str.
   SinkChar* dest = seq_str->GetChars();
   String::WriteToFlat(*prefix, dest, start, end);
@@ -668,11 +655,11 @@ Handle<String> JsonParser<seq_ascii>::ScanJsonString() {
   int length = position_ - beg_pos;
   Handle<String> 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_);
   }