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

Reply via email to