Reviewers: ulan, Benedikt Meurer,
Description:
ARM: Improve SeqStringSetChar implementation.
BUG=none
TEST=/test/mjsunit/lithium/SeqStringSetChar.js
Please review this at https://codereview.chromium.org/23890007/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+43, -35 lines):
M src/arm/lithium-arm.cc
M src/arm/lithium-codegen-arm.cc
A + test/mjsunit/lithium/SeqStringSetChar.js
Index: src/arm/lithium-arm.cc
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index
132e1a60e83b3d46c325ea33cfe01bc656e299ac..10326df8d6aa5131fe15de028239908b985770da
100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -1869,11 +1869,9 @@ LInstruction* LChunkBuilder::DoDateField(HDateField*
instr) {
LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
LOperand* string = UseRegister(instr->string());
- LOperand* index = UseRegister(instr->index());
- LOperand* value = UseTempRegister(instr->value());
- LSeqStringSetChar* result =
- new(zone()) LSeqStringSetChar(instr->encoding(), string, index,
value);
- return DefineAsRegister(result);
+ LOperand* index = UseRegisterOrConstant(instr->index());
+ LOperand* value = UseRegister(instr->value());
+ return new(zone()) LSeqStringSetChar(instr->encoding(), string, index,
value);
}
Index: src/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index
bc34cfafe08e08b3075ff8ae2b377c2393223255..6bcb5c937f6cd5dfb48c6b1f729851d66ce6bc3d
100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -1960,32 +1960,42 @@ void LCodeGen::DoDateField(LDateField* instr) {
void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
Register string = ToRegister(instr->string());
- Register index = ToRegister(instr->index());
+ LOperand* index_op = instr->index();
Register value = ToRegister(instr->value());
+ Register scratch = scratch0();
String::Encoding encoding = instr->encoding();
if (FLAG_debug_code) {
- __ ldr(ip, FieldMemOperand(string, HeapObject::kMapOffset));
- __ ldrb(ip, FieldMemOperand(ip, Map::kInstanceTypeOffset));
+ __ ldr(scratch, FieldMemOperand(string, HeapObject::kMapOffset));
+ __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
- __ and_(ip, ip, Operand(kStringRepresentationMask |
kStringEncodingMask));
+ __ and_(scratch, scratch,
+ Operand(kStringRepresentationMask | kStringEncodingMask));
static const uint32_t one_byte_seq_type = kSeqStringTag |
kOneByteStringTag;
static const uint32_t two_byte_seq_type = kSeqStringTag |
kTwoByteStringTag;
- __ cmp(ip, Operand(encoding == String::ONE_BYTE_ENCODING
- ? one_byte_seq_type : two_byte_seq_type));
+ __ cmp(scratch, Operand(encoding == String::ONE_BYTE_ENCODING
+ ? one_byte_seq_type : two_byte_seq_type));
__ Check(eq, kUnexpectedStringType);
}
- __ add(ip,
- string,
- Operand(SeqString::kHeaderSize - kHeapObjectTag));
- if (encoding == String::ONE_BYTE_ENCODING) {
- __ strb(value, MemOperand(ip, index));
+ if (index_op->IsConstantOperand()) {
+ int constant_index = ToInteger32(LConstantOperand::cast(index_op));
+ if (encoding == String::ONE_BYTE_ENCODING) {
+ __ strb(value,
+ FieldMemOperand(string, SeqString::kHeaderSize +
constant_index));
+ } else {
+ __ strh(value,
+ FieldMemOperand(string, SeqString::kHeaderSize + constant_index
* 2));
+ }
} else {
- // MemOperand with ip as the base register is not allowed for strh, so
- // we do the address calculation explicitly.
- __ add(ip, ip, Operand(index, LSL, 1));
- __ strh(value, MemOperand(ip));
+ Register index = ToRegister(index_op);
+ if (encoding == String::ONE_BYTE_ENCODING) {
+ __ add(scratch, string, Operand(index));
+ __ strb(value, FieldMemOperand(scratch, SeqString::kHeaderSize));
+ } else {
+ __ add(scratch, string, Operand(index, LSL, 1));
+ __ strh(value, FieldMemOperand(scratch, SeqString::kHeaderSize));
+ }
}
}
Index: test/mjsunit/lithium/SeqStringSetChar.js
diff --git a/test/mjsunit/array-non-smi-length.js
b/test/mjsunit/lithium/SeqStringSetChar.js
similarity index 72%
copy from test/mjsunit/array-non-smi-length.js
copy to test/mjsunit/lithium/SeqStringSetChar.js
index
23a25ee797bd68690ad2a7ce26a9135e23b486e2..3c890a84897f0014f79f07ef624daf8c3bf825a4
100644
--- a/test/mjsunit/array-non-smi-length.js
+++ b/test/mjsunit/lithium/SeqStringSetChar.js
@@ -27,20 +27,20 @@
// Flags: --allow-natives-syntax
-function TestNonSmiArrayLength() {
- function f(a) {
- return a.length+1;
- }
-
- var a = [];
- a.length = 0xFFFF;
- assertSame(0x10000, f(a));
- assertSame(0x10000, f(a));
-
- %OptimizeFunctionOnNextCall(f);
- a.length = 0xFFFFFFFF;
- assertSame(0x100000000, f(a));
+function MyStringFromCharCode(code, i) {
+ var one_byte = %NewString(3, true);
+ %_OneByteSeqStringSetChar(one_byte, 0, code);
+ %_OneByteSeqStringSetChar(one_byte, 1, code);
+ %_OneByteSeqStringSetChar(one_byte, i, code);
+ var two_byte = %NewString(3, false);
+ %_TwoByteSeqStringSetChar(two_byte, 0, code);
+ %_TwoByteSeqStringSetChar(two_byte, 1, code);
+ %_TwoByteSeqStringSetChar(two_byte, i, code);
+ return one_byte + two_byte;
}
-TestNonSmiArrayLength();
-
+MyStringFromCharCode(65, 2);
+var r1 = MyStringFromCharCode(65, 2);
+%OptimizeFunctionOnNextCall(MyStringFromCharCode);
+var r2 = MyStringFromCharCode(65, 2);
+assertEquals(r1, r2);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.