From: yangguo@chromium.org Date: Fri, 21 Jun 2013 09:24:30 +0000 (+0000) Subject: Short-circuit embedded cons strings. X-Git-Tag: upstream/4.7.83~13734 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b7b92bd9ac6a5bee6d41c8c7e9e070f29d356394;p=platform%2Fupstream%2Fv8.git Short-circuit embedded cons strings. R=mstarzinger@chromium.org BUG= Review URL: https://codereview.chromium.org/17418003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15263 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/assembler-arm-inl.h b/src/arm/assembler-arm-inl.h index 17831c8..bfe9bc8 100644 --- a/src/arm/assembler-arm-inl.h +++ b/src/arm/assembler-arm-inl.h @@ -149,6 +149,7 @@ Object** RelocInfo::target_object_address() { void RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) { ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); + ASSERT(!target->IsConsString()); Assembler::set_target_pointer_at(pc_, reinterpret_cast
(target)); if (mode == UPDATE_WRITE_BARRIER && host() != NULL && diff --git a/src/factory.cc b/src/factory.cc index 8b842a7..10e70d9 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -259,6 +259,32 @@ Handle Factory::NewConsString(Handle first, } +template +Handle ConcatStringContent(Handle result, + Handle first, + Handle second) { + DisallowHeapAllocation pointer_stays_valid; + SinkChar* sink = result->GetChars(); + String::WriteToFlat(*first, sink, 0, first->length()); + String::WriteToFlat(*second, sink + first->length(), 0, second->length()); + return result; +} + + +Handle Factory::NewFlatConcatString(Handle first, + Handle second) { + int total_length = first->length() + second->length(); + if (first->IsOneByteRepresentationUnderneath() && + second->IsOneByteRepresentationUnderneath()) { + return ConcatStringContent( + NewRawOneByteString(total_length), first, second); + } else { + return ConcatStringContent( + NewRawTwoByteString(total_length), first, second); + } +} + + Handle Factory::NewSubString(Handle str, int begin, int end) { diff --git a/src/factory.h b/src/factory.h index cde8432..9ea66be 100644 --- a/src/factory.h +++ b/src/factory.h @@ -152,6 +152,10 @@ class Factory { Handle NewConsString(Handle first, Handle second); + // Create a new sequential string containing the concatenation of the inputs. + Handle NewFlatConcatString(Handle first, + Handle second); + // Create a new string object which holds a substring of a string. Handle NewSubString(Handle str, int begin, diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index e227cea..a46fcb8 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -3338,10 +3338,9 @@ HInstruction* HStringAdd::New( HConstant* c_right = HConstant::cast(right); HConstant* c_left = HConstant::cast(left); if (c_left->HasStringValue() && c_right->HasStringValue()) { - Factory* factory = Isolate::Current()->factory(); - return new(zone) HConstant(factory->NewConsString(c_left->StringValue(), - c_right->StringValue()), - Representation::Tagged()); + Handle concat = zone->isolate()->factory()->NewFlatConcatString( + c_left->StringValue(), c_right->StringValue()); + return new(zone) HConstant(concat, Representation::Tagged()); } } return new(zone) HStringAdd(context, left, right); diff --git a/src/ia32/assembler-ia32-inl.h b/src/ia32/assembler-ia32-inl.h index 0c737ac..b6ef242 100644 --- a/src/ia32/assembler-ia32-inl.h +++ b/src/ia32/assembler-ia32-inl.h @@ -132,6 +132,7 @@ Object** RelocInfo::target_object_address() { void RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) { ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); + ASSERT(!target->IsConsString()); Memory::Object_at(pc_) = target; CPU::FlushICache(pc_, sizeof(Address)); if (mode == UPDATE_WRITE_BARRIER && diff --git a/src/mips/assembler-mips-inl.h b/src/mips/assembler-mips-inl.h index f518f05..2ca0083 100644 --- a/src/mips/assembler-mips-inl.h +++ b/src/mips/assembler-mips-inl.h @@ -202,6 +202,7 @@ Object** RelocInfo::target_object_address() { void RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) { ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); + ASSERT(!target->IsConsString()); Assembler::set_target_address_at(pc_, reinterpret_cast
(target)); if (mode == UPDATE_WRITE_BARRIER && host() != NULL && diff --git a/src/x64/assembler-x64-inl.h b/src/x64/assembler-x64-inl.h index d1d6278..1c231a7 100644 --- a/src/x64/assembler-x64-inl.h +++ b/src/x64/assembler-x64-inl.h @@ -308,6 +308,7 @@ Address* RelocInfo::target_reference_address() { void RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) { ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); + ASSERT(!target->IsConsString()); Memory::Object_at(pc_) = target; CPU::FlushICache(pc_, sizeof(Address)); if (mode == UPDATE_WRITE_BARRIER && diff --git a/test/mjsunit/regress/regress-embedded-cons-string.js b/test/mjsunit/regress/regress-embedded-cons-string.js new file mode 100644 index 0000000..afb3835 --- /dev/null +++ b/test/mjsunit/regress/regress-embedded-cons-string.js @@ -0,0 +1,66 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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: --fold-constants --nodead-code-elimination +// Flags: --expose-gc --allow-natives-syntax +// Flags: --parallel-recompilation --parallel-recompilation-delay=300 + +if (!%IsParallelRecompilationSupported()) { + print("Parallel recompilation is disabled. Skipping this test."); + quit(); +} + +function assertUnoptimized(fun) { + assertTrue(%GetOptimizationStatus(fun) != 1); +} + +function test(fun) { + fun(); + fun(); + %OptimizeFunctionOnNextCall(fun, "parallel"); + fun(); // Trigger optimization in the background. + gc(); // Tenure cons string. + assertUnoptimized(fun); // Compilation not complete yet. + %CompleteOptimization(fun); // Compilation embeds tenured cons string. + gc(); // Visit embedded cons string during mark compact. +} + +function f() { + return "abcdefghijklmn" + "123456789"; +} + +function g() { + return "abcdefghijklmn\u2603" + "123456789"; +} + +function h() { + return "abcdefghijklmn\u2603" + "123456789\u2604"; +} + +test(f); +test(g); +test(h);