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:
parent
fd46247039
commit
3249530ef0
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
32
test/mjsunit/regress/regress-1757.js
Normal file
32
test/mjsunit/regress/regress-1757.js
Normal 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));
|
Loading…
Reference in New Issue
Block a user