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

Unified Diff: src/json-stringifier.h

Issue 12257005: Improve JSON stringifier's escape check. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: reduce impact on the scanner. Created 7 years, 10 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.cc ('k') | src/parser.cc » ('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 cec98443a5c628cb103c56e27aec2db4e35a4fb6..2433792965771b3948c3406f865c9469c6d2ae41 100644
--- a/src/json-stringifier.h
+++ b/src/json-stringifier.h
@@ -54,14 +54,14 @@ class BasicJsonStringifier BASE_EMBEDDED {
void ShrinkCurrentPart();
- template <bool is_ascii, typename Char>
+ template <bool ascii_mode, typename Char>
INLINE(void Append_(Char c));
- template <bool is_ascii, typename Char>
+ template <bool ascii_mode, typename Char>
INLINE(void Append_(const Char* chars));
INLINE(void Append(uint8_t c)) {
- if (is_ascii_) {
+ if (ascii_mode_) {
Append_<true>(c);
} else {
Append_<false>(c);
@@ -69,7 +69,7 @@ class BasicJsonStringifier BASE_EMBEDDED {
}
INLINE(void AppendAscii(const char* chars)) {
- if (is_ascii_) {
+ if (ascii_mode_) {
Append_<true>(reinterpret_cast<const uint8_t*>(chars));
} else {
Append_<false>(reinterpret_cast<const uint8_t*>(chars));
@@ -130,15 +130,15 @@ class BasicJsonStringifier BASE_EMBEDDED {
void SerializeString(Handle<String> object);
- template <typename SrcChar, typename DestChar>
+ template <bool printable_ascii_only, typename SrcChar, typename DestChar>
INLINE(void SerializeStringUnchecked_(const SrcChar* src,
DestChar* dest,
int length));
- template <bool is_ascii, typename Char>
+ template <bool printable_ascii_only, bool ascii_mode, typename Char>
INLINE(void SerializeString_(Handle<String> string));
- template <typename Char>
+ template <bool printable_ascii_only, typename Char>
INLINE(bool DoNotEscape(Char c));
template <typename Char>
@@ -165,7 +165,7 @@ class BasicJsonStringifier BASE_EMBEDDED {
Handle<JSArray> stack_;
int current_index_;
int part_length_;
- bool is_ascii_;
+ bool ascii_mode_;
static const int kJsonEscapeTableEntrySize = 8;
static const char* const JsonEscapeTable;
@@ -210,7 +210,7 @@ const char* const BasicJsonStringifier::JsonEscapeTable =
BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate)
- : isolate_(isolate), current_index_(0), is_ascii_(true) {
+ : isolate_(isolate), current_index_(0), ascii_mode_(true) {
factory_ = isolate_->factory();
accumulator_store_ = Handle<JSValue>::cast(
factory_->ToObject(factory_->empty_string()));
@@ -240,9 +240,9 @@ MaybeObject* BasicJsonStringifier::Stringify(Handle<Object> object) {
}
-template <bool is_ascii, typename Char>
+template <bool ascii_mode, typename Char>
void BasicJsonStringifier::Append_(Char c) {
- if (is_ascii) {
+ if (ascii_mode) {
SeqOneByteString::cast(*current_part_)->SeqOneByteStringSet(
current_index_++, c);
} else {
@@ -253,9 +253,9 @@ void BasicJsonStringifier::Append_(Char c) {
}
-template <bool is_ascii, typename Char>
+template <bool ascii_mode, typename Char>
void BasicJsonStringifier::Append_(const Char* chars) {
- for ( ; *chars != '\0'; chars++) Append_<is_ascii, Char>(*chars);
+ for ( ; *chars != '\0'; chars++) Append_<ascii_mode, Char>(*chars);
}
@@ -608,7 +608,7 @@ void BasicJsonStringifier::Extend() {
if (part_length_ <= kMaxPartLength / kPartLengthGrowthFactor) {
part_length_ *= kPartLengthGrowthFactor;
}
- if (is_ascii_) {
+ if (ascii_mode_) {
current_part_ = factory_->NewRawOneByteString(part_length_);
} else {
current_part_ = factory_->NewRawTwoByteString(part_length_);
@@ -622,11 +622,11 @@ void BasicJsonStringifier::ChangeEncoding() {
set_accumulator(factory_->NewConsString(accumulator(), current_part_));
current_part_ = factory_->NewRawTwoByteString(part_length_);
current_index_ = 0;
- is_ascii_ = false;
+ ascii_mode_ = false;
}
-template <typename SrcChar, typename DestChar>
+template < bool printable_ascii_only, typename SrcChar, typename DestChar>
void BasicJsonStringifier::SerializeStringUnchecked_(const SrcChar* src,
DestChar* dest,
int length) {
@@ -639,7 +639,7 @@ void BasicJsonStringifier::SerializeStringUnchecked_(const SrcChar* src,
for (int i = 0; i < length; i++) {
SrcChar c = src[i];
- if (DoNotEscape(c)) {
+ if (DoNotEscape<printable_ascii_only>(c)) {
*(dest++) = static_cast<DestChar>(c);
} else {
const char* chars = &JsonEscapeTable[c * kJsonEscapeTableEntrySize];
@@ -651,10 +651,10 @@ void BasicJsonStringifier::SerializeStringUnchecked_(const SrcChar* src,
}
-template <bool is_ascii, typename Char>
+template <bool printable_ascii_only, bool ascii_mode, typename Char>
void BasicJsonStringifier::SerializeString_(Handle<String> string) {
int length = string->length();
- Append_<is_ascii, char>('"');
+ Append_<ascii_mode, char>('"');
// We make a rough estimate to find out if the current string can be
// serialized without allocating a new string part. The worst case length of
// an escaped character is 6. Shifting the remainin string length right by 3
@@ -663,13 +663,13 @@ void BasicJsonStringifier::SerializeString_(Handle<String> string) {
if (((part_length_ - current_index_) >> 3) > length) {
AssertNoAllocation no_allocation;
Vector<const Char> vector = GetCharVector<Char>(string);
- if (is_ascii) {
- SerializeStringUnchecked_(
+ if (ascii_mode) {
+ SerializeStringUnchecked_<printable_ascii_only>(
vector.start(),
SeqOneByteString::cast(*current_part_)->GetChars(),
length);
} else {
- SerializeStringUnchecked_(
+ SerializeStringUnchecked_<printable_ascii_only>(
vector.start(),
SeqTwoByteString::cast(*current_part_)->GetChars(),
length);
@@ -679,10 +679,10 @@ void BasicJsonStringifier::SerializeString_(Handle<String> string) {
Vector<const Char> vector = GetCharVector<Char>(string);
for (int i = 0; i < length; i++) {
Char c = vector[i];
- if (DoNotEscape(c)) {
- Append_<is_ascii, Char>(c);
+ if (DoNotEscape<printable_ascii_only>(c)) {
+ Append_<ascii_mode, Char>(c);
} else {
- Append_<is_ascii, uint8_t>(
+ Append_<ascii_mode, uint8_t>(
reinterpret_cast<const uint8_t*>(
&JsonEscapeTable[c * kJsonEscapeTableEntrySize]));
}
@@ -694,13 +694,15 @@ void BasicJsonStringifier::SerializeString_(Handle<String> string) {
}
}
- Append_<is_ascii, uint8_t>('"');
+ Append_<ascii_mode, uint8_t>('"');
}
-template <typename Char>
+template <bool printable_ascii_only, typename Char>
bool BasicJsonStringifier::DoNotEscape(Char c) {
- return (c >= 0x80) || (c >= '#' && c <= '~' && c != '\\');
+ // "Printable" ASCII is in the range 0x20 .. 0x7e.
+ return (c != '"' && c != '\\') &&
+ (printable_ascii_only || (c != 0x7f && c >= 0x20));
}
@@ -724,18 +726,26 @@ Vector<const uc16> BasicJsonStringifier::GetCharVector(Handle<String> string) {
void BasicJsonStringifier::SerializeString(Handle<String> object) {
FlattenString(object);
String::FlatContent flat = object->GetFlatContent();
- if (is_ascii_) {
+ if (ascii_mode_) {
if (flat.IsAscii()) {
- SerializeString_<true, uint8_t>(object);
+ if (object->map() == isolate_->heap()->printable_ascii_symbol_map()) {
+ SerializeString_<true, true, uint8_t>(object);
+ } else {
+ SerializeString_<false, true, uint8_t>(object);
+ }
} else {
ChangeEncoding();
SerializeString(object);
}
} else {
if (flat.IsAscii()) {
- SerializeString_<false, uint8_t>(object);
+ if (object->map() == isolate_->heap()->printable_ascii_symbol_map()) {
+ SerializeString_<true, false, uint8_t>(object);
+ } else {
+ SerializeString_<false, false, uint8_t>(object);
+ }
} else {
- SerializeString_<false, uc16>(object);
+ SerializeString_<false, false, uc16>(object);
}
}
}
« no previous file with comments | « src/heap.cc ('k') | src/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698