Fixing issue 1757 (string slices of external strings).

BUG=v8:1757
TEST=regress-1757.js

Review URL: http://codereview.chromium.org/8217011

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9573 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
yangguo@chromium.org 2011-10-10 16:09:03 +00:00
parent fd46247039
commit 3249530ef0
5 changed files with 55 additions and 14 deletions

View File

@ -5088,23 +5088,26 @@ void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
__ cmp(result_, Operand(ip));
__ b(ne, &call_runtime_);
// Get the first of the two strings and load its instance type.
__ ldr(object_, FieldMemOperand(object_, ConsString::kFirstOffset));
__ ldr(result_, FieldMemOperand(object_, ConsString::kFirstOffset));
__ jmp(&assure_seq_string);
// SlicedString, unpack and add offset.
__ bind(&sliced_string);
__ ldr(result_, FieldMemOperand(object_, SlicedString::kOffsetOffset));
__ add(scratch_, scratch_, result_);
__ ldr(object_, FieldMemOperand(object_, SlicedString::kParentOffset));
__ ldr(result_, FieldMemOperand(object_, SlicedString::kParentOffset));
// Assure that we are dealing with a sequential string. Go to runtime if not.
__ bind(&assure_seq_string);
__ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
__ ldr(result_, FieldMemOperand(result_, HeapObject::kMapOffset));
__ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
// Check that parent is not an external string. Go to runtime otherwise.
STATIC_ASSERT(kSeqStringTag == 0);
__ tst(result_, Operand(kStringRepresentationMask));
__ b(ne, &call_runtime_);
// Actually fetch the parent string if it is confirmed to be sequential.
STATIC_ASSERT(SlicedString::kParentOffset == ConsString::kFirstOffset);
__ ldr(object_, FieldMemOperand(object_, SlicedString::kParentOffset));
// Check for 1-byte or 2-byte string.
__ bind(&flat_string);

View File

@ -5119,22 +5119,24 @@ void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
Immediate(masm->isolate()->factory()->empty_string()));
__ j(not_equal, &call_runtime_);
// Get the first of the two strings and load its instance type.
__ mov(object_, FieldOperand(object_, ConsString::kFirstOffset));
__ mov(result_, FieldOperand(object_, ConsString::kFirstOffset));
__ jmp(&assure_seq_string, Label::kNear);
// SlicedString, unpack and add offset.
__ bind(&sliced_string);
__ add(scratch_, FieldOperand(object_, SlicedString::kOffsetOffset));
__ mov(object_, FieldOperand(object_, SlicedString::kParentOffset));
__ mov(result_, FieldOperand(object_, SlicedString::kParentOffset));
// Assure that we are dealing with a sequential string. Go to runtime if not.
__ bind(&assure_seq_string);
__ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
__ mov(result_, FieldOperand(result_, HeapObject::kMapOffset));
__ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
STATIC_ASSERT(kSeqStringTag == 0);
__ test(result_, Immediate(kStringRepresentationMask));
__ j(not_zero, &call_runtime_);
__ jmp(&flat_string, Label::kNear);
// Actually fetch the parent string if it is confirmed to be sequential.
STATIC_ASSERT(SlicedString::kParentOffset == ConsString::kFirstOffset);
__ mov(object_, FieldOperand(object_, SlicedString::kParentOffset));
// Check for 1-byte or 2-byte string.
__ bind(&flat_string);

View File

@ -5130,24 +5130,27 @@ void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
__ Branch(&call_runtime_, ne, result_, Operand(t0));
// Get the first of the two strings and load its instance type.
__ lw(object_, FieldMemOperand(object_, ConsString::kFirstOffset));
__ lw(result_, FieldMemOperand(object_, ConsString::kFirstOffset));
__ jmp(&assure_seq_string);
// SlicedString, unpack and add offset.
__ bind(&sliced_string);
__ lw(result_, FieldMemOperand(object_, SlicedString::kOffsetOffset));
__ addu(scratch_, scratch_, result_);
__ lw(object_, FieldMemOperand(object_, SlicedString::kParentOffset));
__ lw(result_, FieldMemOperand(object_, SlicedString::kParentOffset));
// Assure that we are dealing with a sequential string. Go to runtime if not.
__ bind(&assure_seq_string);
__ lw(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
__ lw(result_, FieldMemOperand(result_, HeapObject::kMapOffset));
__ lbu(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
// Check that parent is not an external string. Go to runtime otherwise.
STATIC_ASSERT(kSeqStringTag == 0);
__ And(t0, result_, Operand(kStringRepresentationMask));
__ Branch(&call_runtime_, ne, t0, Operand(zero_reg));
// Actually fetch the parent string if it is confirmed to be sequential.
STATIC_ASSERT(SlicedString::kParentOffset == ConsString::kFirstOffset);
__ lw(object_, FieldMemOperand(object_, SlicedString::kParentOffset));
// Check for 1-byte or 2-byte string.
__ bind(&flat_string);

View File

@ -4084,22 +4084,23 @@ void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
Heap::kEmptyStringRootIndex);
__ j(not_equal, &call_runtime_);
// Get the first of the two strings and load its instance type.
__ movq(object_, FieldOperand(object_, ConsString::kFirstOffset));
ASSERT(kScratchRegister != scratch_);
__ movq(kScratchRegister, FieldOperand(object_, ConsString::kFirstOffset));
__ jmp(&assure_seq_string, Label::kNear);
// SlicedString, unpack and add offset.
__ bind(&sliced_string);
__ addq(scratch_, FieldOperand(object_, SlicedString::kOffsetOffset));
__ movq(object_, FieldOperand(object_, SlicedString::kParentOffset));
__ movq(kScratchRegister, FieldOperand(object_, SlicedString::kParentOffset));
__ bind(&assure_seq_string);
__ movq(result_, FieldOperand(object_, HeapObject::kMapOffset));
__ movq(result_, FieldOperand(kScratchRegister, HeapObject::kMapOffset));
__ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
// If the first cons component is also non-flat, then go to runtime.
STATIC_ASSERT(kSeqStringTag == 0);
__ testb(result_, Immediate(kStringRepresentationMask));
__ j(not_zero, &call_runtime_);
__ jmp(&flat_string);
__ movq(object_, kScratchRegister);
// Check for 1-byte or 2-byte string.
__ bind(&flat_string);

View File

@ -0,0 +1,32 @@
// Copyright 2011 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: --string-slices --expose-externalize-string
var a = "abcdefghijklmnopqrstuvqxy"+"z";
externalizeString(a, true);
assertEquals('b', a.substring(1).charAt(0));