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

Unified Diff: src/json-stringifier.h

Issue 12690017: Unify code for fast and slow path of JSON.stringify. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 9 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 | « src/heap.h ('k') | src/runtime.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/json-stringifier.h
diff --git a/src/json-stringifier.h b/src/json-stringifier.h
index ad9ef3ddb71e86b17a9aa39caacecf94ebcaad81..418d4794595367f088e09cbb519d65209ff7bd96 100644
--- a/src/json-stringifier.h
+++ b/src/json-stringifier.h
@@ -41,6 +41,9 @@ class BasicJsonStringifier BASE_EMBEDDED {
MaybeObject* Stringify(Handle<Object> object);
+ INLINE(static MaybeObject* StringifyString(Isolate* isolate,
+ Handle<String> object));
+
private:
static const int kInitialPartLength = 32;
static const int kMaxPartLength = 16 * 1024;
@@ -84,6 +87,11 @@ class BasicJsonStringifier BASE_EMBEDDED {
bool deferred_comma,
bool deferred_key);
+ template <typename StringType>
+ INLINE(static MaybeObject* StringifyString_(Isolate* isolate,
+ Handle<String> string,
+ Handle<String> result));
+
// Entry point to serialize the object.
INLINE(Result SerializeObject(Handle<Object> obj)) {
return Serialize_<false>(obj, false, factory_->empty_string());
@@ -135,18 +143,18 @@ class BasicJsonStringifier BASE_EMBEDDED {
void SerializeString(Handle<String> object);
template <typename SrcChar, typename DestChar>
- INLINE(void SerializeStringUnchecked_(const SrcChar* src,
- DestChar* dest,
- int length));
+ INLINE(static int SerializeStringUnchecked_(const SrcChar* src,
+ DestChar* dest,
+ int length));
template <bool is_ascii, typename Char>
INLINE(void SerializeString_(Handle<String> string));
template <typename Char>
- INLINE(bool DoNotEscape(Char c));
+ INLINE(static bool DoNotEscape(Char c));
template <typename Char>
- INLINE(Vector<const Char> GetCharVector(Handle<String> string));
+ INLINE(static Vector<const Char> GetCharVector(Handle<String> string));
Result StackPush(Handle<Object> object);
void StackPop();
@@ -244,15 +252,15 @@ const char* const BasicJsonStringifier::JsonEscapeTable =
"\370\0 \371\0 \372\0 \373\0 "
"\374\0 \375\0 \376\0 \377\0 ";
+
BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate)
: isolate_(isolate), current_index_(0), is_ascii_(true) {
factory_ = isolate_->factory();
accumulator_store_ = Handle<JSValue>::cast(
factory_->ToObject(factory_->empty_string()));
part_length_ = kInitialPartLength;
- current_part_ = factory_->NewRawOneByteString(kInitialPartLength);
- tojson_string_ =
- factory_->InternalizeOneByteString(STATIC_ASCII_VECTOR("toJSON"));
+ current_part_ = factory_->NewRawOneByteString(part_length_);
+ tojson_string_ = factory_->toJSON_string();
stack_ = factory_->NewJSArray(8);
}
@@ -275,6 +283,57 @@ MaybeObject* BasicJsonStringifier::Stringify(Handle<Object> object) {
}
+MaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate,
+ Handle<String> object) {
+ static const int kJsonQuoteWorstCaseBlowup = 6;
+ static const int kSpaceForQuotes = 2;
+ int worst_case_length =
+ object->length() * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes;
+
+ if (worst_case_length > 32 * KB) { // Slow path if too large.
+ BasicJsonStringifier stringifier(isolate);
+ return stringifier.Stringify(object);
+ }
+
+ object = FlattenGetString(object);
+ if (object->IsSeqOneByteString()) {
+ return StringifyString_<SeqOneByteString>(
+ isolate,
+ object,
+ isolate->factory()->NewRawOneByteString(worst_case_length));
+ } else {
+ return StringifyString_<SeqTwoByteString>(
+ isolate,
+ object,
+ isolate->factory()->NewRawTwoByteString(worst_case_length));
+ }
+}
+
+
+template <typename StringType>
+MaybeObject* BasicJsonStringifier::StringifyString_(Isolate* isolate,
+ Handle<String> string,
+ Handle<String> result) {
+ AssertNoAllocation no_allocation;
+ int final_size = 0;
+ StringType* dest = StringType::cast(*result);
+ dest->Set(final_size++, '\"');
+ final_size += SerializeStringUnchecked_(StringType::cast(*string)->GetChars(),
+ dest->GetChars() + 1,
+ string->length());
+ dest->Set(final_size++, '\"');
+ if (isolate->heap()->InNewSpace(*result)) {
+ // In new space, simply lower the allocation top to fit the actual size.
+ isolate->heap()->new_space()->ShrinkStringAtAllocationBoundary<StringType>(
+ *result, final_size);
+ return *result;
+ } else {
+ // Not in new space, need to fill the wasted space with filler objects.
+ return SeqString::cast(*result)->Truncate(final_size);
+ }
+}
+
+
template <bool is_ascii, typename Char>
void BasicJsonStringifier::Append_(Char c) {
if (is_ascii) {
@@ -667,10 +726,9 @@ void BasicJsonStringifier::ChangeEncoding() {
template <typename SrcChar, typename DestChar>
-void BasicJsonStringifier::SerializeStringUnchecked_(const SrcChar* src,
- DestChar* dest,
- int length) {
- dest += current_index_;
+int BasicJsonStringifier::SerializeStringUnchecked_(const SrcChar* src,
+ DestChar* dest,
+ int length) {
DestChar* dest_start = dest;
// Assert that uc16 character is not truncated down to 8 bit.
@@ -688,7 +746,7 @@ void BasicJsonStringifier::SerializeStringUnchecked_(const SrcChar* src,
}
}
- current_index_ += static_cast<int>(dest - dest_start);
+ return static_cast<int>(dest - dest_start);
}
@@ -705,14 +763,14 @@ void BasicJsonStringifier::SerializeString_(Handle<String> string) {
AssertNoAllocation no_allocation;
Vector<const Char> vector = GetCharVector<Char>(string);
if (is_ascii) {
- SerializeStringUnchecked_(
+ current_index_ += SerializeStringUnchecked_(
vector.start(),
- SeqOneByteString::cast(*current_part_)->GetChars(),
+ SeqOneByteString::cast(*current_part_)->GetChars() + current_index_,
length);
} else {
- SerializeStringUnchecked_(
+ current_index_ += SerializeStringUnchecked_(
vector.start(),
- SeqTwoByteString::cast(*current_part_)->GetChars(),
+ SeqTwoByteString::cast(*current_part_)->GetChars() + current_index_,
length);
}
} else {
« no previous file with comments | « src/heap.h ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698