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
This commit is contained in:
verwaest@chromium.org 2012-10-19 15:37:28 +00:00
parent 4f40326fae
commit d33cda9338

View 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_);
}