Make kAsciiDataHintTag have correct semantics for all both 1 and 2 byte string types. (issue 11360251)

1 view
Skip to first unread message

dca...@google.com

unread,
Nov 14, 2012, 11:08:32 AM11/14/12
to yan...@chromium.org, v8-...@googlegroups.com
Reviewers: Yang,

Message:
Okay, another attempt. I changed 1 instruction to 2 in the intel code-stubs
files only because I wasn't sure if I could better use that single
instruction
to shift 8 bits.

Description:
Make kAsciiDataHintTag have correct semantics for all both 1 and 2 byte
string
types.


BUG=


Please review this at https://codereview.chromium.org/11360251/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
M src/arm/code-stubs-arm.cc
M src/arm/macro-assembler-arm.cc
M src/ia32/code-stubs-ia32.cc
M src/ia32/full-codegen-ia32.cc
M src/ia32/macro-assembler-ia32.cc
M src/objects-inl.h
M src/objects.h
M src/x64/code-stubs-x64.cc
M src/x64/macro-assembler-x64.cc


Index: src/arm/code-stubs-arm.cc
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index
1e73a55871606f4ce7b2708b856ef6e2e9a3f9d8..5558c55122a7cf781c60cea1b9fabd7c085d7f99
100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -6498,11 +6498,6 @@ void StringAddStub::Generate(MacroAssembler* masm) {
__ tst(r4, Operand(kAsciiDataHintMask));
__ tst(r5, Operand(kAsciiDataHintMask), ne);
__ b(ne, &ascii_data);
- __ eor(r4, r4, Operand(r5));
- STATIC_ASSERT(kOneByteStringTag != 0 && kAsciiDataHintTag != 0);
- __ and_(r4, r4, Operand(kOneByteStringTag | kAsciiDataHintTag));
- __ cmp(r4, Operand(kOneByteStringTag | kAsciiDataHintTag));
- __ b(eq, &ascii_data);

// Allocate a two byte cons string.
__ AllocateTwoByteConsString(r7, r6, r4, r5, &call_runtime);
Index: src/arm/macro-assembler-arm.cc
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index
dcc7149e9cda1d9d016cc5172e331611e1756edb..4438026f2f029311d5ab8478c7bdf6e94cfa8d09
100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -3338,8 +3338,10 @@ void
MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialAscii(
Register scratch2,
Label* failure) {
int kFlatAsciiStringMask =
- kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask;
+ kIsNotStringMask | kStringEncodingMask | kAsciiDataHintMask |
+ kStringRepresentationMask;
int kFlatAsciiStringTag = ASCII_STRING_TYPE;
+ ASSERT_EQ(ASCII_STRING_TYPE, ASCII_STRING_TYPE & kFlatAsciiStringMask);
and_(scratch1, first, Operand(kFlatAsciiStringMask));
and_(scratch2, second, Operand(kFlatAsciiStringMask));
cmp(scratch1, Operand(kFlatAsciiStringTag));
@@ -3353,8 +3355,10 @@ void
MacroAssembler::JumpIfInstanceTypeIsNotSequentialAscii(Register type,
Register
scratch,
Label*
failure) {
int kFlatAsciiStringMask =
- kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask;
+ kIsNotStringMask | kStringEncodingMask | kAsciiDataHintMask |
+ kStringRepresentationMask;
int kFlatAsciiStringTag = ASCII_STRING_TYPE;
+ ASSERT_EQ(ASCII_STRING_TYPE, ASCII_STRING_TYPE & kFlatAsciiStringMask);
and_(scratch, type, Operand(kFlatAsciiStringMask));
cmp(scratch, Operand(kFlatAsciiStringTag));
b(ne, failure);
Index: src/ia32/code-stubs-ia32.cc
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index
7ea71e47eb059b1cf788c2970eddc211e00a5a02..fb8501039497a984572c1bf2894ce679f3fbbb20
100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -5748,13 +5748,6 @@ void StringAddStub::Generate(MacroAssembler* masm) {
// edi: second instance type.
__ test(ecx, Immediate(kAsciiDataHintMask));
__ j(not_zero, &ascii_data);
- __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
- __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
- __ xor_(edi, ecx);
- STATIC_ASSERT(kOneByteStringTag != 0 && kAsciiDataHintTag != 0);
- __ and_(edi, kOneByteStringTag | kAsciiDataHintTag);
- __ cmp(edi, kOneByteStringTag | kAsciiDataHintTag);
- __ j(equal, &ascii_data);
// Allocate a two byte cons string.
__ AllocateTwoByteConsString(ecx, edi, no_reg, &call_runtime);
__ jmp(&allocated);
Index: src/ia32/full-codegen-ia32.cc
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index
159c2cabcc928d6c36d8bfccfeb81738825a573d..23e597f6b4dd58fc8d2efd3978e3cd8c69c53c48
100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -3609,7 +3609,8 @@ void
FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
__ mov(scratch, FieldOperand(string, HeapObject::kMapOffset));
__ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
__ and_(scratch, Immediate(
- kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask));
+ kIsNotStringMask | kStringEncodingMask | kAsciiDataHintMask |
+ kStringRepresentationMask));
__ cmp(scratch, ASCII_STRING_TYPE);
__ j(not_equal, &bailout);

Index: src/ia32/macro-assembler-ia32.cc
diff --git a/src/ia32/macro-assembler-ia32.cc
b/src/ia32/macro-assembler-ia32.cc
index
26d0f92d262658654cb4e50063ce6d33e1468d0e..6d4bff61599f2c8e733fe4dd138d8751c9d6a51e
100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -2638,15 +2638,17 @@ void
MacroAssembler::JumpIfNotBothSequentialAsciiStrings(Register object1,
movzx_b(scratch2, FieldOperand(scratch2, Map::kInstanceTypeOffset));

// Check that both are flat ASCII strings.
- const int kFlatAsciiStringMask =
- kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
+ const int kFlatAsciiStringMask = kIsNotStringMask |
kStringRepresentationMask
+ | kStringEncodingMask | kAsciiDataHintTag;
const int kFlatAsciiStringTag = ASCII_STRING_TYPE;
// Interleave bits from both instance types and compare them in one
check.
- ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3));
+ ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 8));
+ ASSERT_EQ(ASCII_STRING_TYPE, ASCII_STRING_TYPE & kFlatAsciiStringMask);
and_(scratch1, kFlatAsciiStringMask);
and_(scratch2, kFlatAsciiStringMask);
- lea(scratch1, Operand(scratch1, scratch2, times_8, 0));
- cmp(scratch1, kFlatAsciiStringTag | (kFlatAsciiStringTag << 3));
+ shl(scratch1, 8);
+ or_(scratch1, scratch2);
+ cmp(scratch1, kFlatAsciiStringTag | (kFlatAsciiStringTag << 8));
j(not_equal, failure);
}

Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index
ab9ce1af127c07043a0909ec3908cb1b90a14696..32ca39eaea1c2a35bce33cf06c03565750f14356
100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -341,8 +341,7 @@ bool String::IsTwoByteRepresentationUnderneath() {

bool String::HasOnlyAsciiChars() {
uint32_t type = map()->instance_type();
- return (type & kStringEncodingMask) == kOneByteStringTag ||
- (type & kAsciiDataHintMask) == kAsciiDataHintTag;
+ return (type & kAsciiDataHintMask) == kAsciiDataHintTag;
}


Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index
3dc6188997bdead58671bc9982202033e64f5e38..2533c206b7f1b3a870f00f6c55c27636f1c670df
100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -530,39 +530,46 @@ const uint32_t kShortcutTypeTag = kConsStringTag;
enum InstanceType {
// String types.
SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kSeqStringTag,
- ASCII_SYMBOL_TYPE = kOneByteStringTag | kSymbolTag | kSeqStringTag,
+ ASCII_SYMBOL_TYPE = kOneByteStringTag | kAsciiDataHintTag | kSymbolTag |
+ kSeqStringTag,
CONS_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kConsStringTag,
- CONS_ASCII_SYMBOL_TYPE = kOneByteStringTag | kSymbolTag | kConsStringTag,
+ CONS_ASCII_SYMBOL_TYPE = kOneByteStringTag | kAsciiDataHintTag |
kSymbolTag |
+ kConsStringTag,
SHORT_EXTERNAL_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag |
kExternalStringTag |
kShortExternalStringTag,
SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE =
kTwoByteStringTag | kSymbolTag | kExternalStringTag |
kAsciiDataHintTag | kShortExternalStringTag,
- SHORT_EXTERNAL_ASCII_SYMBOL_TYPE = kOneByteStringTag |
kExternalStringTag |
- kSymbolTag | kShortExternalStringTag,
+ SHORT_EXTERNAL_ASCII_SYMBOL_TYPE = kOneByteStringTag | kAsciiDataHintTag
|
+ kExternalStringTag | kSymbolTag |
+ kShortExternalStringTag,
EXTERNAL_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag |
kExternalStringTag,
EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE =
kTwoByteStringTag | kSymbolTag | kExternalStringTag |
kAsciiDataHintTag,
EXTERNAL_ASCII_SYMBOL_TYPE =
- kOneByteStringTag | kSymbolTag | kExternalStringTag,
+ kOneByteStringTag | kAsciiDataHintTag | kSymbolTag |
kExternalStringTag,
STRING_TYPE = kTwoByteStringTag | kSeqStringTag,
- ASCII_STRING_TYPE = kOneByteStringTag | kSeqStringTag,
+ ASCII_STRING_TYPE = kOneByteStringTag | kAsciiDataHintTag |
kSeqStringTag,
CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag,
- CONS_ASCII_STRING_TYPE = kOneByteStringTag | kConsStringTag,
+ CONS_ASCII_STRING_TYPE =
+ kOneByteStringTag | kAsciiDataHintTag | kConsStringTag,
SLICED_STRING_TYPE = kTwoByteStringTag | kSlicedStringTag,
- SLICED_ASCII_STRING_TYPE = kOneByteStringTag | kSlicedStringTag,
+ SLICED_ASCII_STRING_TYPE =
+ kOneByteStringTag | kAsciiDataHintTag | kSlicedStringTag,
SHORT_EXTERNAL_STRING_TYPE =
kTwoByteStringTag | kExternalStringTag | kShortExternalStringTag,
SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE =
kTwoByteStringTag | kExternalStringTag |
kAsciiDataHintTag | kShortExternalStringTag,
SHORT_EXTERNAL_ASCII_STRING_TYPE =
- kOneByteStringTag | kExternalStringTag | kShortExternalStringTag,
+ kOneByteStringTag | kAsciiDataHintTag |
+ kExternalStringTag | kShortExternalStringTag,
EXTERNAL_STRING_TYPE = kTwoByteStringTag | kExternalStringTag,
EXTERNAL_STRING_WITH_ASCII_DATA_TYPE =
kTwoByteStringTag | kExternalStringTag | kAsciiDataHintTag,
// LAST_STRING_TYPE
- EXTERNAL_ASCII_STRING_TYPE = kOneByteStringTag | kExternalStringTag,
+ EXTERNAL_ASCII_STRING_TYPE =
+ kOneByteStringTag | kAsciiDataHintTag | kExternalStringTag,
PRIVATE_EXTERNAL_ASCII_STRING_TYPE = EXTERNAL_ASCII_STRING_TYPE,

// Objects allocated in their own spaces (never in new space).
Index: src/x64/code-stubs-x64.cc
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index
a8e52e99d306d0cedb44ab9f4ef74eedd10d85c0..9c9a266ac53cbef1eed6ac7a4dc238412ef9ffe9
100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -4765,11 +4765,6 @@ void StringAddStub::Generate(MacroAssembler* masm) {
// r9: second instance type.
__ testb(rcx, Immediate(kAsciiDataHintMask));
__ j(not_zero, &ascii_data);
- __ xor_(r8, r9);
- STATIC_ASSERT(kOneByteStringTag != 0 && kAsciiDataHintTag != 0);
- __ andb(r8, Immediate(kOneByteStringTag | kAsciiDataHintTag));
- __ cmpb(r8, Immediate(kOneByteStringTag | kAsciiDataHintTag));
- __ j(equal, &ascii_data);
// Allocate a two byte cons string.
__ AllocateTwoByteConsString(rcx, rdi, no_reg, &call_runtime);
__ jmp(&allocated);
Index: src/x64/macro-assembler-x64.cc
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index
962c2e8b45e0067e6b81c9601ca2d64b5c1fa5a8..3fea033fe0c128d2e291e286a001893299998125
100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -2201,16 +2201,19 @@ void
MacroAssembler::JumpIfNotBothSequentialAsciiStrings(
// Check that both are flat ASCII strings.
ASSERT(kNotStringTag != 0);
const int kFlatAsciiStringMask =
- kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
+ kIsNotStringMask | kStringEncodingMask | kAsciiDataHintMask |
+ kStringRepresentationMask;
const int kFlatAsciiStringTag = ASCII_STRING_TYPE;

andl(scratch1, Immediate(kFlatAsciiStringMask));
andl(scratch2, Immediate(kFlatAsciiStringMask));
// Interleave the bits to check both scratch1 and scratch2 in one test.
- ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3));
- lea(scratch1, Operand(scratch1, scratch2, times_8, 0));
+ ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 8));
+ ASSERT_EQ(ASCII_STRING_TYPE, ASCII_STRING_TYPE & kFlatAsciiStringMask);
+ shl(scratch1, Immediate(8));
+ orl(scratch1, scratch2);
cmpl(scratch1,
- Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 3)));
+ Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 8)));
j(not_equal, on_fail, near_jump);
}

@@ -2246,17 +2249,19 @@ void
MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialAscii(

// Check that both are flat ASCII strings.
ASSERT(kNotStringTag != 0);
- const int kFlatAsciiStringMask =
- kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
+ const int kFlatAsciiStringMask = kIsNotStringMask |
kStringRepresentationMask
+ | kStringEncodingMask | kAsciiDataHintTag;
const int kFlatAsciiStringTag = ASCII_STRING_TYPE;

andl(scratch1, Immediate(kFlatAsciiStringMask));
andl(scratch2, Immediate(kFlatAsciiStringMask));
// Interleave the bits to check both scratch1 and scratch2 in one test.
- ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3));
- lea(scratch1, Operand(scratch1, scratch2, times_8, 0));
+ ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 8));
+ ASSERT_EQ(ASCII_STRING_TYPE, ASCII_STRING_TYPE & kFlatAsciiStringMask);
+ shl(scratch1, Immediate(8));
+ orl(scratch1, scratch2);
cmpl(scratch1,
- Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 3)));
+ Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 8)));
j(not_equal, on_fail, near_jump);
}



yan...@chromium.org

unread,
Nov 15, 2012, 5:28:32 AM11/15/12
to dca...@google.com, v8-...@googlegroups.com
On 2012/11/14 16:08:32, dcarney wrote:
> Okay, another attempt. I changed 1 instruction to 2 in the intel
> code-stubs
> files only because I wasn't sure if I could better use that single
> instruction
> to shift 8 bits.

LGTM.

https://codereview.chromium.org/11360251/
Reply all
Reply to author
Forward
0 new messages