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.

Reply via email to