Commit 64250b81 authored by plind44@gmail.com's avatar plind44@gmail.com

MIPS: Improve implementation of HSeqStringSetChar.

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
parent 60067c9a
......@@ -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));
MemOperand operand = BuildSeqStringOperand(string, instr->index(), encoding);
if (encoding == String::ONE_BYTE_ENCODING) {
__ sb(value,
FieldMemOperand(string, SeqString::kHeaderSize + constant_index));
} else {
__ sh(value,
FieldMemOperand(string, SeqString::kHeaderSize + constant_index * 2));
}
} else {
Register index = ToRegister(index_op);
if (encoding == String::ONE_BYTE_ENCODING) {
__ Addu(scratch, string, Operand(index));
__ sb(value, FieldMemOperand(scratch, SeqString::kHeaderSize));
__ sb(value, operand);
} else {
__ sll(scratch, index, 1);
__ Addu(scratch, string, scratch);
__ sh(value, FieldMemOperand(scratch, SeqString::kHeaderSize));
}
__ sh(value, operand);
}
}
......
......@@ -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.
......
......@@ -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);
}
......
......@@ -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_;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment