Revision: 4563
Author: [email protected]
Date: Mon May  3 02:56:08 2010
Log: Revert "Changing string length field type from int to SMI."

This reverts svn commit 4556 from trunk.

Review URL: http://codereview.chromium.org/1857001
http://code.google.com/p/v8/source/detail?r=4563

Modified:
 /trunk/include/v8.h
 /trunk/src/arm/codegen-arm.cc
 /trunk/src/arm/macro-assembler-arm.cc
 /trunk/src/arm/macro-assembler-arm.h
 /trunk/src/arm/stub-cache-arm.cc
 /trunk/src/ia32/codegen-ia32.cc
 /trunk/src/ia32/macro-assembler-ia32.cc
 /trunk/src/ia32/stub-cache-ia32.cc
 /trunk/src/objects-inl.h
 /trunk/src/objects.h
 /trunk/src/x64/codegen-x64.cc
 /trunk/src/x64/macro-assembler-x64.cc
 /trunk/src/x64/macro-assembler-x64.h
 /trunk/src/x64/stub-cache-x64.cc
 /trunk/test/cctest/test-serialize.cc

=======================================
--- /trunk/include/v8.h Fri Apr 30 05:51:36 2010
+++ /trunk/include/v8.h Mon May  3 02:56:08 2010
@@ -3014,7 +3014,7 @@

 // Internal constants for 64-bit systems.
 template <> struct InternalConstants<8> {
-  static const int kStringResourceOffset = 3 * sizeof(void*);
+  static const int kStringResourceOffset = 2 * sizeof(void*);
 };

 /**
=======================================
--- /trunk/src/arm/codegen-arm.cc       Fri Apr 30 05:51:36 2010
+++ /trunk/src/arm/codegen-arm.cc       Mon May  3 02:56:08 2010
@@ -3978,8 +3978,8 @@

   // Now r2 has the string type.
   __ ldr(r3, FieldMemOperand(r1, String::kLengthOffset));
-  // Now r3 has the length of the string. Compare with the index.
-  __ cmp(r3, Operand(r0));
+  // Now r3 has the length of the string.  Compare with the index.
+  __ cmp(r3, Operand(r0, LSR, kSmiTagSize));
   __ b(le, &slow);

   // Here we know the index is in range.  Check that string is sequential.
@@ -8388,16 +8388,14 @@
   __ ldr(r3, FieldMemOperand(subject, String::kLengthOffset));

   // r2: Number of capture registers
-  // r3: Length of subject string as a smi
+  // r3: Length of subject string
   // subject: Subject string
   // regexp_data: RegExp data (FixedArray)
   // Check that the third argument is a positive smi less than the subject
   // string length. A negative value will be greater (unsigned comparison).
   __ ldr(r0, MemOperand(sp, kPreviousIndexOffset));
-  __ tst(r0, Operand(kSmiTagMask));
-  __ b(eq, &runtime);
-  __ cmp(r3, Operand(r0));
-  __ b(le, &runtime);
+  __ cmp(r3, Operand(r0, ASR, kSmiTagSize + kSmiShiftSize));
+  __ b(ls, &runtime);

   // r2: Number of capture registers
   // subject: Subject string
@@ -8523,7 +8521,6 @@
// For arguments 4 and 3 get string length, calculate start of string data and
   // calculate the shift of the index (0 for ASCII and 1 for two byte).
   __ ldr(r0, FieldMemOperand(subject, String::kLengthOffset));
-  __ mov(r0, Operand(r0, ASR, kSmiTagSize));
   ASSERT_EQ(SeqAsciiString::kHeaderSize, SeqTwoByteString::kHeaderSize);
__ add(r9, subject, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   __ eor(r3, r3, Operand(1));
@@ -9031,7 +9028,7 @@

     // If length is not 2 the string is not a candidate.
     __ ldr(scratch, FieldMemOperand(candidate, String::kLengthOffset));
-    __ cmp(scratch, Operand(Smi::FromInt(2)));
+    __ cmp(scratch, Operand(2));
     __ b(ne, &next_probe[i]);

     // Check that the candidate is a non-external ascii string.
@@ -9182,7 +9179,7 @@
   // r6: from (smi)
   // r7: to (smi)
   __ ldr(r4, FieldMemOperand(r5, String::kLengthOffset));
-  __ cmp(r4, Operand(r7));
+  __ cmp(r4, Operand(r7, ASR, 1));
   __ b(lt, &runtime);  // Fail if to > length.

   // r1: instance type.
@@ -9301,13 +9298,9 @@
   Register length_delta = scratch3;
   __ mov(scratch1, scratch2, LeaveCC, gt);
   Register min_length = scratch1;
-  ASSERT(kSmiTag == 0);
   __ tst(min_length, Operand(min_length));
   __ b(eq, &compare_lengths);

-  // Untag smi.
-  __ mov(min_length, Operand(min_length, ASR, kSmiTagSize));
-
   // Setup registers so that we only need to increment one register
   // in the loop.
   __ add(scratch2, min_length,
@@ -9417,12 +9410,9 @@
// Check if either of the strings are empty. In that case return the other.
     __ ldr(r2, FieldMemOperand(r0, String::kLengthOffset));
     __ ldr(r3, FieldMemOperand(r1, String::kLengthOffset));
-    ASSERT(kSmiTag == 0);
- __ cmp(r2, Operand(Smi::FromInt(0))); // Test if first string is empty.
+    __ cmp(r2, Operand(0));  // Test if first string is empty.
__ mov(r0, Operand(r1), LeaveCC, eq); // If first is empty, return second.
-    ASSERT(kSmiTag == 0);
-     // Else test if second string is empty.
-    __ cmp(r3, Operand(Smi::FromInt(0)), ne);
+    __ cmp(r3, Operand(0), ne);  // Else test if second string is empty.
__ b(ne, &strings_not_empty); // If either string was empty, return r0.

     __ IncrementCounter(&Counters::string_add_native, 1, r2, r3);
@@ -9432,8 +9422,6 @@
     __ bind(&strings_not_empty);
   }

-  __ mov(r2, Operand(r2, ASR, kSmiTagSize));
-  __ mov(r3, Operand(r3, ASR, kSmiTagSize));
   // Both strings are non-empty.
   // r0: first string
   // r1: second string
=======================================
--- /trunk/src/arm/macro-assembler-arm.cc       Fri Apr 30 05:51:36 2010
+++ /trunk/src/arm/macro-assembler-arm.cc       Mon May  3 02:56:08 2010
@@ -397,20 +397,6 @@
   }
 #endif
 }
-
-
-void MacroAssembler::InitializeNewString(Register string,
-                                         Register length,
-                                         Heap::RootListIndex map_index,
-                                         Register scratch1,
-                                         Register scratch2) {
-  mov(scratch1, Operand(length, LSL, kSmiTagSize));
-  LoadRoot(scratch2, map_index);
-  str(scratch1, FieldMemOperand(string, String::kLengthOffset));
-  mov(scratch1, Operand(String::kEmptyHashField));
-  str(scratch2, FieldMemOperand(string, HeapObject::kMapOffset));
-  str(scratch1, FieldMemOperand(string, String::kHashFieldOffset));
-}


 int MacroAssembler::ActivationFrameAlignment() {
@@ -1034,11 +1020,11 @@
                      TAG_OBJECT);

   // Set the map, length and hash field.
-  InitializeNewString(result,
-                      length,
-                      Heap::kStringMapRootIndex,
-                      scratch1,
-                      scratch2);
+  LoadRoot(scratch1, Heap::kStringMapRootIndex);
+  str(length, FieldMemOperand(result, String::kLengthOffset));
+  str(scratch1, FieldMemOperand(result, HeapObject::kMapOffset));
+  mov(scratch2, Operand(String::kEmptyHashField));
+  str(scratch2, FieldMemOperand(result, String::kHashFieldOffset));
 }


@@ -1068,11 +1054,12 @@
                      TAG_OBJECT);

   // Set the map, length and hash field.
-  InitializeNewString(result,
-                      length,
-                      Heap::kAsciiStringMapRootIndex,
-                      scratch1,
-                      scratch2);
+  LoadRoot(scratch1, Heap::kAsciiStringMapRootIndex);
+  mov(scratch1, Operand(Factory::ascii_string_map()));
+  str(length, FieldMemOperand(result, String::kLengthOffset));
+  str(scratch1, FieldMemOperand(result, HeapObject::kMapOffset));
+  mov(scratch2, Operand(String::kEmptyHashField));
+  str(scratch2, FieldMemOperand(result, String::kHashFieldOffset));
 }


@@ -1087,12 +1074,11 @@
                      scratch2,
                      gc_required,
                      TAG_OBJECT);
-
-  InitializeNewString(result,
-                      length,
-                      Heap::kConsStringMapRootIndex,
-                      scratch1,
-                      scratch2);
+  LoadRoot(scratch1, Heap::kConsStringMapRootIndex);
+  mov(scratch2, Operand(String::kEmptyHashField));
+  str(length, FieldMemOperand(result, String::kLengthOffset));
+  str(scratch1, FieldMemOperand(result, HeapObject::kMapOffset));
+  str(scratch2, FieldMemOperand(result, String::kHashFieldOffset));
 }


@@ -1107,12 +1093,11 @@
                      scratch2,
                      gc_required,
                      TAG_OBJECT);
-
-  InitializeNewString(result,
-                      length,
-                      Heap::kConsAsciiStringMapRootIndex,
-                      scratch1,
-                      scratch2);
+  LoadRoot(scratch1, Heap::kConsAsciiStringMapRootIndex);
+  mov(scratch2, Operand(String::kEmptyHashField));
+  str(length, FieldMemOperand(result, String::kLengthOffset));
+  str(scratch1, FieldMemOperand(result, HeapObject::kMapOffset));
+  str(scratch2, FieldMemOperand(result, String::kHashFieldOffset));
 }


=======================================
--- /trunk/src/arm/macro-assembler-arm.h        Fri Apr 30 05:51:36 2010
+++ /trunk/src/arm/macro-assembler-arm.h        Mon May  3 02:56:08 2010
@@ -553,12 +553,6 @@
   void EnterFrame(StackFrame::Type type);
   void LeaveFrame(StackFrame::Type type);

-  void InitializeNewString(Register string,
-                           Register length,
-                           Heap::RootListIndex map_index,
-                           Register scratch1,
-                           Register scratch2);
-
   bool generating_stub_;
   bool allow_stub_calls_;
   // This handle will be patched with the code object on installation.
=======================================
--- /trunk/src/arm/stub-cache-arm.cc    Fri Apr 30 05:51:36 2010
+++ /trunk/src/arm/stub-cache-arm.cc    Mon May  3 02:56:08 2010
@@ -229,6 +229,7 @@

   // Load length directly from the string.
   __ ldr(r0, FieldMemOperand(receiver, String::kLengthOffset));
+  __ mov(r0, Operand(r0, LSL, kSmiTagSize));
   __ Ret();

   // Check if the object is a JSValue wrapper.
@@ -240,6 +241,7 @@
   __ ldr(scratch1, FieldMemOperand(receiver, JSValue::kValueOffset));
   GenerateStringCheck(masm, scratch1, scratch2, scratch2, miss, miss);
   __ ldr(r0, FieldMemOperand(scratch1, String::kLengthOffset));
+  __ mov(r0, Operand(r0, LSL, kSmiTagSize));
   __ Ret();
 }

=======================================
--- /trunk/src/ia32/codegen-ia32.cc     Fri Apr 30 05:51:36 2010
+++ /trunk/src/ia32/codegen-ia32.cc     Mon May  3 02:56:08 2010
@@ -2693,7 +2693,7 @@
       if (cc == equal) {
         Label comparison_done;
         __ cmp(FieldOperand(left_side.reg(), String::kLengthOffset),
-               Immediate(Smi::FromInt(1)));
+               Immediate(1));
         __ j(not_equal, &comparison_done);
         uint8_t char_value =
             static_cast<uint8_t>(String::cast(*right_val)->Get(0));
@@ -2703,7 +2703,6 @@
       } else {
         __ mov(temp2.reg(),
                FieldOperand(left_side.reg(), String::kLengthOffset));
-        __ SmiUntag(temp2.reg());
         __ sub(Operand(temp2.reg()), Immediate(1));
         Label comparison;
// If the length is 0 then the subtraction gave -1 which compares less
@@ -2723,7 +2722,7 @@
// If the first character is the same then the long string sorts after
         // the short one.
         __ cmp(FieldOperand(left_side.reg(), String::kLengthOffset),
-               Immediate(Smi::FromInt(1)));
+               Immediate(1));
         __ bind(&characters_were_different);
       }
       temp2.Unuse();
@@ -8820,7 +8819,6 @@
   __ cmp(ecx, FIRST_NONSTRING_TYPE);
   __ j(above_equal, &not_string);
   __ mov(edx, FieldOperand(eax, String::kLengthOffset));
-  ASSERT(kSmiTag == 0);
   __ test(edx, Operand(edx));
   __ j(zero, &false_result);
   __ jmp(&true_result);
@@ -10777,16 +10775,15 @@
   // Get the length of the string to ebx.
   __ mov(ebx, FieldOperand(eax, String::kLengthOffset));

-  // ebx: Length of subject string as a smi
+  // ebx: Length of subject string
   // ecx: RegExp data (FixedArray)
   // edx: Number of capture registers
   // Check that the third argument is a positive smi less than the subject
   // string length. A negative value will be greater (unsigned comparison).
   __ mov(eax, Operand(esp, kPreviousIndexOffset));
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(zero, &runtime);
+  __ SmiUntag(eax);
   __ cmp(eax, Operand(ebx));
-  __ j(above_equal, &runtime);
+  __ j(above, &runtime);

   // ecx: RegExp data (FixedArray)
   // edx: Number of capture registers
@@ -10909,7 +10906,6 @@
   __ test(edi, Operand(edi));
   __ mov(edi, FieldOperand(eax, String::kLengthOffset));
   __ j(zero, &setup_two_byte);
-  __ SmiUntag(edi);
__ lea(ecx, FieldOperand(eax, edi, times_1, SeqAsciiString::kHeaderSize));
   __ mov(Operand(esp, 3 * kPointerSize), ecx);  // Argument 4.
__ lea(ecx, FieldOperand(eax, ebx, times_1, SeqAsciiString::kHeaderSize));
@@ -10917,8 +10913,7 @@
   __ jmp(&setup_rest);

   __ bind(&setup_two_byte);
-  ASSERT(kSmiTag == 0 && kSmiTagSize == 1);  // edi is smi (powered by 2).
- __ lea(ecx, FieldOperand(eax, edi, times_1, SeqTwoByteString::kHeaderSize)); + __ lea(ecx, FieldOperand(eax, edi, times_2, SeqTwoByteString::kHeaderSize));
   __ mov(Operand(esp, 3 * kPointerSize), ecx);  // Argument 4.
__ lea(ecx, FieldOperand(eax, ebx, times_2, SeqTwoByteString::kHeaderSize));
   __ mov(Operand(esp, 2 * kPointerSize), ecx);  // Argument 3.
@@ -12081,8 +12076,12 @@
   __ test(index, Immediate(kSmiTagMask | kSmiSignMask));
   __ j(not_zero, index_not_positive_smi);

+  // Put untagged index into scratch register.
+  __ mov(scratch, index);
+  __ SmiUntag(scratch);
+
   // Check for index out of range.
-  __ cmp(index, FieldOperand(object, String::kLengthOffset));
+  __ cmp(scratch, FieldOperand(object, String::kLengthOffset));
   __ j(greater_equal, slow_case);

   __ bind(&try_again_with_new_string);
@@ -12104,9 +12103,8 @@

   // 2-byte string.
   // Load the 2-byte character code into the temp register.
- ASSERT(kSmiTagSize == 1 && kSmiTag == 0); // index is smi (powered by 2).
   __ movzx_w(result, FieldOperand(object,
-                                  index, times_1,
+                                  scratch, times_2,
                                   SeqTwoByteString::kHeaderSize));
   __ jmp(&got_char_code);

@@ -12132,10 +12130,6 @@

   // ASCII string.
   __ bind(&ascii_string);
-  // Put untagged index into scratch register.
-  __ mov(scratch, index);
-  __ SmiUntag(scratch);
-
   // Load the byte into the temp register.
   __ movzx_b(result, FieldOperand(object,
                                   scratch, times_1,
@@ -12226,7 +12220,6 @@
// Check if either of the strings are empty. In that case return the other.
   Label second_not_zero_length, both_not_zero_length;
   __ mov(ecx, FieldOperand(edx, String::kLengthOffset));
-  ASSERT(kSmiTag == 0);
   __ test(ecx, Operand(ecx));
   __ j(not_zero, &second_not_zero_length);
// Second string is empty, result is first string which is already in eax.
@@ -12234,7 +12227,6 @@
   __ ret(2 * kPointerSize);
   __ bind(&second_not_zero_length);
   __ mov(ebx, FieldOperand(eax, String::kLengthOffset));
-  ASSERT(kSmiTag == 0);
   __ test(ebx, Operand(ebx));
   __ j(not_zero, &both_not_zero_length);
   // First string is empty, result is second string which is in edx.
@@ -12244,19 +12236,16 @@

   // Both strings are non-empty.
   // eax: first string
-  // ebx: length of first string as a smi
-  // ecx: length of second string as a smi
+  // ebx: length of first string
+  // ecx: length of second string
   // edx: second string
   // Look at the length of the result of adding the two strings.
   Label string_add_flat_result, longer_than_two;
   __ bind(&both_not_zero_length);
   __ add(ebx, Operand(ecx));
-  ASSERT(Smi::kMaxValue == String::kMaxLength);
-  // Handle exceptionally long strings in the runtime system.
-  __ j(overflow, &string_add_runtime);
   // Use the runtime system when adding two one character strings, as it
   // contains optimizations for this specific case using the symbol table.
-  __ cmp(Operand(ebx), Immediate(Smi::FromInt(2)));
+  __ cmp(ebx, 2);
   __ j(not_equal, &longer_than_two);

   // Check that both strings are non-external ascii strings.
@@ -12276,13 +12265,17 @@
   __ ret(2 * kPointerSize);

   __ bind(&make_two_character_string);
-  __ Set(ebx, Immediate(Smi::FromInt(2)));
+  __ Set(ebx, Immediate(2));
   __ jmp(&make_flat_ascii_string);

   __ bind(&longer_than_two);
   // Check if resulting string will be flat.
-  __ cmp(Operand(ebx), Immediate(Smi::FromInt(String::kMinNonFlatLength)));
+  __ cmp(ebx, String::kMinNonFlatLength);
   __ j(below, &string_add_flat_result);
+  // Handle exceptionally long strings in the runtime system.
+  ASSERT((String::kMaxLength & 0x80000000) == 0);
+  __ cmp(ebx, String::kMaxLength);
+  __ j(above, &string_add_runtime);

// If result is not supposed to be flat allocate a cons string object. If both
   // strings are ascii the result is an ascii cons string.
@@ -12299,7 +12292,6 @@
   __ AllocateAsciiConsString(ecx, edi, no_reg, &string_add_runtime);
   __ bind(&allocated);
   // Fill the fields of the cons string.
-  if (FLAG_debug_code) __ AbortIfNotSmi(ebx);
   __ mov(FieldOperand(ecx, ConsString::kLengthOffset), ebx);
   __ mov(FieldOperand(ecx, ConsString::kHashFieldOffset),
          Immediate(String::kEmptyHashField));
@@ -12316,7 +12308,7 @@
   // Handle creating a flat result. First check that both strings are not
   // external strings.
   // eax: first string
-  // ebx: length of resulting flat string as a smi
+  // ebx: length of resulting flat string
   // edx: second string
   __ bind(&string_add_flat_result);
   __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
@@ -12331,7 +12323,7 @@
   __ j(equal, &string_add_runtime);
   // Now check if both strings are ascii strings.
   // eax: first string
-  // ebx: length of resulting flat string as a smi
+  // ebx: length of resulting flat string
   // edx: second string
   Label non_ascii_string_add_flat_result;
   __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
@@ -12346,8 +12338,7 @@

   __ bind(&make_flat_ascii_string);
   // Both strings are ascii strings. As they are short they are both flat.
-  // ebx: length of resulting flat string as a smi
-  __ SmiUntag(ebx);
+  // ebx: length of resulting flat string
   __ AllocateAsciiString(eax, ebx, ecx, edx, edi, &string_add_runtime);
   // eax: result string
   __ mov(ecx, eax);
@@ -12356,7 +12347,6 @@
   // Load first argument and locate first character.
   __ mov(edx, Operand(esp, 2 * kPointerSize));
   __ mov(edi, FieldOperand(edx, String::kLengthOffset));
-  __ SmiUntag(edi);
__ add(Operand(edx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   // eax: result string
   // ecx: first character of result
@@ -12366,7 +12356,6 @@
   // Load second argument and locate first character.
   __ mov(edx, Operand(esp, 1 * kPointerSize));
   __ mov(edi, FieldOperand(edx, String::kLengthOffset));
-  __ SmiUntag(edi);
__ add(Operand(edx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   // eax: result string
   // ecx: next character of result
@@ -12378,7 +12367,7 @@

   // Handle creating a flat two byte result.
   // eax: first string - known to be two byte
-  // ebx: length of resulting flat string as a smi
+  // ebx: length of resulting flat string
   // edx: second string
   __ bind(&non_ascii_string_add_flat_result);
   __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
@@ -12387,7 +12376,6 @@
   __ j(not_zero, &string_add_runtime);
   // Both strings are two byte strings. As they are short they are both
   // flat.
-  __ SmiUntag(ebx);
   __ AllocateTwoByteString(eax, ebx, ecx, edx, edi, &string_add_runtime);
   // eax: result string
   __ mov(ecx, eax);
@@ -12397,7 +12385,6 @@
   // Load first argument and locate first character.
   __ mov(edx, Operand(esp, 2 * kPointerSize));
   __ mov(edi, FieldOperand(edx, String::kLengthOffset));
-  __ SmiUntag(edi);
   __ add(Operand(edx),
          Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
   // eax: result string
@@ -12408,7 +12395,6 @@
   // Load second argument and locate first character.
   __ mov(edx, Operand(esp, 1 * kPointerSize));
   __ mov(edi, FieldOperand(edx, String::kLengthOffset));
-  __ SmiUntag(edi);
__ add(Operand(edx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   // eax: result string
   // ecx: next character of result
@@ -12593,8 +12579,7 @@
     __ j(equal, not_found);

     // If length is not 2 the string is not a candidate.
-    __ cmp(FieldOperand(candidate, String::kLengthOffset),
-           Immediate(Smi::FromInt(2)));
+    __ cmp(FieldOperand(candidate, String::kLengthOffset), Immediate(2));
     __ j(not_equal, &next_probe[i]);

     // As we are out of registers save the mask on the stack and use that
@@ -12863,7 +12848,6 @@
   // Change index to run from -min_length to -1 by adding min_length
   // to string start. This means that loop ends when index reaches zero,
   // which doesn't need an additional compare.
-  __ SmiUntag(min_length);
   __ lea(left,
          FieldOperand(left,
                       min_length, times_1,
=======================================
--- /trunk/src/ia32/macro-assembler-ia32.cc     Fri Apr 30 05:51:36 2010
+++ /trunk/src/ia32/macro-assembler-ia32.cc     Mon May  3 02:56:08 2010
@@ -901,9 +901,7 @@
   // Set the map, length and hash field.
   mov(FieldOperand(result, HeapObject::kMapOffset),
       Immediate(Factory::string_map()));
-  mov(scratch1, length);
-  SmiTag(scratch1);
-  mov(FieldOperand(result, String::kLengthOffset), scratch1);
+  mov(FieldOperand(result, String::kLengthOffset), length);
   mov(FieldOperand(result, String::kHashFieldOffset),
       Immediate(String::kEmptyHashField));
 }
@@ -936,9 +934,7 @@
   // Set the map, length and hash field.
   mov(FieldOperand(result, HeapObject::kMapOffset),
       Immediate(Factory::ascii_string_map()));
-  mov(scratch1, length);
-  SmiTag(scratch1);
-  mov(FieldOperand(result, String::kLengthOffset), scratch1);
+  mov(FieldOperand(result, String::kLengthOffset), length);
   mov(FieldOperand(result, String::kHashFieldOffset),
       Immediate(String::kEmptyHashField));
 }
=======================================
--- /trunk/src/ia32/stub-cache-ia32.cc  Fri Apr 30 05:51:36 2010
+++ /trunk/src/ia32/stub-cache-ia32.cc  Mon May  3 02:56:08 2010
@@ -221,6 +221,7 @@

   // Load length from the string and convert to a smi.
   __ mov(eax, FieldOperand(receiver, String::kLengthOffset));
+  __ SmiTag(eax);
   __ ret(0);

   // Check if the object is a JSValue wrapper.
@@ -233,6 +234,7 @@
   __ mov(scratch2, FieldOperand(receiver, JSValue::kValueOffset));
   GenerateStringCheck(masm, scratch2, scratch1, miss, miss);
   __ mov(eax, FieldOperand(scratch2, String::kLengthOffset));
+  __ SmiTag(eax);
   __ ret(0);
 }

=======================================
--- /trunk/src/objects-inl.h    Fri Apr 30 05:51:36 2010
+++ /trunk/src/objects-inl.h    Mon May  3 02:56:08 2010
@@ -1651,7 +1651,7 @@
 INT_ACCESSORS(Array, length, kLengthOffset)


-SMI_ACCESSORS(String, length, kLengthOffset)
+INT_ACCESSORS(String, length, kLengthOffset)


 uint32_t String::hash_field() {
@@ -1773,12 +1773,14 @@


 int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
-  return SizeFor(length());
+  uint32_t length = READ_INT_FIELD(this, kLengthOffset);
+  return SizeFor(length);
 }


 int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
-  return SizeFor(length());
+  uint32_t length = READ_INT_FIELD(this, kLengthOffset);
+  return SizeFor(length);
 }


=======================================
--- /trunk/src/objects.h        Fri Apr 30 05:51:36 2010
+++ /trunk/src/objects.h        Mon May  3 02:56:08 2010
@@ -4063,7 +4063,7 @@

   // Layout description.
   static const int kLengthOffset = HeapObject::kHeaderSize;
-  static const int kHashFieldOffset = kLengthOffset + kPointerSize;
+  static const int kHashFieldOffset = kLengthOffset + kIntSize;
   static const int kSize = kHashFieldOffset + kIntSize;
   // Notice: kSize is not pointer-size aligned if pointers are 64-bit.

=======================================
--- /trunk/src/x64/codegen-x64.cc       Fri Apr 30 05:51:36 2010
+++ /trunk/src/x64/codegen-x64.cc       Mon May  3 02:56:08 2010
@@ -3922,6 +3922,9 @@
   // If the index is negative or non-smi trigger the slow case.
   __ JumpIfNotPositiveSmi(index.reg(), &slow_case);

+  // Untag the index.
+  __ SmiToInteger32(index.reg(), index.reg());
+
   __ bind(&try_again_with_new_string);
   // Fetch the instance type of the receiver into rcx.
   __ movq(rcx, FieldOperand(object.reg(), HeapObject::kMapOffset));
@@ -3931,7 +3934,7 @@
   __ j(not_zero, &slow_case);

   // Check for index out of range.
- __ SmiCompare(index.reg(), FieldOperand(object.reg(), String::kLengthOffset));
+  __ cmpl(index.reg(), FieldOperand(object.reg(), String::kLengthOffset));
   __ j(greater_equal, &slow_case);
   // Reload the instance type (into the temp register this time)..
   __ movq(temp.reg(), FieldOperand(object.reg(), HeapObject::kMapOffset));
@@ -3943,10 +3946,6 @@
   __ j(not_zero, &not_a_flat_string);
   // Check for 1-byte or 2-byte string.
   ASSERT_EQ(0, kTwoByteStringTag);
-
-  // Untag the index.
-  __ SmiToInteger32(index.reg(), index.reg());
-
   __ testb(temp.reg(), Immediate(kStringEncodingMask));
   __ j(not_zero, &ascii_string);

@@ -5617,8 +5616,8 @@
       // Test string equality and comparison.
       if (cc == equal) {
         Label comparison_done;
-        __ SmiCompare(FieldOperand(left_side.reg(), String::kLengthOffset),
-                Smi::FromInt(1));
+        __ cmpl(FieldOperand(left_side.reg(), String::kLengthOffset),
+                Immediate(1));
         __ j(not_equal, &comparison_done);
         uint8_t char_value =
             static_cast<uint8_t>(String::cast(*right_val)->Get(0));
@@ -5626,9 +5625,9 @@
                 Immediate(char_value));
         __ bind(&comparison_done);
       } else {
-        __ movq(temp2.reg(),
+        __ movl(temp2.reg(),
                 FieldOperand(left_side.reg(), String::kLengthOffset));
-        __ SmiSubConstant(temp2.reg(), temp2.reg(), Smi::FromInt(1));
+        __ subl(temp2.reg(), Immediate(1));
         Label comparison;
// If the length is 0 then the subtraction gave -1 which compares less
         // than any character.
@@ -5646,8 +5645,8 @@
         __ j(not_equal, &characters_were_different);
// If the first character is the same then the long string sorts after
         // the short one.
-        __ SmiCompare(FieldOperand(left_side.reg(), String::kLengthOffset),
-               Smi::FromInt(1));
+        __ cmpl(FieldOperand(left_side.reg(), String::kLengthOffset),
+               Immediate(1));
         __ bind(&characters_were_different);
       }
       temp2.Unuse();
@@ -7096,8 +7095,8 @@
   // String value => false iff empty.
   __ cmpq(rcx, Immediate(FIRST_NONSTRING_TYPE));
   __ j(above_equal, &not_string);
-  __ movq(rdx, FieldOperand(rax, String::kLengthOffset));
-  __ testq(rdx, rdx);
+  __ movl(rdx, FieldOperand(rax, String::kLengthOffset));
+  __ testl(rdx, rdx);
   __ j(zero, &false_result);
   __ jmp(&true_result);

@@ -7497,17 +7496,17 @@
   Condition is_string = masm->IsObjectStringType(rax, rbx, rbx);
   __ j(NegateCondition(is_string), &runtime);
   // Get the length of the string to rbx.
-  __ movq(rbx, FieldOperand(rax, String::kLengthOffset));
-
-  // rbx: Length of subject string as smi
+  __ movl(rbx, FieldOperand(rax, String::kLengthOffset));
+
+  // rbx: Length of subject string
   // rcx: RegExp data (FixedArray)
   // rdx: Number of capture registers
   // Check that the third argument is a positive smi less than the string
   // length. A negative value will be greater (unsigned comparison).
   __ movq(rax, Operand(rsp, kPreviousIndexOffset));
-  __ JumpIfNotSmi(rax, &runtime);
-  __ SmiCompare(rax, rbx);
-  __ j(above_equal, &runtime);
+  __ SmiToInteger32(rax, rax);
+  __ cmpl(rax, rbx);
+  __ j(above, &runtime);

   // rcx: RegExp data (FixedArray)
   // rdx: Number of capture registers
@@ -7660,14 +7659,12 @@
   // Argument 3: Start of string data
   Label setup_two_byte, setup_rest;
   __ testb(rdi, rdi);
-  __ movq(rdi, FieldOperand(rax, String::kLengthOffset));
+  __ movl(rdi, FieldOperand(rax, String::kLengthOffset));
   __ j(zero, &setup_two_byte);
-  __ SmiToInteger32(rdi, rdi);
__ lea(arg4, FieldOperand(rax, rdi, times_1, SeqAsciiString::kHeaderSize)); __ lea(arg3, FieldOperand(rax, rbx, times_1, SeqAsciiString::kHeaderSize));
   __ jmp(&setup_rest);
   __ bind(&setup_two_byte);
-  __ SmiToInteger32(rdi, rdi);
__ lea(arg4, FieldOperand(rax, rdi, times_2, SeqTwoByteString::kHeaderSize)); __ lea(arg3, FieldOperand(rax, rbx, times_2, SeqTwoByteString::kHeaderSize));

@@ -9827,15 +9824,15 @@
   // rdx: second string
// Check if either of the strings are empty. In that case return the other.
   Label second_not_zero_length, both_not_zero_length;
-  __ movq(rcx, FieldOperand(rdx, String::kLengthOffset));
-  __ SmiTest(rcx);
+  __ movl(rcx, FieldOperand(rdx, String::kLengthOffset));
+  __ testl(rcx, rcx);
   __ j(not_zero, &second_not_zero_length);
// Second string is empty, result is first string which is already in rax.
   __ IncrementCounter(&Counters::string_add_native, 1);
   __ ret(2 * kPointerSize);
   __ bind(&second_not_zero_length);
-  __ movq(rbx, FieldOperand(rax, String::kLengthOffset));
-  __ SmiTest(rbx);
+  __ movl(rbx, FieldOperand(rax, String::kLengthOffset));
+  __ testl(rbx, rbx);
   __ j(not_zero, &both_not_zero_length);
   // First string is empty, result is second string which is in rdx.
   __ movq(rax, rdx);
@@ -9863,11 +9860,10 @@
   __ movzxbl(r9, FieldOperand(r9, Map::kInstanceTypeOffset));

   // Look at the length of the result of adding the two strings.
-  ASSERT(String::kMaxLength <= Smi::kMaxValue / 2);
-  __ SmiAdd(rbx, rbx, rcx, NULL);
+  __ addl(rbx, rcx);
   // Use the runtime system when adding two one character strings, as it
   // contains optimizations for this specific case using the symbol table.
-  __ SmiCompare(rbx, Smi::FromInt(2));
+  __ cmpl(rbx, Immediate(2));
   __ j(not_equal, &longer_than_two);

   // Check that both strings are non-external ascii strings.
@@ -9892,11 +9888,11 @@

   __ bind(&longer_than_two);
   // Check if resulting string will be flat.
-  __ SmiCompare(rbx, Smi::FromInt(String::kMinNonFlatLength));
+  __ cmpl(rbx, Immediate(String::kMinNonFlatLength));
   __ j(below, &string_add_flat_result);
   // Handle exceptionally long strings in the runtime system.
   ASSERT((String::kMaxLength & 0x80000000) == 0);
-  __ SmiCompare(rbx, Smi::FromInt(String::kMaxLength));
+  __ cmpl(rbx, Immediate(String::kMaxLength));
   __ j(above, &string_add_runtime);

// If result is not supposed to be flat, allocate a cons string object. If
@@ -9916,7 +9912,7 @@
   __ AllocateAsciiConsString(rcx, rdi, no_reg, &string_add_runtime);
   __ bind(&allocated);
   // Fill the fields of the cons string.
-  __ movq(FieldOperand(rcx, ConsString::kLengthOffset), rbx);
+  __ movl(FieldOperand(rcx, ConsString::kLengthOffset), rbx);
   __ movl(FieldOperand(rcx, ConsString::kHashFieldOffset),
           Immediate(String::kEmptyHashField));
   __ movq(FieldOperand(rcx, ConsString::kFirstOffset), rax);
@@ -9932,12 +9928,11 @@
   // Handle creating a flat result. First check that both strings are not
   // external strings.
   // rax: first string
-  // ebx: length of resulting flat string as smi
+  // ebx: length of resulting flat string
   // rdx: second string
   // r8: instance type of first string
   // r9: instance type of first string
   __ bind(&string_add_flat_result);
-  __ SmiToInteger32(rbx, rbx);
   __ movl(rcx, r8);
   __ and_(rcx, Immediate(kStringRepresentationMask));
   __ cmpl(rcx, Immediate(kExternalStringTag));
@@ -9967,8 +9962,7 @@
   // Locate first character of result.
   __ addq(rcx, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   // Locate first character of first argument
-  __ movq(rdi, FieldOperand(rax, String::kLengthOffset));
-  __ SmiToInteger32(rdi, rdi);
+  __ movl(rdi, FieldOperand(rax, String::kLengthOffset));
   __ addq(rax, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   // rax: first char of first argument
   // rbx: result string
@@ -9977,8 +9971,7 @@
   // rdi: length of first argument
   GenerateCopyCharacters(masm, rcx, rax, rdi, true);
   // Locate first character of second argument.
-  __ movq(rdi, FieldOperand(rdx, String::kLengthOffset));
-  __ SmiToInteger32(rdi, rdi);
+  __ movl(rdi, FieldOperand(rdx, String::kLengthOffset));
   __ addq(rdx, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   // rbx: result string
   // rcx: next character of result
@@ -10006,8 +9999,7 @@
   // Locate first character of result.
   __ addq(rcx, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
   // Locate first character of first argument.
-  __ movq(rdi, FieldOperand(rax, String::kLengthOffset));
-  __ SmiToInteger32(rdi, rdi);
+  __ movl(rdi, FieldOperand(rax, String::kLengthOffset));
   __ addq(rax, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
   // rax: first char of first argument
   // rbx: result string
@@ -10016,8 +10008,7 @@
   // rdi: length of first argument
   GenerateCopyCharacters(masm, rcx, rax, rdi, false);
   // Locate first character of second argument.
-  __ movq(rdi, FieldOperand(rdx, String::kLengthOffset));
-  __ SmiToInteger32(rdi, rdi);
+  __ movl(rdi, FieldOperand(rdx, String::kLengthOffset));
   __ addq(rdx, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
   // rbx: result string
   // rcx: next character of result
@@ -10199,8 +10190,7 @@
     __ j(equal, not_found);

     // If length is not 2 the string is not a candidate.
-    __ SmiCompare(FieldOperand(candidate, String::kLengthOffset),
-                  Smi::FromInt(2));
+    __ cmpl(FieldOperand(candidate, String::kLengthOffset), Immediate(2));
     __ j(not_equal, &next_probe[i]);

     // We use kScratchRegister as a temporary register in assumption that
@@ -10444,12 +10434,9 @@
   ASSERT(String::kMaxLength < 0x7fffffff);

   // Find minimum length and length difference.
-  __ movq(scratch1, FieldOperand(left, String::kLengthOffset));
-  __ movq(scratch4, scratch1);
-  __ SmiSub(scratch4,
-            scratch4,
-            FieldOperand(right, String::kLengthOffset),
-            NULL);
+  __ movl(scratch1, FieldOperand(left, String::kLengthOffset));
+  __ movl(scratch4, scratch1);
+  __ subl(scratch4, FieldOperand(right, String::kLengthOffset));
   // Register scratch4 now holds left.length - right.length.
   const Register length_difference = scratch4;
   Label left_shorter;
@@ -10457,18 +10444,16 @@
   // The right string isn't longer that the left one.
// Get the right string's length by subtracting the (non-negative) difference
   // from the left string's length.
-  __ SmiSub(scratch1, scratch1, length_difference, NULL);
+  __ subl(scratch1, length_difference);
   __ bind(&left_shorter);
   // Register scratch1 now holds Min(left.length, right.length).
   const Register min_length = scratch1;

   Label compare_lengths;
   // If min-length is zero, go directly to comparing lengths.
-  __ SmiTest(min_length);
+  __ testl(min_length, min_length);
   __ j(zero, &compare_lengths);

-  __ SmiToInteger32(min_length, min_length);
-
   // Registers scratch2 and scratch3 are free.
   Label result_not_equal;
   Label loop;
@@ -10499,7 +10484,7 @@
   // Completed loop without finding different characters.
   // Compare lengths (precomputed).
   __ bind(&compare_lengths);
-  __ SmiTest(length_difference);
+  __ testl(length_difference, length_difference);
   __ j(not_zero, &result_not_equal);

   // Result is EQUAL.
=======================================
--- /trunk/src/x64/macro-assembler-x64.cc       Fri Apr 30 05:51:36 2010
+++ /trunk/src/x64/macro-assembler-x64.cc       Mon May  3 02:56:08 2010
@@ -597,11 +597,6 @@
     cmpq(dst, kScratchRegister);
   }
 }
-
-
-void MacroAssembler::SmiCompare(Register  dst, const Operand& src) {
-  cmpq(dst, src);
-}


 void MacroAssembler::SmiCompare(const Operand& dst, Register src) {
@@ -739,17 +734,7 @@
                             Register src2,
                             Label* on_not_smi_result) {
   ASSERT(!dst.is(src2));
-  if (on_not_smi_result == NULL) {
-    // No overflow checking. Use only when it's known that
-    // overflowing is impossible.
-    if (dst.is(src1)) {
-      addq(dst, src2);
-    } else {
-      movq(dst, src1);
-      addq(dst, src2);
-    }
-    Assert(no_overflow, "Smi addition onverflow");
-  } else if (dst.is(src1)) {
+  if (dst.is(src1)) {
     addq(dst, src2);
     Label smi_result;
     j(no_overflow, &smi_result);
@@ -795,36 +780,6 @@
   }
 }

-
-void MacroAssembler::SmiSub(Register dst,
-                            Register src1,
-                            Operand const& src2,
-                            Label* on_not_smi_result) {
-  ASSERT(!dst.is(src2));
-  if (on_not_smi_result == NULL) {
-    // No overflow checking. Use only when it's known that
-    // overflowing is impossible (e.g., subtracting two positive smis).
-    if (dst.is(src1)) {
-      subq(dst, src2);
-    } else {
-      movq(dst, src1);
-      subq(dst, src2);
-    }
-    Assert(no_overflow, "Smi substraction onverflow");
-  } else if (dst.is(src1)) {
-    subq(dst, src2);
-    Label smi_result;
-    j(no_overflow, &smi_result);
-    // Restore src1.
-    addq(src1, src2);
-    jmp(on_not_smi_result);
-    bind(&smi_result);
-  } else {
-    movq(dst, src1);
-    subq(dst, src2);
-    j(overflow, on_not_smi_result);
-  }
-}

 void MacroAssembler::SmiMul(Register dst,
                             Register src1,
@@ -2549,16 +2504,11 @@
                                            Label* gc_required) {
// Calculate the number of bytes needed for the characters in the string while
   // observing object alignment.
-  const int kHeaderAlignment = SeqTwoByteString::kHeaderSize &
-                               kObjectAlignmentMask;
+  ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
   ASSERT(kShortSize == 2);
   // scratch1 = length * 2 + kObjectAlignmentMask.
-  lea(scratch1, Operand(length, length, times_1, kObjectAlignmentMask +
-                kHeaderAlignment));
+  lea(scratch1, Operand(length, length, times_1, kObjectAlignmentMask));
   and_(scratch1, Immediate(~kObjectAlignmentMask));
-  if (kHeaderAlignment > 0) {
-    subq(scratch1, Immediate(kHeaderAlignment));
-  }

   // Allocate two byte string in new space.
   AllocateInNewSpace(SeqTwoByteString::kHeaderSize,
@@ -2573,8 +2523,7 @@
   // Set the map, length and hash field.
   LoadRoot(kScratchRegister, Heap::kStringMapRootIndex);
   movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
-  Integer32ToSmi(scratch1, length);
-  movq(FieldOperand(result, String::kLengthOffset), scratch1);
+  movl(FieldOperand(result, String::kLengthOffset), length);
   movl(FieldOperand(result, String::kHashFieldOffset),
        Immediate(String::kEmptyHashField));
 }
@@ -2588,15 +2537,11 @@
                                          Label* gc_required) {
// Calculate the number of bytes needed for the characters in the string while
   // observing object alignment.
-  const int kHeaderAlignment = SeqAsciiString::kHeaderSize &
-                               kObjectAlignmentMask;
+  ASSERT((SeqAsciiString::kHeaderSize & kObjectAlignmentMask) == 0);
   movl(scratch1, length);
   ASSERT(kCharSize == 1);
-  addq(scratch1, Immediate(kObjectAlignmentMask + kHeaderAlignment));
+  addq(scratch1, Immediate(kObjectAlignmentMask));
   and_(scratch1, Immediate(~kObjectAlignmentMask));
-  if (kHeaderAlignment > 0) {
-    subq(scratch1, Immediate(kHeaderAlignment));
-  }

   // Allocate ascii string in new space.
   AllocateInNewSpace(SeqAsciiString::kHeaderSize,
@@ -2611,8 +2556,7 @@
   // Set the map, length and hash field.
   LoadRoot(kScratchRegister, Heap::kAsciiStringMapRootIndex);
   movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
-  Integer32ToSmi(scratch1, length);
-  movq(FieldOperand(result, String::kLengthOffset), scratch1);
+  movl(FieldOperand(result, String::kLengthOffset), length);
   movl(FieldOperand(result, String::kHashFieldOffset),
        Immediate(String::kEmptyHashField));
 }
=======================================
--- /trunk/src/x64/macro-assembler-x64.h        Fri Apr 30 05:51:36 2010
+++ /trunk/src/x64/macro-assembler-x64.h        Mon May  3 02:56:08 2010
@@ -197,7 +197,6 @@
   // Simple comparison of smis.
   void SmiCompare(Register dst, Register src);
   void SmiCompare(Register dst, Smi* src);
-  void SmiCompare(Register dst, const Operand& src);
   void SmiCompare(const Operand& dst, Register src);
   void SmiCompare(const Operand& dst, Smi* src);
   // Sets sign and zero flags depending on value of smi in register.
@@ -288,8 +287,7 @@
                       Label* on_not_smi_result);

   // Subtract an integer constant from a tagged smi, giving a tagged smi as
-  // result. No testing on the result is done. Sets the N and Z flags
-  // based on the value of the resulting integer.
+  // result. No testing on the result is done.
   void SmiSubConstant(Register dst, Register src, Smi* constant);

   // Subtract an integer constant from a tagged smi, giving a tagged smi as
@@ -321,11 +319,6 @@
               Register src2,
               Label* on_not_smi_result);

-  void SmiSub(Register dst,
-              Register src1,
-              Operand const& src2,
-              Label* on_not_smi_result);
-
   // Multiplies smi values and return the result as a smi,
   // if possible.
   // If dst is src1, then src1 will be destroyed, even if
=======================================
--- /trunk/src/x64/stub-cache-x64.cc    Fri Apr 30 05:51:36 2010
+++ /trunk/src/x64/stub-cache-x64.cc    Mon May  3 02:56:08 2010
@@ -327,7 +327,8 @@
   GenerateStringCheck(masm, receiver, scratch1, miss, &check_wrapper);

   // Load length directly from the string.
-  __ movq(rax, FieldOperand(receiver, String::kLengthOffset));
+  __ movl(rax, FieldOperand(receiver, String::kLengthOffset));
+  __ Integer32ToSmi(rax, rax);
   __ ret(0);

   // Check if the object is a JSValue wrapper.
@@ -339,7 +340,8 @@
   // directly if it is.
   __ movq(scratch2, FieldOperand(receiver, JSValue::kValueOffset));
   GenerateStringCheck(masm, scratch2, scratch1, miss, miss);
-  __ movq(rax, FieldOperand(scratch2, String::kLengthOffset));
+  __ movl(rax, FieldOperand(scratch2, String::kLengthOffset));
+  __ Integer32ToSmi(rax, rax);
   __ ret(0);
 }

=======================================
--- /trunk/test/cctest/test-serialize.cc        Fri Apr 30 05:51:36 2010
+++ /trunk/test/cctest/test-serialize.cc        Mon May  3 02:56:08 2010
@@ -573,8 +573,7 @@
         FixedArray::kHeaderSize + kSmallFixedArrayLength * kPointerSize;
     const int kSmallStringLength = 16;
     const int kSmallStringSize =
-        (SeqAsciiString::kHeaderSize + kSmallStringLength +
-        kObjectAlignmentMask) & ~kObjectAlignmentMask;
+        SeqAsciiString::kHeaderSize + kSmallStringLength;
     const int kMapSize = Map::kSize;

     Object* new_last = NULL;

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to