Revision: 9936
Author: [email protected]
Date: Wed Nov 9 06:32:51 2011
Log: Simplify StringCharCodeAt in non-crankshaft codegen.
TEST=test/mjsunit/string-slices.js
Review URL: http://codereview.chromium.org/8510005
http://code.google.com/p/v8/source/detail?r=9936
Modified:
/branches/bleeding_edge/src/arm/code-stubs-arm.cc
/branches/bleeding_edge/src/arm/full-codegen-arm.cc
/branches/bleeding_edge/src/arm/ic-arm.cc
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/arm/stub-cache-arm.cc
/branches/bleeding_edge/src/code-stubs.h
/branches/bleeding_edge/src/ia32/code-stubs-ia32.cc
/branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/ic-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
/branches/bleeding_edge/src/x64/code-stubs-x64.cc
/branches/bleeding_edge/src/x64/full-codegen-x64.cc
/branches/bleeding_edge/src/x64/ic-x64.cc
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
/branches/bleeding_edge/src/x64/stub-cache-x64.cc
/branches/bleeding_edge/test/mjsunit/string-slices-regexp.js
/branches/bleeding_edge/test/mjsunit/string-slices.js
=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.cc Tue Nov 8 06:39:37
2011
+++ /branches/bleeding_edge/src/arm/code-stubs-arm.cc Wed Nov 9 06:32:51
2011
@@ -5056,14 +5056,11 @@
// If the index is non-smi trigger the non-smi case.
__ JumpIfNotSmi(index_, &index_not_smi_);
-
- // Put smi-tagged index into scratch register.
- __ mov(scratch_, index_);
__ bind(&got_smi_index_);
// Check for index out of range.
__ ldr(ip, FieldMemOperand(object_, String::kLengthOffset));
- __ cmp(ip, Operand(scratch_));
+ __ cmp(ip, Operand(index_));
__ b(ls, index_out_of_range_);
// We need special handling for non-flat strings.
@@ -5089,27 +5086,27 @@
__ LoadRoot(ip, Heap::kEmptyStringRootIndex);
__ cmp(result_, Operand(ip));
__ b(ne, &call_runtime_);
- // Get the first of the two strings and load its instance type.
- __ ldr(result_, FieldMemOperand(object_, ConsString::kFirstOffset));
+ // Get the first of the two parts.
+ __ ldr(object_, 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(result_, FieldMemOperand(object_, SlicedString::kParentOffset));
+ __ add(index_, index_, result_);
+ __ ldr(object_, 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(result_, HeapObject::kMapOffset));
+ __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
__ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
// Check that parent is not an external string. Go to runtime otherwise.
+ // Note that if the original string is a cons or slice with an external
+ // string as underlying string, we pass that unpacked underlying string
with
+ // the updated index to the runtime function.
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);
@@ -5123,15 +5120,15 @@
// add without shifting since the smi tag size is the log2 of the
// number of bytes in a two-byte character.
STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1 && kSmiShiftSize == 0);
- __ add(scratch_, object_, Operand(scratch_));
- __ ldrh(result_, FieldMemOperand(scratch_,
SeqTwoByteString::kHeaderSize));
+ __ add(index_, object_, Operand(index_));
+ __ ldrh(result_, FieldMemOperand(index_, SeqTwoByteString::kHeaderSize));
__ jmp(&got_char_code);
// ASCII string.
// Load the byte into the result register.
__ bind(&ascii_string);
- __ add(scratch_, object_, Operand(scratch_, LSR, kSmiTagSize));
- __ ldrb(result_, FieldMemOperand(scratch_, SeqAsciiString::kHeaderSize));
+ __ add(index_, object_, Operand(index_, LSR, kSmiTagSize));
+ __ ldrb(result_, FieldMemOperand(index_, SeqAsciiString::kHeaderSize));
__ bind(&got_char_code);
__ mov(result_, Operand(result_, LSL, kSmiTagSize));
@@ -5148,12 +5145,12 @@
__ bind(&index_not_smi_);
// If index is a heap number, try converting it to an integer.
__ CheckMap(index_,
- scratch_,
+ result_,
Heap::kHeapNumberMapRootIndex,
index_not_number_,
DONT_DO_SMI_CHECK);
call_helper.BeforeCall(masm);
- __ Push(object_, index_);
+ __ push(object_);
__ push(index_); // Consumed by runtime conversion function.
if (index_flags_ == STRING_INDEX_IS_NUMBER) {
__ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1);
@@ -5164,15 +5161,14 @@
}
// Save the conversion result before the pop instructions below
// have a chance to overwrite it.
- __ Move(scratch_, r0);
- __ pop(index_);
+ __ Move(index_, r0);
__ pop(object_);
// Reload the instance type.
__ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
__ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
call_helper.AfterCall(masm);
// If index is still not a smi, it must be out of range.
- __ JumpIfNotSmi(scratch_, index_out_of_range_);
+ __ JumpIfNotSmi(index_, index_out_of_range_);
// Otherwise, return to the fast path.
__ jmp(&got_smi_index_);
=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Tue Nov 8 06:39:37
2011
+++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Wed Nov 9 06:32:51
2011
@@ -3033,7 +3033,6 @@
Register object = r1;
Register index = r0;
- Register scratch = r2;
Register result = r3;
__ pop(object);
@@ -3043,7 +3042,6 @@
Label done;
StringCharCodeAtGenerator generator(object,
index,
- scratch,
result,
&need_conversion,
&need_conversion,
@@ -3080,8 +3078,7 @@
Register object = r1;
Register index = r0;
- Register scratch1 = r2;
- Register scratch2 = r3;
+ Register scratch = r3;
Register result = r0;
__ pop(object);
@@ -3091,8 +3088,7 @@
Label done;
StringCharAtGenerator generator(object,
index,
- scratch1,
- scratch2,
+ scratch,
result,
&need_conversion,
&need_conversion,
=======================================
--- /branches/bleeding_edge/src/arm/ic-arm.cc Mon Oct 24 03:55:00 2011
+++ /branches/bleeding_edge/src/arm/ic-arm.cc Wed Nov 9 06:32:51 2011
@@ -1109,14 +1109,12 @@
Register receiver = r1;
Register index = r0;
- Register scratch1 = r2;
- Register scratch2 = r3;
+ Register scratch = r3;
Register result = r0;
StringCharAtGenerator char_at_generator(receiver,
index,
- scratch1,
- scratch2,
+ scratch,
result,
&miss, // When not a string.
&miss, // When not a number.
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Nov 8
06:39:37 2011
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Nov 9
06:32:51 2011
@@ -3647,6 +3647,9 @@
// Check whether the string is sequential. The only non-sequential
// shapes we support have just been unwrapped above.
+ // Note that if the original string is a cons or slice with an external
+ // string as underlying string, we pass that unpacked underlying string
with
+ // the updated index to the runtime function.
__ bind(&check_sequential);
STATIC_ASSERT(kSeqStringTag == 0);
__ tst(result, Operand(kStringRepresentationMask));
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Fri Oct 28 07:08:43
2011
+++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Wed Nov 9 06:32:51
2011
@@ -1727,7 +1727,6 @@
Register receiver = r1;
Register index = r4;
- Register scratch = r3;
Register result = r0;
__ ldr(receiver, MemOperand(sp, argc * kPointerSize));
if (argc > 0) {
@@ -1738,7 +1737,6 @@
StringCharCodeAtGenerator generator(receiver,
index,
- scratch,
result,
&miss, // When not a string.
&miss, // When not a number.
@@ -1809,8 +1807,7 @@
Register receiver = r0;
Register index = r4;
- Register scratch1 = r1;
- Register scratch2 = r3;
+ Register scratch = r3;
Register result = r0;
__ ldr(receiver, MemOperand(sp, argc * kPointerSize));
if (argc > 0) {
@@ -1821,8 +1818,7 @@
StringCharAtGenerator generator(receiver,
index,
- scratch1,
- scratch2,
+ scratch,
result,
&miss, // When not a string.
&miss, // When not a number.
=======================================
--- /branches/bleeding_edge/src/code-stubs.h Wed Nov 2 01:32:40 2011
+++ /branches/bleeding_edge/src/code-stubs.h Wed Nov 9 06:32:51 2011
@@ -771,7 +771,6 @@
public:
StringCharCodeAtGenerator(Register object,
Register index,
- Register scratch,
Register result,
Label* receiver_not_string,
Label* index_not_number,
@@ -779,7 +778,6 @@
StringIndexFlags index_flags)
: object_(object),
index_(index),
- scratch_(scratch),
result_(result),
receiver_not_string_(receiver_not_string),
index_not_number_(index_not_number),
@@ -805,7 +803,6 @@
private:
Register object_;
Register index_;
- Register scratch_;
Register result_;
Label* receiver_not_string_;
@@ -868,8 +865,7 @@
public:
StringCharAtGenerator(Register object,
Register index,
- Register scratch1,
- Register scratch2,
+ Register scratch,
Register result,
Label* receiver_not_string,
Label* index_not_number,
@@ -877,13 +873,12 @@
StringIndexFlags index_flags)
: char_code_at_generator_(object,
index,
- scratch1,
- scratch2,
+ scratch,
receiver_not_string,
index_not_number,
index_out_of_range,
index_flags),
- char_from_code_generator_(scratch2, result) {}
+ char_from_code_generator_(scratch, result) {}
// Generates the fast case code. On the fallthrough path |result|
// register contains the result.
=======================================
--- /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Tue Nov 8 06:39:37
2011
+++ /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Wed Nov 9 06:32:51
2011
@@ -5106,13 +5106,10 @@
// If the index is non-smi trigger the non-smi case.
STATIC_ASSERT(kSmiTag == 0);
__ JumpIfNotSmi(index_, &index_not_smi_);
-
- // Put smi-tagged index into scratch register.
- __ mov(scratch_, index_);
__ bind(&got_smi_index_);
// Check for index out of range.
- __ cmp(scratch_, FieldOperand(object_, String::kLengthOffset));
+ __ cmp(index_, FieldOperand(object_, String::kLengthOffset));
__ j(above_equal, index_out_of_range_);
// We need special handling for non-flat strings.
@@ -5137,25 +5134,25 @@
__ cmp(FieldOperand(object_, ConsString::kSecondOffset),
Immediate(masm->isolate()->factory()->empty_string()));
__ j(not_equal, &call_runtime_);
- // Get the first of the two strings and load its instance type.
- __ mov(result_, FieldOperand(object_, ConsString::kFirstOffset));
+ // Get the first of the two parts.
+ __ mov(object_, 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(result_, FieldOperand(object_, SlicedString::kParentOffset));
+ __ add(index_, FieldOperand(object_, SlicedString::kOffsetOffset));
+ __ mov(object_, FieldOperand(object_, SlicedString::kParentOffset));
// Assure that we are dealing with a sequential string. Go to runtime if
not.
+ // Note that if the original string is a cons or slice with an external
+ // string as underlying string, we pass that unpacked underlying string
with
+ // the updated index to the runtime function.
__ bind(&assure_seq_string);
- __ mov(result_, FieldOperand(result_, HeapObject::kMapOffset));
+ __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
__ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
STATIC_ASSERT(kSeqStringTag == 0);
__ test(result_, Immediate(kStringRepresentationMask));
__ j(not_zero, &call_runtime_);
- // 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);
@@ -5168,16 +5165,16 @@
// Load the 2-byte character code into the result register.
STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
__ movzx_w(result_, FieldOperand(object_,
- scratch_, times_1, // Scratch is
smi-tagged.
+ index_, times_1, // Scratch is
smi-tagged.
SeqTwoByteString::kHeaderSize));
__ jmp(&got_char_code, Label::kNear);
// ASCII string.
// Load the byte into the result register.
__ bind(&ascii_string);
- __ SmiUntag(scratch_);
+ __ SmiUntag(index_);
__ movzx_b(result_, FieldOperand(object_,
- scratch_, times_1,
+ index_, times_1,
SeqAsciiString::kHeaderSize));
__ bind(&got_char_code);
__ SmiTag(result_);
@@ -5199,7 +5196,6 @@
DONT_DO_SMI_CHECK);
call_helper.BeforeCall(masm);
__ push(object_);
- __ push(index_);
__ push(index_); // Consumed by runtime conversion function.
if (index_flags_ == STRING_INDEX_IS_NUMBER) {
__ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1);
@@ -5208,12 +5204,11 @@
// NumberToSmi discards numbers that are not exact integers.
__ CallRuntime(Runtime::kNumberToSmi, 1);
}
- if (!scratch_.is(eax)) {
+ if (!index_.is(eax)) {
// Save the conversion result before the pop instructions below
// have a chance to overwrite it.
- __ mov(scratch_, eax);
- }
- __ pop(index_);
+ __ mov(index_, eax);
+ }
__ pop(object_);
// Reload the instance type.
__ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
@@ -5221,7 +5216,7 @@
call_helper.AfterCall(masm);
// If index is still not a smi, it must be out of range.
STATIC_ASSERT(kSmiTag == 0);
- __ JumpIfNotSmi(scratch_, index_out_of_range_);
+ __ JumpIfNotSmi(index_, index_out_of_range_);
// Otherwise, return to the fast path.
__ jmp(&got_smi_index_);
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Tue Nov 8
06:39:37 2011
+++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Wed Nov 9
06:32:51 2011
@@ -2936,7 +2936,6 @@
Register object = ebx;
Register index = eax;
- Register scratch = ecx;
Register result = edx;
__ pop(object);
@@ -2946,7 +2945,6 @@
Label done;
StringCharCodeAtGenerator generator(object,
index,
- scratch,
result,
&need_conversion,
&need_conversion,
@@ -2984,8 +2982,7 @@
Register object = ebx;
Register index = eax;
- Register scratch1 = ecx;
- Register scratch2 = edx;
+ Register scratch = edx;
Register result = eax;
__ pop(object);
@@ -2995,8 +2992,7 @@
Label done;
StringCharAtGenerator generator(object,
index,
- scratch1,
- scratch2,
+ scratch,
result,
&need_conversion,
&need_conversion,
=======================================
--- /branches/bleeding_edge/src/ia32/ic-ia32.cc Mon Oct 24 03:55:00 2011
+++ /branches/bleeding_edge/src/ia32/ic-ia32.cc Wed Nov 9 06:32:51 2011
@@ -606,14 +606,12 @@
Register receiver = edx;
Register index = eax;
- Register scratch1 = ebx;
- Register scratch2 = ecx;
+ Register scratch = ecx;
Register result = eax;
StringCharAtGenerator char_at_generator(receiver,
index,
- scratch1,
- scratch2,
+ scratch,
result,
&miss, // When not a string.
&miss, // When not a number.
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Nov 8
06:39:37 2011
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Wed Nov 9
06:32:51 2011
@@ -3451,6 +3451,9 @@
// Check whether the string is sequential. The only non-sequential
// shapes we support have just been unwrapped above.
+ // Note that if the original string is a cons or slice with an external
+ // string as underlying string, we pass that unpacked underlying string
with
+ // the updated index to the runtime function.
__ bind(&check_sequential);
STATIC_ASSERT(kSeqStringTag == 0);
__ test(result, Immediate(kStringRepresentationMask));
=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Fri Oct 28 07:08:43
2011
+++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Wed Nov 9 06:32:51
2011
@@ -1624,7 +1624,6 @@
Register receiver = ebx;
Register index = edi;
- Register scratch = edx;
Register result = eax;
__ mov(receiver, Operand(esp, (argc + 1) * kPointerSize));
if (argc > 0) {
@@ -1635,7 +1634,6 @@
StringCharCodeAtGenerator generator(receiver,
index,
- scratch,
result,
&miss, // When not a string.
&miss, // When not a number.
@@ -1709,8 +1707,7 @@
Register receiver = eax;
Register index = edi;
- Register scratch1 = ebx;
- Register scratch2 = edx;
+ Register scratch = edx;
Register result = eax;
__ mov(receiver, Operand(esp, (argc + 1) * kPointerSize));
if (argc > 0) {
@@ -1721,8 +1718,7 @@
StringCharAtGenerator generator(receiver,
index,
- scratch1,
- scratch2,
+ scratch,
result,
&miss, // When not a string.
&miss, // When not a number.
=======================================
--- /branches/bleeding_edge/src/x64/code-stubs-x64.cc Tue Nov 8 06:39:37
2011
+++ /branches/bleeding_edge/src/x64/code-stubs-x64.cc Wed Nov 9 06:32:51
2011
@@ -4068,13 +4068,10 @@
// If the index is non-smi trigger the non-smi case.
__ JumpIfNotSmi(index_, &index_not_smi_);
-
- // Put smi-tagged index into scratch register.
- __ movq(scratch_, index_);
__ bind(&got_smi_index_);
// Check for index out of range.
- __ SmiCompare(scratch_, FieldOperand(object_, String::kLengthOffset));
+ __ SmiCompare(index_, FieldOperand(object_, String::kLengthOffset));
__ j(above_equal, index_out_of_range_);
// We need special handling for non-flat strings.
@@ -4099,46 +4096,47 @@
__ CompareRoot(FieldOperand(object_, ConsString::kSecondOffset),
Heap::kEmptyStringRootIndex);
__ j(not_equal, &call_runtime_);
- // Get the first of the two strings and load its instance type.
+ // Get the first of the two parts.
ASSERT(!kScratchRegister.is(scratch_));
- __ movq(kScratchRegister, FieldOperand(object_,
ConsString::kFirstOffset));
+ __ movq(object_, 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(kScratchRegister, FieldOperand(object_,
SlicedString::kParentOffset));
-
+ __ addq(index_, FieldOperand(object_, SlicedString::kOffsetOffset));
+ __ movq(object_, FieldOperand(object_, SlicedString::kParentOffset));
+
+ // Assure that we are dealing with a sequential string. Go to runtime if
not.
+ // Note that if the original string is a cons or slice with an external
+ // string as underlying string, we pass that unpacked underlying string
with
+ // the updated index to the runtime function.
__ bind(&assure_seq_string);
- __ movq(result_, FieldOperand(kScratchRegister, HeapObject::kMapOffset));
+ __ movq(result_, FieldOperand(object_, 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_);
- __ movq(object_, kScratchRegister);
// Check for 1-byte or 2-byte string.
__ bind(&flat_string);
STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
+ __ SmiToInteger32(index_, index_);
__ testb(result_, Immediate(kStringEncodingMask));
__ j(not_zero, &ascii_string);
// 2-byte string.
// Load the 2-byte character code into the result register.
- __ SmiToInteger32(scratch_, scratch_);
__ movzxwl(result_, FieldOperand(object_,
- scratch_, times_2,
+ index_, times_2,
SeqTwoByteString::kHeaderSize));
__ jmp(&got_char_code);
// ASCII string.
// Load the byte into the result register.
__ bind(&ascii_string);
- __ SmiToInteger32(scratch_, scratch_);
__ movzxbl(result_, FieldOperand(object_,
- scratch_, times_1,
+ index_, times_1,
SeqAsciiString::kHeaderSize));
__ bind(&got_char_code);
__ Integer32ToSmi(result_, result_);
@@ -4161,7 +4159,6 @@
DONT_DO_SMI_CHECK);
call_helper.BeforeCall(masm);
__ push(object_);
- __ push(index_);
__ push(index_); // Consumed by runtime conversion function.
if (index_flags_ == STRING_INDEX_IS_NUMBER) {
__ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1);
@@ -4170,19 +4167,18 @@
// NumberToSmi discards numbers that are not exact integers.
__ CallRuntime(Runtime::kNumberToSmi, 1);
}
- if (!scratch_.is(rax)) {
+ if (!index_.is(rax)) {
// Save the conversion result before the pop instructions below
// have a chance to overwrite it.
- __ movq(scratch_, rax);
- }
- __ pop(index_);
+ __ movq(index_, rax);
+ }
__ pop(object_);
// Reload the instance type.
__ movq(result_, FieldOperand(object_, HeapObject::kMapOffset));
__ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
call_helper.AfterCall(masm);
// If index is still not a smi, it must be out of range.
- __ JumpIfNotSmi(scratch_, index_out_of_range_);
+ __ JumpIfNotSmi(index_, index_out_of_range_);
// Otherwise, return to the fast path.
__ jmp(&got_smi_index_);
=======================================
--- /branches/bleeding_edge/src/x64/full-codegen-x64.cc Tue Nov 8 06:39:37
2011
+++ /branches/bleeding_edge/src/x64/full-codegen-x64.cc Wed Nov 9 06:32:51
2011
@@ -2865,7 +2865,6 @@
Register object = rbx;
Register index = rax;
- Register scratch = rcx;
Register result = rdx;
__ pop(object);
@@ -2875,7 +2874,6 @@
Label done;
StringCharCodeAtGenerator generator(object,
index,
- scratch,
result,
&need_conversion,
&need_conversion,
@@ -2913,8 +2911,7 @@
Register object = rbx;
Register index = rax;
- Register scratch1 = rcx;
- Register scratch2 = rdx;
+ Register scratch = rdx;
Register result = rax;
__ pop(object);
@@ -2924,8 +2921,7 @@
Label done;
StringCharAtGenerator generator(object,
index,
- scratch1,
- scratch2,
+ scratch,
result,
&need_conversion,
&need_conversion,
=======================================
--- /branches/bleeding_edge/src/x64/ic-x64.cc Wed Oct 26 04:34:11 2011
+++ /branches/bleeding_edge/src/x64/ic-x64.cc Wed Nov 9 06:32:51 2011
@@ -531,14 +531,12 @@
Register receiver = rdx;
Register index = rax;
- Register scratch1 = rbx;
- Register scratch2 = rcx;
+ Register scratch = rcx;
Register result = rax;
StringCharAtGenerator char_at_generator(receiver,
index,
- scratch1,
- scratch2,
+ scratch,
result,
&miss, // When not a string.
&miss, // When not a number.
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Nov 8
06:39:37 2011
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Nov 9
06:32:51 2011
@@ -3380,6 +3380,9 @@
// Check whether the string is sequential. The only non-sequential
// shapes we support have just been unwrapped above.
+ // Note that if the original string is a cons or slice with an external
+ // string as underlying string, we pass that unpacked underlying string
with
+ // the updated index to the runtime function.
__ bind(&check_sequential);
STATIC_ASSERT(kSeqStringTag == 0);
__ testb(result, Immediate(kStringRepresentationMask));
=======================================
--- /branches/bleeding_edge/src/x64/stub-cache-x64.cc Fri Oct 28 07:08:43
2011
+++ /branches/bleeding_edge/src/x64/stub-cache-x64.cc Wed Nov 9 06:32:51
2011
@@ -1600,7 +1600,6 @@
Register receiver = rbx;
Register index = rdi;
- Register scratch = rdx;
Register result = rax;
__ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize));
if (argc > 0) {
@@ -1611,7 +1610,6 @@
StringCharCodeAtGenerator generator(receiver,
index,
- scratch,
result,
&miss, // When not a string.
&miss, // When not a number.
@@ -1680,8 +1678,7 @@
Register receiver = rax;
Register index = rdi;
- Register scratch1 = rbx;
- Register scratch2 = rdx;
+ Register scratch = rdx;
Register result = rax;
__ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize));
if (argc > 0) {
@@ -1692,8 +1689,7 @@
StringCharAtGenerator generator(receiver,
index,
- scratch1,
- scratch2,
+ scratch,
result,
&miss, // When not a string.
&miss, // When not a number.
=======================================
--- /branches/bleeding_edge/test/mjsunit/string-slices-regexp.js Mon Sep 19
11:36:47 2011
+++ /branches/bleeding_edge/test/mjsunit/string-slices-regexp.js Wed Nov 9
06:32:51 2011
@@ -24,11 +24,6 @@
// 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
-
-//assertEquals('345"12345 6"1234567"123',
-// '12345""12345
6""1234567""1234'.slice(2,-1).replace(/""/g, '"'));
var foo = "lsdfj sldkfj sdklfj læsdfjl sdkfjlsdk fjsdl fjsdljskdj flsj
flsdkj flskd regexp: /foobar/\nldkfj sdlkfj sdkl";
for(var i = 0; i < 1000; i++) {
=======================================
--- /branches/bleeding_edge/test/mjsunit/string-slices.js Mon Oct 17
06:39:56 2011
+++ /branches/bleeding_edge/test/mjsunit/string-slices.js Wed Nov 9
06:32:51 2011
@@ -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: --string-slices --expose-externalize-string
+// Flags: --expose-externalize-string --allow-natives-syntax
var s = 'abcdefghijklmn';
assertEquals(s, s.substr());
@@ -100,14 +100,7 @@
// Keep creating strings to to force allocation failure on substring
creation.
var x = "0123456789ABCDEF";
-x += x; // 2^5
-x += x;
-x += x;
-x += x;
-x += x;
-x += x; // 2^10
-x += x;
-x += x;
+for (var i = 0; i < 8; i++) x += x;
var xl = x.length;
var cache = [];
for (var i = 0; i < 1000; i++) {
@@ -119,14 +112,7 @@
// Same with two-byte strings
var x = "\u2028123456789ABCDEF";
-x += x; // 2^5
-x += x;
-x += x;
-x += x;
-x += x;
-x += x; // 2^10
-x += x;
-x += x;
+for (var i = 0; i < 8; i++) x += x;
var xl = x.length;
var cache = [];
for (var i = 0; i < 1000; i++) {
@@ -202,3 +188,21 @@
assertTrue(/3456789qwe/.test(a));
assertEquals(5, a.indexOf("678"));
assertEquals("12345", a.split("6")[0]);
+
+// Create a slice with an external string as parent string.
+var c = a.slice(1,-1);
+
+function test_crankshaft() {
+ for (var i = 0; i < 20; i++) {
+ assertEquals(b.charAt(i), a.charAt(i + 1));
+ assertEquals(b.charAt(i), c.charAt(i));
+ assertEquals(b.charAt(4), c.charAt(4));
+ assertTrue(/3456789qwe/.test(c));
+ assertEquals(4, c.indexOf("678"));
+ assertEquals("2345", c.split("6")[0]);
+ }
+}
+
+test_crankshaft();
+%OptimizeFunctionOnNextCall(test_crankshaft);
+test_crankshaft();
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev