Revision: 4813
Author: [email protected]
Date: Mon Jun  7 06:16:05 2010
Log: Revert change 4812 due to performance problems. This was a change in string addition on ia32.
Review URL: http://codereview.chromium.org/2706001
http://code.google.com/p/v8/source/detail?r=4813

Modified:
 /branches/bleeding_edge/src/ia32/codegen-ia32.cc

=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Mon Jun 7 05:15:10 2010 +++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Mon Jun 7 06:16:05 2010
@@ -11316,57 +11316,58 @@

   // ecx: RegExp data (FixedArray)
   // Check the representation and encoding of the subject string.
-  Label seq_ascii_string, seq_two_byte_string, check_code;
+  Label seq_string, seq_two_byte_string, check_code;
+  const int kStringRepresentationEncodingMask =
+      kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
   __ mov(eax, Operand(esp, kSubjectOffset));
   __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
   __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
-  // First check for flat two-byte string.
-  __ test_b(Operand(ebx),
- kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask);
-  ASSERT_EQ(0, kStringTag | kSeqStringTag | kTwoByteStringTag);
-  __ j(zero, &seq_two_byte_string);
-  // Any other flat string must be a flat ascii string.
-  __ test_b(Operand(ebx), kIsNotStringMask | kStringRepresentationMask);
-  __ j(zero, &seq_ascii_string);
+  __ and_(ebx, kStringRepresentationEncodingMask);
+  // First check for sequential string.
+  ASSERT_EQ(0, kStringTag);
+  ASSERT_EQ(0, kSeqStringTag);
+  __ test(Operand(ebx),
+          Immediate(kIsNotStringMask | kStringRepresentationMask));
+  __ j(zero, &seq_string);

   // Check for flat cons string.
-  // If this is a string, and not an external string, it is a cons string.
   // A flat cons string is a cons string where the second part is the empty
// string. In that case the subject string is just the first part of the cons // string. Also in this case the first part of the cons string is known to be
   // a sequential string or an external string.
-  ASSERT(kExternalStringTag !=0);
-  ASSERT_EQ(0, kConsStringTag & kExternalStringTag);
-  __ test_b(Operand(ebx), kIsNotStringMask | kExternalStringTag);
-  __ j(not_zero, &runtime);
-  // String is a cons string.
-  __ cmp(FieldOperand(eax, ConsString::kSecondOffset),
-         Factory::empty_string());
+  __ and_(ebx, kStringRepresentationMask);
+  __ cmp(ebx, kConsStringTag);
+  __ j(not_equal, &runtime);
+  __ mov(edx, FieldOperand(eax, ConsString::kSecondOffset));
+  __ cmp(Operand(edx), Factory::empty_string());
   __ j(not_equal, &runtime);
   __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset));
   __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
-  // String is a cons string with empty second part.
-  // eax: first part of cons string.
-  // ebx: map of first part of cons string.
-  // Is first part a flat two byte string?
-  __ test_b(FieldOperand(ebx, Map::kInstanceTypeOffset),
-            kStringRepresentationMask | kStringEncodingMask);
-  ASSERT_EQ(0, kSeqStringTag | kTwoByteStringTag);
-  __ j(zero, &seq_two_byte_string);
-  // Any other flat string must be ascii.
-  __ test_b(FieldOperand(ebx, Map::kInstanceTypeOffset),
-            kStringRepresentationMask);
+  __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
+  ASSERT_EQ(0, kSeqStringTag);
+  __ test(ebx, Immediate(kStringRepresentationMask));
   __ j(not_zero, &runtime);
-
-  __ bind(&seq_ascii_string);
-  // eax: subject string (flat ascii)
+  __ and_(ebx, kStringRepresentationEncodingMask);
+
+  __ bind(&seq_string);
+  // eax: subject string (sequential either ascii to two byte)
+  // ebx: suject string type & kStringRepresentationEncodingMask
   // ecx: RegExp data (FixedArray)
+ // Check that the irregexp code has been generated for an ascii string. If + // it has, the field contains a code object otherwise it contains the hole. + const int kSeqTwoByteString = kStringTag | kSeqStringTag | kTwoByteStringTag;
+  __ cmp(ebx, kSeqTwoByteString);
+  __ j(equal, &seq_two_byte_string);
+  if (FLAG_debug_code) {
+    __ cmp(ebx, kStringTag | kSeqStringTag | kAsciiStringTag);
+    __ Check(equal, "Expected sequential ascii string");
+  }
   __ mov(edx, FieldOperand(ecx, JSRegExp::kDataAsciiCodeOffset));
   __ Set(edi, Immediate(1));  // Type is ascii.
   __ jmp(&check_code);

   __ bind(&seq_two_byte_string);
-  // eax: subject string (flat two byte)
+  // eax: subject string
   // ecx: RegExp data (FixedArray)
   __ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset));
   __ Set(edi, Immediate(0));  // Type is two byte.
@@ -12772,17 +12773,16 @@

   // Make sure that both arguments are strings if not known in advance.
   if (string_check_) {
-    __ mov(ecx, eax);
-    __ and_(Operand(ecx), edx);
-    __ test(ecx, Immediate(kSmiTagMask));
+    __ test(eax, Immediate(kSmiTagMask));
     __ j(zero, &string_add_runtime);
-    __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
-    __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceTypeOffset));
-    __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
-    __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
-    __ or_(Operand(ecx), ebx);
-    __ test_b(Operand(ecx), kIsNotStringMask);
-    __ j(not_zero, &string_add_runtime);
+    __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ebx);
+    __ j(above_equal, &string_add_runtime);
+
+    // First argument is a a string, test second.
+    __ test(edx, Immediate(kSmiTagMask));
+    __ j(zero, &string_add_runtime);
+    __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, ebx);
+    __ j(above_equal, &string_add_runtime);
   }

   // Both arguments are strings.
@@ -12813,8 +12813,7 @@
   // ecx: length of second string as a smi
   // edx: second string
   // Look at the length of the result of adding the two strings.
-  Label make_two_character_string, longer_than_two,
-      make_flat_string, make_flat_ascii_string, make_flat_non_ascii_string;
+  Label string_add_flat_result, longer_than_two;
   __ bind(&both_not_zero_length);
   __ add(ebx, Operand(ecx));
   ASSERT(Smi::kMaxValue == String::kMaxLength);
@@ -12835,6 +12834,7 @@

   // Try to lookup two character string in symbol table. If it is not found
   // just allocate a new one.
+  Label make_two_character_string, make_flat_ascii_string;
   StringHelper::GenerateTwoCharacterSymbolTableProbe(
       masm, ebx, ecx, eax, edx, edi, &make_two_character_string);
   __ IncrementCounter(&Counters::string_add_native, 1);
@@ -12847,7 +12847,7 @@
   __ bind(&longer_than_two);
   // Check if resulting string will be flat.
   __ cmp(Operand(ebx), Immediate(Smi::FromInt(String::kMinNonFlatLength)));
-  __ j(below, &make_flat_string);
+  __ j(below, &string_add_flat_result);

// 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.
@@ -12878,38 +12878,37 @@
   __ AllocateConsString(ecx, edi, no_reg, &string_add_runtime);
   __ jmp(&allocated);

-  // Handle creating a flat result. Branch to runtime if either string
-  // is external or if they are not both ascii or both two-byte.
-  // Otherwise branch to ascii case or two-byte case.
+  // 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
   // edx: second string
-  __ bind(&make_flat_string);
+  __ bind(&string_add_flat_result);
   __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
-  __ movzx_b(edi, FieldOperand(ecx, Map::kInstanceTypeOffset));
+  __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
+  __ and_(ecx, kStringRepresentationMask);
+  __ cmp(ecx, kExternalStringTag);
+  __ j(equal, &string_add_runtime);
   __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
   __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
-  __ or_(ecx, Operand(edi));
-  ASSERT(kExternalStringTag !=0);
-  ASSERT_EQ(0, kConsStringTag & kExternalStringTag);
-  ASSERT_EQ(0, kSeqStringTag & kExternalStringTag);
-  ASSERT_EQ(0, kTwoByteStringTag);
-  __ test_b(Operand(ecx), kExternalStringTag | kStringEncodingMask);
- __ j(zero, &make_flat_non_ascii_string); // Neither is ascii or external.
-  __ test_b(Operand(ecx), kExternalStringTag);
-  __ j(not_zero, &string_add_runtime);  // One or both is external.
-
-  // At this point, neither is external, and at least one is ascii.
- // Check that both are ascii, by computing mask & first type & second type.
-  __ and_(edi, kStringEncodingMask);
+  __ and_(ecx, kStringRepresentationMask);
+  __ cmp(ecx, kExternalStringTag);
+  __ 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
+  // edx: second string
+  Label non_ascii_string_add_flat_result;
+  ASSERT(kStringEncodingMask == kAsciiStringTag);
+  __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
+  __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
+  __ j(zero, &non_ascii_string_add_flat_result);
   __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
-  __ test_b(edi, FieldOperand(ecx, Map::kInstanceTypeOffset));
-  ASSERT(kAsciiStringTag != 0);
+  __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
   __ j(zero, &string_add_runtime);

   __ bind(&make_flat_ascii_string);
-  // Both strings are ascii strings.  As they are short they are both flat.
-  // Create a flat ascii result.
+  // Both strings are ascii strings. As they are short they are both flat.
   // ebx: length of resulting flat string as a smi
   __ SmiUntag(ebx);
   __ AllocateAsciiString(eax, ebx, ecx, edx, edi, &string_add_runtime);
@@ -12940,10 +12939,14 @@
   __ IncrementCounter(&Counters::string_add_native, 1);
   __ ret(2 * kPointerSize);

- // Both strings are two-byte strings. As they are short they are both flat.
-  // Create a flat two byte result.
+  // Handle creating a flat two byte result.
+  // eax: first string - known to be two byte
   // ebx: length of resulting flat string as a smi
-  __ bind(&make_flat_non_ascii_string);
+  // edx: second string
+  __ bind(&non_ascii_string_add_flat_result);
+  __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
+  __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
+  __ j(not_zero, &string_add_runtime);
   // Both strings are two byte strings. As they are short they are both
   // flat.
   __ SmiUntag(ebx);

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

Reply via email to