Revision: 17521
Author: [email protected]
Date: Wed Nov 6 13:09:22 2013 UTC
Log: Improve implementation of HSeqStringSetChar.
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
[email protected], [email protected]
Review URL: https://codereview.chromium.org/57383004
http://code.google.com/p/v8/source/detail?r=17521
Modified:
/branches/bleeding_edge/src/arm/lithium-arm.cc
/branches/bleeding_edge/src/arm/lithium-arm.h
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/arm/lithium-codegen-arm.h
/branches/bleeding_edge/src/hydrogen-instructions.h
/branches/bleeding_edge/src/ia32/assembler-ia32.cc
/branches/bleeding_edge/src/ia32/assembler-ia32.h
/branches/bleeding_edge/src/ia32/disasm-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h
/branches/bleeding_edge/src/ia32/lithium-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-ia32.h
/branches/bleeding_edge/src/x64/assembler-x64.cc
/branches/bleeding_edge/src/x64/assembler-x64.h
/branches/bleeding_edge/src/x64/disasm-x64.cc
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
/branches/bleeding_edge/src/x64/lithium-codegen-x64.h
/branches/bleeding_edge/src/x64/lithium-x64.cc
/branches/bleeding_edge/src/x64/lithium-x64.h
/branches/bleeding_edge/test/mjsunit/string-natives.js
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Thu Oct 31 10:18:51 2013
UTC
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc Wed Nov 6 13:09:22 2013
UTC
@@ -1888,7 +1888,7 @@
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);
}
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h Thu Oct 31 10:18:51 2013
UTC
+++ /branches/bleeding_edge/src/arm/lithium-arm.h Wed Nov 6 13:09:22 2013
UTC
@@ -1362,25 +1362,20 @@
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_;
};
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Thu Oct 31
10:18:51 2013 UTC
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Nov 6
13:09:22 2013 UTC
@@ -1922,16 +1922,39 @@
__ bind(&done);
}
}
+
+
+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) {
+ __ add(scratch, string, Operand(ToRegister(index)));
+ } else {
+ STATIC_ASSERT(kUC16Size == 2);
+ __ add(scratch, string, Operand(ToRegister(index), LSL, 1));
+ }
+ 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();
__ ldr(scratch, FieldMemOperand(string, HeapObject::kMapOffset));
__ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
@@ -1944,24 +1967,11 @@
__ Check(eq, kUnexpectedStringType);
}
- 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));
- }
+ MemOperand operand = BuildSeqStringOperand(string, instr->index(),
encoding);
+ if (encoding == String::ONE_BYTE_ENCODING) {
+ __ strb(value, operand);
} else {
- 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));
- }
+ __ strh(value, operand);
}
}
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Thu Oct 24
12:40:34 2013 UTC
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Wed Nov 6
13:09:22 2013 UTC
@@ -273,6 +273,10 @@
Register ToRegister(int index) const;
DwVfpRegister ToDoubleRegister(int index) const;
+ MemOperand BuildSeqStringOperand(Register string,
+ LOperand* index,
+ String::Encoding encoding);
+
void EmitIntegerMathAbs(LMathAbs* instr);
// Support for recording safepoint and position information.
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Mon Oct 28 09:36:49
2013 UTC
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Wed Nov 6 13:09:22
2013 UTC
@@ -208,7 +208,8 @@
V(GlobalVars) \
V(InobjectFields) \
V(OsrEntries) \
- V(ExternalMemory)
+ V(ExternalMemory) \
+ V(StringChars)
#define DECLARE_ABSTRACT_INSTRUCTION(type) \
@@ -542,7 +543,7 @@
};
-typedef EnumSet<GVNFlag> GVNFlagSet;
+typedef EnumSet<GVNFlag, int64_t> GVNFlagSet;
class HValue : public ZoneObject {
@@ -6750,6 +6751,7 @@
set_representation(Representation::Integer32());
SetFlag(kUseGVN);
SetGVNFlag(kDependsOnMaps);
+ SetGVNFlag(kDependsOnStringChars);
SetGVNFlag(kChangesNewSpacePromotion);
}
@@ -7047,6 +7049,7 @@
SetOperandAt(1, index);
SetOperandAt(2, value);
set_representation(Representation::Tagged());
+ SetGVNFlag(kChangesStringChars);
}
String::Encoding encoding_;
=======================================
--- /branches/bleeding_edge/src/ia32/assembler-ia32.cc Tue Nov 5 12:04:46
2013 UTC
+++ /branches/bleeding_edge/src/ia32/assembler-ia32.cc Wed Nov 6 13:09:22
2013 UTC
@@ -551,6 +551,16 @@
EMIT(0x89);
emit_operand(src, dst);
}
+
+
+void Assembler::mov_w(const Operand& dst, int16_t imm16) {
+ EnsureSpace ensure_space(this);
+ EMIT(0x66);
+ EMIT(0xC7);
+ emit_operand(eax, dst);
+ EMIT(static_cast<int8_t>(imm16 & 0xff));
+ EMIT(static_cast<int8_t>(imm16 >> 8));
+}
void Assembler::mov(Register dst, int32_t imm32) {
=======================================
--- /branches/bleeding_edge/src/ia32/assembler-ia32.h Tue Nov 5 12:04:46
2013 UTC
+++ /branches/bleeding_edge/src/ia32/assembler-ia32.h Wed Nov 6 13:09:22
2013 UTC
@@ -735,6 +735,7 @@
void mov_w(Register dst, const Operand& src);
void mov_w(const Operand& dst, Register src);
+ void mov_w(const Operand& dst, int16_t imm16);
void mov(Register dst, int32_t imm32);
void mov(Register dst, const Immediate& x);
=======================================
--- /branches/bleeding_edge/src/ia32/disasm-ia32.cc Tue Nov 5 12:04:46
2013 UTC
+++ /branches/bleeding_edge/src/ia32/disasm-ia32.cc Wed Nov 6 13:09:22
2013 UTC
@@ -1205,6 +1205,13 @@
AppendToBuffer("mov_w ");
data += PrintRightOperand(data);
AppendToBuffer(",%s", NameOfCPURegister(regop));
+ } else if (*data == 0xC7) {
+ data++;
+ AppendToBuffer("%s ", "mov_w");
+ data += PrintRightOperand(data);
+ int imm = *reinterpret_cast<int16_t*>(data);
+ AppendToBuffer(",0x%x", imm);
+ data += 2;
} else if (*data == 0x0F) {
data++;
if (*data == 0x38) {
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Nov 5
12:04:46 2013 UTC
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Wed Nov 6
13:09:22 2013 UTC
@@ -2057,34 +2057,64 @@
__ bind(&done);
}
}
+
+
+Operand LCodeGen::BuildSeqStringOperand(Register string,
+ LOperand* index,
+ String::Encoding encoding) {
+ if (index->IsConstantOperand()) {
+ int offset = ToRepresentation(LConstantOperand::cast(index),
+ Representation::Integer32());
+ if (encoding == String::TWO_BYTE_ENCODING) {
+ offset *= kUC16Size;
+ }
+ STATIC_ASSERT(kCharSize == 1);
+ return FieldOperand(string, SeqString::kHeaderSize + offset);
+ }
+ return FieldOperand(
+ string, ToRegister(index),
+ encoding == String::ONE_BYTE_ENCODING ? times_1 : times_2,
+ SeqString::kHeaderSize);
+}
void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
+ String::Encoding encoding = instr->hydrogen()->encoding();
Register string = ToRegister(instr->string());
- Register index = ToRegister(instr->index());
- Register value = ToRegister(instr->value());
- String::Encoding encoding = instr->encoding();
if (FLAG_debug_code) {
- __ push(value);
- __ mov(value, FieldOperand(string, HeapObject::kMapOffset));
- __ movzx_b(value, FieldOperand(value, Map::kInstanceTypeOffset));
+ __ push(string);
+ __ mov(string, FieldOperand(string, HeapObject::kMapOffset));
+ __ movzx_b(string, FieldOperand(string, Map::kInstanceTypeOffset));
- __ and_(value, Immediate(kStringRepresentationMask |
kStringEncodingMask));
+ __ and_(string, Immediate(kStringRepresentationMask |
kStringEncodingMask));
static const uint32_t one_byte_seq_type = kSeqStringTag |
kOneByteStringTag;
static const uint32_t two_byte_seq_type = kSeqStringTag |
kTwoByteStringTag;
- __ cmp(value, Immediate(encoding == String::ONE_BYTE_ENCODING
- ? one_byte_seq_type : two_byte_seq_type));
+ __ cmp(string, Immediate(encoding == String::ONE_BYTE_ENCODING
+ ? one_byte_seq_type : two_byte_seq_type));
__ Check(equal, kUnexpectedStringType);
- __ pop(value);
+ __ pop(string);
}
- if (encoding == String::ONE_BYTE_ENCODING) {
- __ mov_b(FieldOperand(string, index, times_1, SeqString::kHeaderSize),
- value);
+ Operand operand = BuildSeqStringOperand(string, instr->index(),
encoding);
+ if (instr->value()->IsConstantOperand()) {
+ int value = ToRepresentation(LConstantOperand::cast(instr->value()),
+ Representation::Integer32());
+ ASSERT_LE(0, value);
+ if (encoding == String::ONE_BYTE_ENCODING) {
+ ASSERT_LE(value, String::kMaxOneByteCharCode);
+ __ mov_b(operand, static_cast<int8_t>(value));
+ } else {
+ ASSERT_LE(value, String::kMaxUtf16CodeUnit);
+ __ mov_w(operand, static_cast<int16_t>(value));
+ }
} else {
- __ mov_w(FieldOperand(string, index, times_2, SeqString::kHeaderSize),
- value);
+ Register value = ToRegister(instr->value());
+ if (encoding == String::ONE_BYTE_ENCODING) {
+ __ mov_b(operand, value);
+ } else {
+ __ mov_w(operand, value);
+ }
}
}
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Mon Oct 21
13:35:48 2013 UTC
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Wed Nov 6
13:09:22 2013 UTC
@@ -295,6 +295,10 @@
uint32_t offset,
uint32_t additional_index = 0);
+ Operand BuildSeqStringOperand(Register string,
+ LOperand* index,
+ String::Encoding encoding);
+
void EmitIntegerMathAbs(LMathAbs* instr);
// Support for recording safepoint and position information.
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Thu Oct 31 10:18:51
2013 UTC
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Wed Nov 6 13:09:22
2013 UTC
@@ -578,6 +578,14 @@
? chunk_->DefineConstantOperand(HConstant::cast(value))
: UseAtStart(value);
}
+
+
+LOperand* LChunkBuilder::UseFixedOrConstant(HValue* value,
+ Register fixed_register) {
+ return CanBeImmediateConstant(value)
+ ? chunk_->DefineConstantOperand(HConstant::cast(value))
+ : UseFixed(value, fixed_register);
+}
LOperand* LChunkBuilder::UseRegisterOrConstant(HValue* value) {
@@ -1866,13 +1874,12 @@
LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
- LOperand* string = UseRegister(instr->string());
- LOperand* index = UseRegister(instr->index());
- ASSERT(ecx.is_byte_register());
- LOperand* value = UseFixed(instr->value(), ecx);
- LSeqStringSetChar* result =
- new(zone()) LSeqStringSetChar(instr->encoding(), string, index,
value);
- return DefineSameAsFirst(result);
+ LOperand* string = UseRegisterAtStart(instr->string());
+ LOperand* index = UseRegisterOrConstantAtStart(instr->index());
+ LOperand* value = (instr->encoding() == String::ONE_BYTE_ENCODING)
+ ? UseFixedOrConstant(instr->value(), eax)
+ : UseRegisterOrConstantAtStart(instr->value());
+ return new(zone()) LSeqStringSetChar(string, index, value);
}
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h Thu Oct 31 10:18:51
2013 UTC
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.h Wed Nov 6 13:09:22
2013 UTC
@@ -1339,25 +1339,20 @@
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_;
};
@@ -2832,6 +2827,10 @@
MUST_USE_RESULT LOperand* UseOrConstant(HValue* value);
MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value);
+ // An input operand in a fixed register or a constant operand.
+ MUST_USE_RESULT LOperand* UseFixedOrConstant(HValue* value,
+ Register fixed_register);
+
// An input operand in a register or a constant operand.
MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64.cc Tue Nov 5 12:04:46
2013 UTC
+++ /branches/bleeding_edge/src/x64/assembler-x64.cc Wed Nov 6 13:09:22
2013 UTC
@@ -1355,6 +1355,15 @@
emit(0x88);
emit_operand(src, dst);
}
+
+
+void Assembler::movb(const Operand& dst, Immediate imm) {
+ EnsureSpace ensure_space(this);
+ emit_optional_rex_32(dst);
+ emit(0xC6);
+ emit_operand(0x0, dst);
+ emit(static_cast<byte>(imm.value_));
+}
void Assembler::movw(const Operand& dst, Register src) {
@@ -1364,6 +1373,17 @@
emit(0x89);
emit_operand(src, dst);
}
+
+
+void Assembler::movw(const Operand& dst, Immediate imm) {
+ EnsureSpace ensure_space(this);
+ emit(0x66);
+ emit_optional_rex_32(dst);
+ emit(0xC7);
+ emit_operand(0x0, dst);
+ emit(static_cast<byte>(imm.value_ & 0xff));
+ emit(static_cast<byte>(imm.value_ >> 8));
+}
void Assembler::movl(Register dst, const Operand& src) {
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64.h Tue Nov 5 12:04:46
2013 UTC
+++ /branches/bleeding_edge/src/x64/assembler-x64.h Wed Nov 6 13:09:22
2013 UTC
@@ -694,10 +694,12 @@
void movb(Register dst, const Operand& src);
void movb(Register dst, Immediate imm);
void movb(const Operand& dst, Register src);
+ void movb(const Operand& dst, Immediate imm);
// Move the low 16 bits of a 64-bit register value to a 16-bit
// memory location.
void movw(const Operand& dst, Register src);
+ void movw(const Operand& dst, Immediate imm);
void movl(Register dst, Register src);
void movl(Register dst, const Operand& src);
=======================================
--- /branches/bleeding_edge/src/x64/disasm-x64.cc Tue Nov 5 12:04:46 2013
UTC
+++ /branches/bleeding_edge/src/x64/disasm-x64.cc Wed Nov 6 13:09:22 2013
UTC
@@ -1565,9 +1565,15 @@
} else {
AppendToBuffer("mov%c ", operand_size_code());
data += PrintRightOperand(data);
- int32_t imm = *reinterpret_cast<int32_t*>(data);
- AppendToBuffer(",0x%x", imm);
- data += 4;
+ if (operand_size() == OPERAND_WORD_SIZE) {
+ int16_t imm = *reinterpret_cast<int16_t*>(data);
+ AppendToBuffer(",0x%x", imm);
+ data += 2;
+ } else {
+ int32_t imm = *reinterpret_cast<int32_t*>(data);
+ AppendToBuffer(",0x%x", imm);
+ data += 4;
+ }
}
}
break;
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Nov 5
12:04:46 2013 UTC
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Nov 6
13:09:22 2013 UTC
@@ -1630,34 +1630,62 @@
__ bind(&done);
}
}
+
+
+Operand 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 FieldOperand(string, SeqString::kHeaderSize + offset);
+ }
+ return FieldOperand(
+ string, ToRegister(index),
+ encoding == String::ONE_BYTE_ENCODING ? times_1 : times_2,
+ SeqString::kHeaderSize);
+}
void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
+ String::Encoding encoding = instr->hydrogen()->encoding();
Register string = ToRegister(instr->string());
- Register index = ToRegister(instr->index());
- Register value = ToRegister(instr->value());
- String::Encoding encoding = instr->encoding();
if (FLAG_debug_code) {
- __ push(value);
- __ movq(value, FieldOperand(string, HeapObject::kMapOffset));
- __ movzxbq(value, FieldOperand(value, Map::kInstanceTypeOffset));
+ __ push(string);
+ __ movq(string, FieldOperand(string, HeapObject::kMapOffset));
+ __ movzxbq(string, FieldOperand(string, Map::kInstanceTypeOffset));
- __ andb(value, Immediate(kStringRepresentationMask |
kStringEncodingMask));
+ __ andb(string, Immediate(kStringRepresentationMask |
kStringEncodingMask));
static const uint32_t one_byte_seq_type = kSeqStringTag |
kOneByteStringTag;
static const uint32_t two_byte_seq_type = kSeqStringTag |
kTwoByteStringTag;
- __ cmpq(value, Immediate(encoding == String::ONE_BYTE_ENCODING
- ? one_byte_seq_type : two_byte_seq_type));
+ __ cmpq(string, Immediate(encoding == String::ONE_BYTE_ENCODING
+ ? one_byte_seq_type : two_byte_seq_type));
__ Check(equal, kUnexpectedStringType);
- __ pop(value);
+ __ pop(string);
}
- if (encoding == String::ONE_BYTE_ENCODING) {
- __ movb(FieldOperand(string, index, times_1, SeqString::kHeaderSize),
- value);
+ Operand operand = BuildSeqStringOperand(string, instr->index(),
encoding);
+ if (instr->value()->IsConstantOperand()) {
+ int value = ToInteger32(LConstantOperand::cast(instr->value()));
+ ASSERT_LE(0, value);
+ if (encoding == String::ONE_BYTE_ENCODING) {
+ ASSERT_LE(value, String::kMaxOneByteCharCode);
+ __ movb(operand, Immediate(value));
+ } else {
+ ASSERT_LE(value, String::kMaxUtf16CodeUnit);
+ __ movw(operand, Immediate(value));
+ }
} else {
- __ movw(FieldOperand(string, index, times_2, SeqString::kHeaderSize),
- value);
+ Register value = ToRegister(instr->value());
+ if (encoding == String::ONE_BYTE_ENCODING) {
+ __ movb(operand, value);
+ } else {
+ __ movw(operand, value);
+ }
}
}
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Mon Oct 21
13:35:48 2013 UTC
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Wed Nov 6
13:09:22 2013 UTC
@@ -242,6 +242,10 @@
uint32_t offset,
uint32_t additional_index = 0);
+ Operand BuildSeqStringOperand(Register string,
+ LOperand* index,
+ String::Encoding encoding);
+
void EmitIntegerMathAbs(LMathAbs* instr);
void EmitSmiMathAbs(LMathAbs* instr);
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc Thu Oct 31 10:18:51 2013
UTC
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc Wed Nov 6 13:09:22 2013
UTC
@@ -1757,13 +1757,10 @@
LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
- LOperand* string = UseRegister(instr->string());
- LOperand* index = UseRegister(instr->index());
- ASSERT(rcx.is_byte_register());
- LOperand* value = UseFixed(instr->value(), rcx);
- LSeqStringSetChar* result =
- new(zone()) LSeqStringSetChar(instr->encoding(), string, index,
value);
- return DefineSameAsFirst(result);
+ LOperand* string = UseRegisterAtStart(instr->string());
+ LOperand* index = UseRegisterOrConstantAtStart(instr->index());
+ LOperand* value = UseRegisterOrConstantAtStart(instr->value());
+ return new(zone()) LSeqStringSetChar(string, index, value);
}
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h Thu Oct 31 10:18:51 2013
UTC
+++ /branches/bleeding_edge/src/x64/lithium-x64.h Wed Nov 6 13:09:22 2013
UTC
@@ -1283,25 +1283,20 @@
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_;
};
=======================================
--- /branches/bleeding_edge/test/mjsunit/string-natives.js Wed Dec 5
15:49:22 2012 UTC
+++ /branches/bleeding_edge/test/mjsunit/string-natives.js Wed Nov 6
13:09:22 2013 UTC
@@ -29,15 +29,23 @@
function test() {
var s1 = %NewString(26, true);
+ for (i = 0; i < 26; i++) %_OneByteSeqStringSetChar(s1, i, 65);
+ assertEquals("AAAAAAAAAAAAAAAAAAAAAAAAAA", s1);
+ %_OneByteSeqStringSetChar(s1, 25, 66);
+ assertEquals("AAAAAAAAAAAAAAAAAAAAAAAAAB", s1);
for (i = 0; i < 26; i++) %_OneByteSeqStringSetChar(s1, i, i+65);
assertEquals("ABCDEFGHIJKLMNOPQRSTUVWXYZ", s1);
s1 = %TruncateString(s1, 13);
assertEquals("ABCDEFGHIJKLM", s1);
var s2 = %NewString(26, false);
+ for (i = 0; i < 26; i++) %_TwoByteSeqStringSetChar(s2, i, 65);
+ assertEquals("AAAAAAAAAAAAAAAAAAAAAAAAAA", s2);
+ %_TwoByteSeqStringSetChar(s2, 25, 66);
+ assertEquals("AAAAAAAAAAAAAAAAAAAAAAAAAB", s2);
for (i = 0; i < 26; i++) %_TwoByteSeqStringSetChar(s2, i, i+65);
assertEquals("ABCDEFGHIJKLMNOPQRSTUVWXYZ", s2);
- s2 = %TruncateString(s1, 13);
+ s2 = %TruncateString(s2, 13);
assertEquals("ABCDEFGHIJKLM", s2);
var s3 = %NewString(26, false);
--
--
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.