Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(481)

Unified Diff: src/ia32/codegen-ia32.cc

Issue 2673001: Improve generated code for string encoding tests on ia32. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/codegen-ia32.cc
===================================================================
--- src/ia32/codegen-ia32.cc (revision 4803)
+++ src/ia32/codegen-ia32.cc (working copy)
@@ -11303,58 +11303,58 @@
// ecx: RegExp data (FixedArray)
// Check the representation and encoding of the subject string.
- Label seq_string, seq_two_byte_string, check_code;
- const int kStringRepresentationEncodingMask =
- kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
+ Label seq_ascii_string, seq_two_byte_string, check_code;
__ mov(eax, Operand(esp, kSubjectOffset));
__ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
__ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
- __ and_(ebx, kStringRepresentationEncodingMask);
- // First check for sequential string.
- ASSERT_EQ(0, kStringTag);
- ASSERT_EQ(0, kSeqStringTag);
+ // First check for flat two byte string.
Lasse Reichstein 2010/06/07 09:29:06 "two-byte"?
William Hesse 2010/06/07 12:17:28 Done.
+ __ and_(ebx,
Lasse Reichstein 2010/06/07 09:29:06 Would andb be enough? (Although I don't think it m
William Hesse 2010/06/07 12:17:28 All of these changed to test_b. On 2010/06/07 09:
+ 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(Operand(ebx),
Immediate(kIsNotStringMask | kStringRepresentationMask));
- __ j(zero, &seq_string);
+ __ j(zero, &seq_ascii_string);
// Check for flat 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.
- __ and_(ebx, kStringRepresentationMask);
- __ cmp(ebx, kConsStringTag);
- __ j(not_equal, &runtime);
+ ASSERT(kExternalStringTag !=0);
+ ASSERT_EQ(0, kConsStringTag & kExternalStringTag);
+ __ test(Operand(ebx),
+ Immediate(kIsNotStringMask | kExternalStringTag));
+ __ j(not_zero, &runtime);
+ // String is a cons string.
__ mov(edx, FieldOperand(eax, ConsString::kSecondOffset));
__ cmp(Operand(edx), Factory::empty_string());
Lasse Reichstein 2010/06/07 09:29:06 Can you do a direct compare to memory? I.e., cmp(
William Hesse 2010/06/07 12:17:28 Done.
__ j(not_equal, &runtime);
__ mov(eax, FieldOperand(eax, ConsString::kFirstOffset));
__ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
- __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
- ASSERT_EQ(0, kSeqStringTag);
- __ test(ebx, Immediate(kStringRepresentationMask));
+ // 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);
__ j(not_zero, &runtime);
- __ and_(ebx, kStringRepresentationEncodingMask);
- __ bind(&seq_string);
- // eax: subject string (sequential either ascii to two byte)
- // ebx: suject string type & kStringRepresentationEncodingMask
+ __ bind(&seq_ascii_string);
+ // eax: subject string (flat ascii)
// 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
+ // eax: subject string (flat two byte)
// ecx: RegExp data (FixedArray)
__ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset));
__ Set(edi, Immediate(0)); // Type is two byte.
@@ -12760,16 +12760,17 @@
// Make sure that both arguments are strings if not known in advance.
if (string_check_) {
- __ test(eax, Immediate(kSmiTagMask));
+ __ mov(ecx, eax);
+ __ and_(Operand(ecx), edx);
+ __ test(ecx, Immediate(kSmiTagMask));
__ j(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);
+ __ 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);
}
// Both arguments are strings.
@@ -12800,7 +12801,8 @@
// ecx: length of second string as a smi
// edx: second string
// Look at the length of the result of adding the two strings.
- Label string_add_flat_result, longer_than_two;
+ Label make_two_character_string, longer_than_two,
+ make_flat_string, make_flat_ascii_string, make_flat_non_ascii_string;
__ bind(&both_not_zero_length);
__ add(ebx, Operand(ecx));
ASSERT(Smi::kMaxValue == String::kMaxLength);
@@ -12821,7 +12823,6 @@
// 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);
@@ -12834,7 +12835,7 @@
__ bind(&longer_than_two);
// Check if resulting string will be flat.
__ cmp(Operand(ebx), Immediate(Smi::FromInt(String::kMinNonFlatLength)));
- __ j(below, &string_add_flat_result);
+ __ j(below, &make_flat_string);
// 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.
@@ -12865,37 +12866,36 @@
__ AllocateConsString(ecx, edi, no_reg, &string_add_runtime);
__ jmp(&allocated);
- // Handle creating a flat result. First check that both strings are not
- // external strings.
+ // 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.
// eax: first string
// ebx: length of resulting flat string as a smi
// edx: second string
- __ bind(&string_add_flat_result);
+ __ bind(&make_flat_string);
__ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
- __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
- __ and_(ecx, kStringRepresentationMask);
- __ cmp(ecx, kExternalStringTag);
- __ j(equal, &string_add_runtime);
+ __ movzx_b(edi, FieldOperand(ecx, Map::kInstanceTypeOffset));
__ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
__ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
- __ 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);
+ __ or_(ecx, Operand(edi));
+ ASSERT(kExternalStringTag !=0);
+ ASSERT((kConsStringTag & kExternalStringTag) == 0);
+ ASSERT((kSeqStringTag & kExternalStringTag) == 0);
+ ASSERT(kTwoByteStringTag == 0);
+ __ 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.
+ __ test(edi, Immediate(kStringEncodingMask));
Lasse Reichstein 2010/06/07 09:29:06 Could you do an xor (or just an and) here to check
William Hesse 2010/06/07 12:17:28 We can do a test with the other one and the mask,
+ __ j(zero, &string_add_runtime); // First string is two-byte, second ascii.
__ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
- __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
- __ j(zero, &string_add_runtime);
+ __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kStringEncodingMask);
+ __ j(zero, &string_add_runtime); // First string is ascii, second two-byte.
__ bind(&make_flat_ascii_string);
- // Both strings are ascii strings. As they are short they are both flat.
+ // Both strings are ascii strings. As they are short they are both flat.
+ // Create a flat ascii result.
// ebx: length of resulting flat string as a smi
__ SmiUntag(ebx);
__ AllocateAsciiString(eax, ebx, ecx, edx, edi, &string_add_runtime);
@@ -12926,14 +12926,10 @@
__ IncrementCounter(&Counters::string_add_native, 1);
__ ret(2 * kPointerSize);
- // Handle creating a flat two byte result.
- // eax: first string - known to be two byte
+ // Both strings are two-byte strings. As they are short they are both flat.
+ // Create a flat two byte result.
// ebx: length of resulting flat string as a smi
- // 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);
+ __ bind(&make_flat_non_ascii_string);
// Both strings are two byte strings. As they are short they are both
// flat.
__ SmiUntag(ebx);
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698