Commit 780934e1 authored by vitalyr@chromium.org's avatar vitalyr@chromium.org

ia32 StringAddStub: fast two character case.

Review URL: http://codereview.chromium.org/3327001

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5397 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5b1ba9a4
......@@ -3828,21 +3828,41 @@ void StringAddStub::Generate(MacroAssembler* masm) {
__ JumpIfNotBothSequentialAsciiStrings(eax, edx, ebx, ecx,
&string_add_runtime);
// Get the two characters forming the sub string.
// Get the two characters forming the new string.
__ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize));
__ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize));
// Try to lookup two character string in symbol table. If it is not found
// just allocate a new one.
Label make_two_character_string, make_flat_ascii_string;
Label make_two_character_string, make_two_character_string_no_reload;
StringHelper::GenerateTwoCharacterSymbolTableProbe(
masm, ebx, ecx, eax, edx, edi, &make_two_character_string);
masm, ebx, ecx, eax, edx, edi,
&make_two_character_string_no_reload, &make_two_character_string);
__ IncrementCounter(&Counters::string_add_native, 1);
__ ret(2 * kPointerSize);
// Allocate a two character string.
__ bind(&make_two_character_string);
__ Set(ebx, Immediate(Smi::FromInt(2)));
__ jmp(&make_flat_ascii_string);
// Reload the arguments.
__ mov(eax, Operand(esp, 2 * kPointerSize)); // First argument.
__ mov(edx, Operand(esp, 1 * kPointerSize)); // Second argument.
// Get the two characters forming the new string.
__ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize));
__ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize));
__ bind(&make_two_character_string_no_reload);
__ IncrementCounter(&Counters::string_add_make_two_char, 1);
__ AllocateAsciiString(eax, // Result.
2, // Length.
edi, // Scratch 1.
edx, // Scratch 2.
&string_add_runtime);
// Pack both characters in ebx.
__ shl(ecx, kBitsPerByte);
__ or_(ebx, Operand(ecx));
// Set the characters in the new string.
__ mov_w(FieldOperand(eax, SeqAsciiString::kHeaderSize), ebx);
__ IncrementCounter(&Counters::string_add_native, 1);
__ ret(2 * kPointerSize);
__ bind(&longer_than_two);
// Check if resulting string will be flat.
......@@ -3921,7 +3941,6 @@ void StringAddStub::Generate(MacroAssembler* masm) {
__ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
__ j(zero, &string_add_runtime);
__ bind(&make_flat_ascii_string);
// Both strings are ascii strings. As they are short they are both flat.
// ebx: length of resulting flat string as a smi
__ SmiUntag(ebx);
......@@ -4092,6 +4111,7 @@ void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
Register scratch1,
Register scratch2,
Register scratch3,
Label* not_probed,
Label* not_found) {
// Register scratch3 is the general scratch register in this function.
Register scratch = scratch3;
......@@ -4106,7 +4126,7 @@ void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
__ mov(scratch, c2);
__ sub(Operand(scratch), Immediate(static_cast<int>('0')));
__ cmp(Operand(scratch), Immediate(static_cast<int>('9' - '0')));
__ j(below_equal, not_found);
__ j(below_equal, not_probed);
__ bind(&not_array_index);
// Calculate the two character string hash.
......@@ -4320,7 +4340,8 @@ void SubStringStub::Generate(MacroAssembler* masm) {
// Try to lookup two character string in symbol table.
Label make_two_character_string;
StringHelper::GenerateTwoCharacterSymbolTableProbe(
masm, ebx, ecx, eax, edx, edi, &make_two_character_string);
masm, ebx, ecx, eax, edx, edi,
&make_two_character_string, &make_two_character_string);
__ ret(3 * kPointerSize);
__ bind(&make_two_character_string);
......
......@@ -234,16 +234,21 @@ class StringHelper : public AllStatic {
Register scratch, // Neither of above.
bool ascii);
// Probe the symbol table for a two character string. If the string is
// not found by probing a jump to the label not_found is performed. This jump
// does not guarantee that the string is not in the symbol table. If the
// string is found the code falls through with the string in register eax.
// Probe the symbol table for a two character string. If the string
// requires non-standard hashing a jump to the label not_probed is
// performed and registers c1 and c2 are preserved. In all other
// cases they are clobbered. If the string is not found by probing a
// jump to the label not_found is performed. This jump does not
// guarantee that the string is not in the symbol table. If the
// string is found the code falls through with the string in
// register eax.
static void GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
Register c1,
Register c2,
Register scratch1,
Register scratch2,
Register scratch3,
Label* not_probed,
Label* not_found);
// Generate string hash.
......
......@@ -782,6 +782,31 @@ void MacroAssembler::AllocateAsciiString(Register result,
}
void MacroAssembler::AllocateAsciiString(Register result,
int length,
Register scratch1,
Register scratch2,
Label* gc_required) {
ASSERT(length > 0);
// Allocate ascii string in new space.
AllocateInNewSpace(SeqAsciiString::SizeFor(length),
result,
scratch1,
scratch2,
gc_required,
TAG_OBJECT);
// Set the map, length and hash field.
mov(FieldOperand(result, HeapObject::kMapOffset),
Immediate(Factory::ascii_string_map()));
mov(FieldOperand(result, String::kLengthOffset),
Immediate(Smi::FromInt(length)));
mov(FieldOperand(result, String::kHashFieldOffset),
Immediate(String::kEmptyHashField));
}
void MacroAssembler::AllocateConsString(Register result,
Register scratch1,
Register scratch2,
......
......@@ -356,6 +356,11 @@ class MacroAssembler: public Assembler {
Register scratch2,
Register scratch3,
Label* gc_required);
void AllocateAsciiString(Register result,
int length,
Register scratch1,
Register scratch2,
Label* gc_required);
// Allocate a raw cons string object. Only the map field of the result is
// initialized.
......
......@@ -203,6 +203,7 @@ namespace internal {
SC(string_add_runtime_ext_to_ascii, V8.StringAddRuntimeExtToAscii) \
SC(sub_string_runtime, V8.SubStringRuntime) \
SC(sub_string_native, V8.SubStringNative) \
SC(string_add_make_two_char, V8.StringAddMakeTwoChar) \
SC(string_compare_native, V8.StringCompareNative) \
SC(string_compare_runtime, V8.StringCompareRuntime) \
SC(regexp_entry_runtime, V8.RegExpEntryRuntime) \
......
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