MIPS: Improve implementation of HSeqStringSetChar.
authorplind44@gmail.com <plind44@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 6 Nov 2013 23:52:37 +0000 (23:52 +0000)
committerplind44@gmail.com <plind44@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 6 Nov 2013 23:52:37 +0000 (23:52 +0000)
Port r17521 (c51c75e)

Original commit message:
This improves the generated code for HSeqStringSetChar across
all platforms, taking advantage of constant operands whenever
possible. It also drops the unused DefineSameAsFirst constraint
for the register allocator on x64 and ia32, where it caused
unnecessary spills when the string operand was live across the
HSeqStringSetChar instruction.

A new GVN flag StringChars is introduced to express dependencies
between HSeqStringSetChar, HStringCharCodeAt and the upcoming
HSeqStringGetChar (the GVNFlags type is now 64bit in size).

Also improves the test case.

TEST=mjsunit/string-natives
BUG=
R=plind44@gmail.com

Review URL: https://codereview.chromium.org/61893003

Patch from Balazs Kilvady <kilvadyb@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17536 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/mips/lithium-codegen-mips.cc
src/mips/lithium-codegen-mips.h
src/mips/lithium-mips.cc
src/mips/lithium-mips.h

index 8fa397b..5d09a30 100644 (file)
@@ -1731,14 +1731,38 @@ void LCodeGen::DoDateField(LDateField* instr) {
 }
 
 
+MemOperand LCodeGen::BuildSeqStringOperand(Register string,
+                                           LOperand* index,
+                                           String::Encoding encoding) {
+  if (index->IsConstantOperand()) {
+    int offset = ToInteger32(LConstantOperand::cast(index));
+    if (encoding == String::TWO_BYTE_ENCODING) {
+      offset *= kUC16Size;
+    }
+    STATIC_ASSERT(kCharSize == 1);
+    return FieldMemOperand(string, SeqString::kHeaderSize + offset);
+  }
+  Register scratch = scratch0();
+  ASSERT(!scratch.is(string));
+  ASSERT(!scratch.is(ToRegister(index)));
+  if (encoding == String::ONE_BYTE_ENCODING) {
+    __ Addu(scratch, string, ToRegister(index));
+  } else {
+    STATIC_ASSERT(kUC16Size == 2);
+    __ sll(scratch, ToRegister(index), 1);
+    __ Addu(scratch, string, scratch);
+  }
+  return FieldMemOperand(scratch, SeqString::kHeaderSize);
+}
+
+
 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
+  String::Encoding encoding = instr->hydrogen()->encoding();
   Register string = ToRegister(instr->string());
-  LOperand* index_op = instr->index();
   Register value = ToRegister(instr->value());
-  Register scratch = scratch0();
-  String::Encoding encoding = instr->encoding();
 
   if (FLAG_debug_code) {
+    Register scratch = scratch0();
     __ lw(scratch, FieldMemOperand(string, HeapObject::kMapOffset));
     __ lbu(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
 
@@ -1751,25 +1775,11 @@ void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
     __ Check(eq, kUnexpectedStringType, at, Operand(zero_reg));
   }
 
-  if (index_op->IsConstantOperand()) {
-    int constant_index = ToInteger32(LConstantOperand::cast(index_op));
-    if (encoding == String::ONE_BYTE_ENCODING) {
-      __ sb(value,
-          FieldMemOperand(string, SeqString::kHeaderSize + constant_index));
-    } else {
-      __ sh(value,
-          FieldMemOperand(string, SeqString::kHeaderSize + constant_index * 2));
-    }
+  MemOperand operand = BuildSeqStringOperand(string, instr->index(), encoding);
+  if (encoding == String::ONE_BYTE_ENCODING) {
+    __ sb(value, operand);
   } else {
-    Register index = ToRegister(index_op);
-    if (encoding == String::ONE_BYTE_ENCODING) {
-      __ Addu(scratch, string, Operand(index));
-      __ sb(value, FieldMemOperand(scratch, SeqString::kHeaderSize));
-    } else {
-      __ sll(scratch, index, 1);
-      __ Addu(scratch, string, scratch);
-      __ sh(value, FieldMemOperand(scratch, SeqString::kHeaderSize));
-    }
+    __ sh(value, operand);
   }
 }
 
index d0909ae..f41adbf 100644 (file)
@@ -277,6 +277,10 @@ class LCodeGen: public LCodeGenBase {
   Register ToRegister(int index) const;
   DoubleRegister ToDoubleRegister(int index) const;
 
+  MemOperand BuildSeqStringOperand(Register string,
+                                   LOperand* index,
+                                   String::Encoding encoding);
+
   void EmitIntegerMathAbs(LMathAbs* instr);
 
   // Support for recording safepoint and position information.
index ba7346f..6f8d95e 100644 (file)
@@ -1808,7 +1808,7 @@ LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
   LOperand* string = UseRegister(instr->string());
   LOperand* index = UseRegisterOrConstant(instr->index());
   LOperand* value = UseRegister(instr->value());
-  return new(zone()) LSeqStringSetChar(instr->encoding(), string, index, value);
+  return new(zone()) LSeqStringSetChar(string, index, value);
 }
 
 
index 7254d83..9b4d111 100644 (file)
@@ -1342,25 +1342,20 @@ class LDateField V8_FINAL : public LTemplateInstruction<1, 1, 1> {
 
 class LSeqStringSetChar V8_FINAL : public LTemplateInstruction<1, 3, 0> {
  public:
-  LSeqStringSetChar(String::Encoding encoding,
-                    LOperand* string,
+  LSeqStringSetChar(LOperand* string,
                     LOperand* index,
-                    LOperand* value) : encoding_(encoding) {
+                    LOperand* value) {
     inputs_[0] = string;
     inputs_[1] = index;
     inputs_[2] = value;
   }
 
-  String::Encoding encoding() { return encoding_; }
   LOperand* string() { return inputs_[0]; }
   LOperand* index() { return inputs_[1]; }
   LOperand* value() { return inputs_[2]; }
 
   DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char")
   DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar)
-
- private:
-  String::Encoding encoding_;
 };