From 006b1a88a0c8cd24ab4048ea296fe7d6922b1458 Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Fri, 22 Mar 2013 08:42:38 +0000 Subject: [PATCH] Fix JSON.stringifier's slow path wrt external strings. R=verwaest@chromium.org BUG= Review URL: https://chromiumcodereview.appspot.com/12825016 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14042 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/json-stringifier.h | 26 ++++++++++++++------------ test/mjsunit/json2.js | 8 +++++++- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/json-stringifier.h b/src/json-stringifier.h index 418d479..60614f4 100644 --- a/src/json-stringifier.h +++ b/src/json-stringifier.h @@ -87,9 +87,9 @@ class BasicJsonStringifier BASE_EMBEDDED { bool deferred_comma, bool deferred_key); - template + template INLINE(static MaybeObject* StringifyString_(Isolate* isolate, - Handle string, + Vector vector, Handle result)); // Entry point to serialize the object. @@ -295,36 +295,38 @@ MaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate, return stringifier.Stringify(object); } - object = FlattenGetString(object); - if (object->IsSeqOneByteString()) { + FlattenString(object); + String::FlatContent flat = object->GetFlatContent(); + if (flat.IsAscii()) { return StringifyString_( isolate, - object, + flat.ToOneByteVector(), isolate->factory()->NewRawOneByteString(worst_case_length)); } else { + ASSERT(flat.IsTwoByte()); return StringifyString_( isolate, - object, + flat.ToUC16Vector(), isolate->factory()->NewRawTwoByteString(worst_case_length)); } } -template +template MaybeObject* BasicJsonStringifier::StringifyString_(Isolate* isolate, - Handle string, + Vector vector, Handle result) { AssertNoAllocation no_allocation; int final_size = 0; - StringType* dest = StringType::cast(*result); + ResultType* dest = ResultType::cast(*result); dest->Set(final_size++, '\"'); - final_size += SerializeStringUnchecked_(StringType::cast(*string)->GetChars(), + final_size += SerializeStringUnchecked_(vector.start(), dest->GetChars() + 1, - string->length()); + vector.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( + isolate->heap()->new_space()->ShrinkStringAtAllocationBoundary( *result, final_size); return *result; } else { diff --git a/test/mjsunit/json2.js b/test/mjsunit/json2.js index 6a72051..cf20b90 100644 --- a/test/mjsunit/json2.js +++ b/test/mjsunit/json2.js @@ -25,7 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --allow-natives-syntax +// Flags: --allow-natives-syntax --expose-externalize-string // Test JSON.stringify on the global object. var a = 12345; @@ -172,3 +172,9 @@ non_enum.a = 1; Object.defineProperty(non_enum, "b", { value: 2, enumerable: false }); non_enum.c = 3; TestStringify('{"a":1,"c":3}', non_enum); + +var str = "external"; +try { + externalizeString(str, true); +} catch (e) { } +TestStringify("\"external\"", str, null, 0); -- 2.7.4