From: yangguo@chromium.org Date: Fri, 22 Mar 2013 08:42:38 +0000 (+0000) Subject: Fix JSON.stringifier's slow path wrt external strings. X-Git-Tag: upstream/4.7.83~14774 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=006b1a88a0c8cd24ab4048ea296fe7d6922b1458;p=platform%2Fupstream%2Fv8.git 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 --- 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);