From fe6fc554b0850cfe33f5a1c49763015b6088cc64 Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Tue, 9 Apr 2013 08:12:59 +0000 Subject: [PATCH] Fix slow path of JSON.stringifier when GC strikes. FlatContent is not GC-safe. R=verwaest@chromium.org BUG= Review URL: https://chromiumcodereview.appspot.com/13782002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14175 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/json-stringifier.h | 27 ++++++++++++++++------- test/mjsunit/regress/regress-json-stringify-gc.js | 10 +++++++++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/json-stringifier.h b/src/json-stringifier.h index bcdd64c..a154a4e 100644 --- a/src/json-stringifier.h +++ b/src/json-stringifier.h @@ -295,19 +295,30 @@ MaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate, return stringifier.Stringify(object); } - FlattenString(object); - String::FlatContent flat = object->GetFlatContent(); - if (flat.IsAscii()) { + object = FlattenGetString(object); + ASSERT(object->IsFlat()); + if (object->IsOneByteRepresentation()) { + Handle result = + isolate->factory()->NewRawOneByteString(worst_case_length); + AssertNoAllocation no_alloc; + const uint8_t* start = object->IsSeqOneByteString() + ? SeqOneByteString::cast(*object)->GetChars() + : ExternalAsciiString::cast(*object)->GetChars(); return StringifyString_( isolate, - flat.ToOneByteVector(), - isolate->factory()->NewRawOneByteString(worst_case_length)); + Vector(start, object->length()), + result); } else { - ASSERT(flat.IsTwoByte()); + Handle result = + isolate->factory()->NewRawTwoByteString(worst_case_length); + AssertNoAllocation no_alloc; + const uc16* start = object->IsSeqTwoByteString() + ? SeqTwoByteString::cast(*object)->GetChars() + : ExternalTwoByteString::cast(*object)->GetChars(); return StringifyString_( isolate, - flat.ToUC16Vector(), - isolate->factory()->NewRawTwoByteString(worst_case_length)); + Vector(start, object->length()), + result); } } diff --git a/test/mjsunit/regress/regress-json-stringify-gc.js b/test/mjsunit/regress/regress-json-stringify-gc.js index c0a71bf..4b355ae 100644 --- a/test/mjsunit/regress/regress-json-stringify-gc.js +++ b/test/mjsunit/regress/regress-json-stringify-gc.js @@ -39,3 +39,13 @@ json1 = JSON.stringify(a); json2 = JSON.stringify(a); assertTrue(json1 == json2, "GC caused JSON.stringify to fail."); +// Check that the slow path of JSON.stringify works correctly wrt GC. +for (var i = 0; i < 100000; i++) { + var s = i.toString(); + assertEquals('"' + s + '"', JSON.stringify(s, null, 0)); +} + +for (var i = 0; i < 100000; i++) { + var s = i.toString() + "\u2603"; + assertEquals('"' + s + '"', JSON.stringify(s, null, 0)); +} -- 2.7.4