Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(420)

Unified Diff: src/ia32/codegen-ia32.cc

Issue 1633024: Revert r4444 "Inline fast cases in string keyed load IC." (Closed)
Patch Set: Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/codegen-ia32.cc
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index 5ab7a531f325679e5285d045aadaa570625b56e4..9512886a58e26d75eca7f6d01239e71f4b906d91 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -2348,7 +2348,7 @@ Result CodeGenerator::ConstantSmiBinaryOperation(
smi_value,
overwrite_mode);
// Check for negative or non-Smi left hand side.
- __ test(operand->reg(), Immediate(kSmiTagMask | kSmiSignMask));
+ __ test(operand->reg(), Immediate(kSmiTagMask | 0x80000000));
deferred->Branch(not_zero);
if (int_value < 0) int_value = -int_value;
if (int_value == 1) {
@@ -5901,7 +5901,7 @@ void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) {
Result value = frame_->Pop();
value.ToRegister();
ASSERT(value.is_valid());
- __ test(value.reg(), Immediate(kSmiTagMask | kSmiSignMask));
+ __ test(value.reg(), Immediate(kSmiTagMask | 0x80000000));
value.Unuse();
destination()->Split(zero);
}
@@ -5917,11 +5917,43 @@ void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
Comment(masm_, "[ GenerateFastCharCodeAt");
ASSERT(args->length() == 2);
+ Label slow_case;
+ Label end;
+ Label not_a_flat_string;
+ Label try_again_with_new_string;
+ Label ascii_string;
+ Label got_char_code;
+
Load(args->at(0));
Load(args->at(1));
Result index = frame_->Pop();
Result object = frame_->Pop();
+ // Get register ecx to use as shift amount later.
+ Result shift_amount;
+ if (object.is_register() && object.reg().is(ecx)) {
+ Result fresh = allocator_->Allocate();
+ shift_amount = object;
+ object = fresh;
+ __ mov(object.reg(), ecx);
+ }
+ if (index.is_register() && index.reg().is(ecx)) {
+ Result fresh = allocator_->Allocate();
+ shift_amount = index;
+ index = fresh;
+ __ mov(index.reg(), ecx);
+ }
+ // There could be references to ecx in the frame. Allocating will
+ // spill them, otherwise spill explicitly.
+ if (shift_amount.is_valid()) {
+ frame_->Spill(ecx);
+ } else {
+ shift_amount = allocator()->Allocate(ecx);
+ }
+ ASSERT(shift_amount.is_register());
+ ASSERT(shift_amount.reg().is(ecx));
+ ASSERT(allocator_->count(ecx) == 1);
+
// We will mutate the index register and possibly the object register.
// The case where they are somehow the same register is handled
// because we only mutate them in the case where the receiver is a
@@ -5931,33 +5963,93 @@ void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
frame_->Spill(object.reg());
frame_->Spill(index.reg());
- // We need two extra registers.
- Result result = allocator()->Allocate();
- ASSERT(result.is_valid());
- Result scratch = allocator()->Allocate();
- ASSERT(scratch.is_valid());
+ // We need a single extra temporary register.
+ Result temp = allocator()->Allocate();
+ ASSERT(temp.is_valid());
// There is no virtual frame effect from here up to the final result
// push.
- Label slow_case;
- Label exit;
- StringHelper::GenerateFastCharCodeAt(masm_,
- object.reg(),
- index.reg(),
- scratch.reg(),
- result.reg(),
- &slow_case,
- &slow_case,
- &slow_case);
- __ jmp(&exit);
+
+ // If the receiver is a smi trigger the slow case.
+ ASSERT(kSmiTag == 0);
+ __ test(object.reg(), Immediate(kSmiTagMask));
+ __ j(zero, &slow_case);
+
+ // If the index is negative or non-smi trigger the slow case.
+ ASSERT(kSmiTag == 0);
+ __ test(index.reg(), Immediate(kSmiTagMask | 0x80000000));
+ __ j(not_zero, &slow_case);
+ // Untag the index.
+ __ SmiUntag(index.reg());
+
+ __ bind(&try_again_with_new_string);
+ // Fetch the instance type of the receiver into ecx.
+ __ mov(ecx, FieldOperand(object.reg(), HeapObject::kMapOffset));
+ __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
+ // If the receiver is not a string trigger the slow case.
+ __ test(ecx, Immediate(kIsNotStringMask));
+ __ j(not_zero, &slow_case);
+
+ // Fetch the length field into the temporary register.
+ __ mov(temp.reg(), FieldOperand(object.reg(), String::kLengthOffset));
+ // Check for index out of range.
+ __ cmp(index.reg(), Operand(temp.reg()));
+ __ j(greater_equal, &slow_case);
+ // Reload the instance type (into the temp register this time)..
+ __ mov(temp.reg(), FieldOperand(object.reg(), HeapObject::kMapOffset));
+ __ movzx_b(temp.reg(), FieldOperand(temp.reg(), Map::kInstanceTypeOffset));
+
+ // We need special handling for non-flat strings.
+ ASSERT(kSeqStringTag == 0);
+ __ test(temp.reg(), Immediate(kStringRepresentationMask));
+ __ j(not_zero, &not_a_flat_string);
+ // Check for 1-byte or 2-byte string.
+ __ test(temp.reg(), Immediate(kStringEncodingMask));
+ __ j(not_zero, &ascii_string);
+
+ // 2-byte string.
+ // Load the 2-byte character code into the temp register.
+ __ movzx_w(temp.reg(), FieldOperand(object.reg(),
+ index.reg(),
+ times_2,
+ SeqTwoByteString::kHeaderSize));
+ __ jmp(&got_char_code);
+
+ // ASCII string.
+ __ bind(&ascii_string);
+ // Load the byte into the temp register.
+ __ movzx_b(temp.reg(), FieldOperand(object.reg(),
+ index.reg(),
+ times_1,
+ SeqAsciiString::kHeaderSize));
+ __ bind(&got_char_code);
+ __ SmiTag(temp.reg());
+ __ jmp(&end);
+
+ // Handle non-flat strings.
+ __ bind(&not_a_flat_string);
+ __ and_(temp.reg(), kStringRepresentationMask);
+ __ cmp(temp.reg(), kConsStringTag);
+ __ j(not_equal, &slow_case);
+
+ // ConsString.
+ // Check that the right hand side is the empty string (ie if this is really a
+ // flat string in a cons string). If that is not the case we would rather go
+ // to the runtime system now, to flatten the string.
+ __ mov(temp.reg(), FieldOperand(object.reg(), ConsString::kSecondOffset));
+ __ cmp(Operand(temp.reg()), Factory::empty_string());
+ __ j(not_equal, &slow_case);
+ // Get the first of the two strings.
+ __ mov(object.reg(), FieldOperand(object.reg(), ConsString::kFirstOffset));
+ __ jmp(&try_again_with_new_string);
__ bind(&slow_case);
// Move the undefined value into the result register, which will
// trigger the slow case.
- __ Set(result.reg(), Immediate(Factory::undefined_value()));
+ __ Set(temp.reg(), Immediate(Factory::undefined_value()));
- __ bind(&exit);
- frame_->Push(&result);
+ __ bind(&end);
+ frame_->Push(&temp);
}
@@ -5966,22 +6058,46 @@ void CodeGenerator::GenerateCharFromCode(ZoneList<Expression*>* args) {
ASSERT(args->length() == 1);
Load(args->at(0));
-
Result code = frame_->Pop();
code.ToRegister();
ASSERT(code.is_valid());
- // StringHelper::GenerateCharFromCode may do a runtime call.
- frame_->SpillAll();
+ Result temp = allocator()->Allocate();
+ ASSERT(temp.is_valid());
+
+ JumpTarget slow_case;
+ JumpTarget exit;
+
+ // Fast case of Heap::LookupSingleCharacterStringFromCode.
+ ASSERT(kSmiTag == 0);
+ ASSERT(kSmiShiftSize == 0);
+ ASSERT(IsPowerOf2(String::kMaxAsciiCharCode + 1));
+ __ test(code.reg(),
+ Immediate(kSmiTagMask |
+ ((~String::kMaxAsciiCharCode) << kSmiTagSize)));
+ slow_case.Branch(not_zero, &code, not_taken);
+
+ __ Set(temp.reg(), Immediate(Factory::single_character_string_cache()));
+ ASSERT(kSmiTag == 0);
+ ASSERT(kSmiTagSize == 1);
+ ASSERT(kSmiShiftSize == 0);
+ // At this point code register contains smi tagged ascii char code.
+ __ mov(temp.reg(), FieldOperand(temp.reg(),
+ code.reg(), times_half_pointer_size,
+ FixedArray::kHeaderSize));
+ __ cmp(temp.reg(), Factory::undefined_value());
+ slow_case.Branch(equal, &code, not_taken);
+ code.Unuse();
- Result result = allocator()->Allocate();
- ASSERT(result.is_valid());
+ frame_->Push(&temp);
+ exit.Jump();
- StringHelper::GenerateCharFromCode(masm_,
- code.reg(),
- result.reg(),
- CALL_FUNCTION);
+ slow_case.Bind(&code);
+ frame_->Push(&code);
+ Result result = frame_->CallRuntime(Runtime::kCharFromCode, 1);
frame_->Push(&result);
+
+ exit.Bind();
}
@@ -8406,7 +8522,7 @@ Result CodeGenerator::EmitKeyedStore(StaticType* key_type) {
}
// Check that the key is a non-negative smi.
- __ test(key.reg(), Immediate(kSmiTagMask | kSmiSignMask));
+ __ test(key.reg(), Immediate(kSmiTagMask | 0x80000000));
deferred->Branch(not_zero);
// Check that the receiver is not a smi.
@@ -12038,154 +12154,6 @@ const char* CompareStub::GetName() {
}
-void StringHelper::GenerateFastCharCodeAt(MacroAssembler* masm,
- Register object,
- Register index,
- Register scratch,
- Register result,
- Label* receiver_not_string,
- Label* index_not_positive_smi,
- Label* slow_case) {
- Label not_a_flat_string;
- Label try_again_with_new_string;
- Label ascii_string;
- Label got_char_code;
-
- // If the receiver is a smi trigger the non-string case.
- ASSERT(kSmiTag == 0);
- __ test(object, Immediate(kSmiTagMask));
- __ j(zero, receiver_not_string);
-
- // Fetch the instance type of the receiver into result register.
- __ mov(result, FieldOperand(object, HeapObject::kMapOffset));
- __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset));
- // If the receiver is not a string trigger the non-string case.
- __ test(result, Immediate(kIsNotStringMask));
- __ j(not_zero, receiver_not_string);
-
- // If the index is negative or non-smi trigger the non-positive-smi
- // case.
- ASSERT(kSmiTag == 0);
- __ test(index, Immediate(kSmiTagMask | kSmiSignMask));
- __ j(not_zero, index_not_positive_smi);
-
- // Put untagged index into scratch register.
- __ mov(scratch, index);
- __ SmiUntag(scratch);
-
- // Check for index out of range.
- __ cmp(scratch, FieldOperand(object, String::kLengthOffset));
- __ j(greater_equal, slow_case);
-
- __ bind(&try_again_with_new_string);
- // ----------- S t a t e -------------
- // -- object : string to access
- // -- result : instance type of the string
- // -- scratch : positive smi index < length
- // -----------------------------------
-
- // We need special handling for non-flat strings.
- ASSERT(kSeqStringTag == 0);
- __ test(result, Immediate(kStringRepresentationMask));
- __ j(not_zero, &not_a_flat_string);
-
- // Check for 1-byte or 2-byte string.
- ASSERT(kAsciiStringTag != 0);
- __ test(result, Immediate(kStringEncodingMask));
- __ j(not_zero, &ascii_string);
-
- // 2-byte string.
- // Load the 2-byte character code into the temp register.
- __ movzx_w(result, FieldOperand(object,
- scratch, times_2,
- SeqTwoByteString::kHeaderSize));
- __ jmp(&got_char_code);
-
- // Handle non-flat strings.
- __ bind(&not_a_flat_string);
- __ and_(result, kStringRepresentationMask);
- __ cmp(result, kConsStringTag);
- __ j(not_equal, slow_case);
-
- // ConsString.
- // Check whether the right hand side is the empty string (i.e. if
- // this is really a flat string in a cons string). If that is not
- // the case we would rather go to the runtime system now to flatten
- // the string.
- __ mov(result, FieldOperand(object, ConsString::kSecondOffset));
- __ cmp(Operand(result), Factory::empty_string());
- __ j(not_equal, slow_case);
- // Get the first of the two strings and load its instance type.
- __ mov(object, FieldOperand(object, ConsString::kFirstOffset));
- __ mov(result, FieldOperand(object, HeapObject::kMapOffset));
- __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset));
- __ jmp(&try_again_with_new_string);
-
- // ASCII string.
- __ bind(&ascii_string);
- // Load the byte into the temp register.
- __ movzx_b(result, FieldOperand(object,
- scratch, times_1,
- SeqAsciiString::kHeaderSize));
- __ bind(&got_char_code);
- __ SmiTag(result);
-}
-
-
-void StringHelper::GenerateCharFromCode(MacroAssembler* masm,
- Register code,
- Register result,
- InvokeFlag flag) {
- ASSERT(!code.is(result));
-
- Label slow_case;
- Label exit;
-
- // Fast case of Heap::LookupSingleCharacterStringFromCode.
- ASSERT(kSmiTag == 0);
- ASSERT(kSmiShiftSize == 0);
- ASSERT(IsPowerOf2(String::kMaxAsciiCharCode + 1));
- __ test(code,
- Immediate(kSmiTagMask |
- ((~String::kMaxAsciiCharCode) << kSmiTagSize)));
- __ j(not_zero, &slow_case, not_taken);
-
- __ Set(result, Immediate(Factory::single_character_string_cache()));
- ASSERT(kSmiTag == 0);
- ASSERT(kSmiTagSize == 1);
- ASSERT(kSmiShiftSize == 0);
- // At this point code register contains smi tagged ascii char code.
- __ mov(result, FieldOperand(result,
- code, times_half_pointer_size,
- FixedArray::kHeaderSize));
- __ cmp(result, Factory::undefined_value());
- __ j(equal, &slow_case, not_taken);
- __ jmp(&exit);
-
- __ bind(&slow_case);
- if (flag == CALL_FUNCTION) {
- __ push(code);
- __ CallRuntime(Runtime::kCharFromCode, 1);
- if (!result.is(eax)) {
- __ mov(result, eax);
- }
- } else {
- ASSERT(flag == JUMP_FUNCTION);
- ASSERT(result.is(eax));
- __ pop(eax); // Save return address.
- __ push(code);
- __ push(eax); // Restore return address.
- __ TailCallRuntime(Runtime::kCharFromCode, 1, 1);
- }
-
- __ bind(&exit);
- if (flag == JUMP_FUNCTION) {
- ASSERT(result.is(eax));
- __ ret(0);
- }
-}
-
-
void StringAddStub::Generate(MacroAssembler* masm) {
Label string_add_runtime;
@@ -12252,8 +12220,8 @@ void StringAddStub::Generate(MacroAssembler* masm) {
// 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;
- StringHelper::GenerateTwoCharacterSymbolTableProbe(
- masm, ebx, ecx, eax, edx, edi, &make_two_character_string);
+ GenerateTwoCharacterSymbolTableProbe(masm, ebx, ecx, eax, edx, edi,
+ &make_two_character_string);
__ IncrementCounter(&Counters::string_add_native, 1);
__ ret(2 * kPointerSize);
@@ -12345,7 +12313,7 @@ void StringAddStub::Generate(MacroAssembler* masm) {
// ecx: first character of result
// edx: first char of first argument
// edi: length of first argument
- StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, true);
+ GenerateCopyCharacters(masm, ecx, edx, edi, ebx, true);
// Load second argument and locate first character.
__ mov(edx, Operand(esp, 1 * kPointerSize));
__ mov(edi, FieldOperand(edx, String::kLengthOffset));
@@ -12354,7 +12322,7 @@ void StringAddStub::Generate(MacroAssembler* masm) {
// ecx: next character of result
// edx: first char of second argument
// edi: length of second argument
- StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, true);
+ GenerateCopyCharacters(masm, ecx, edx, edi, ebx, true);
__ IncrementCounter(&Counters::string_add_native, 1);
__ ret(2 * kPointerSize);
@@ -12384,7 +12352,7 @@ void StringAddStub::Generate(MacroAssembler* masm) {
// ecx: first character of result
// edx: first char of first argument
// edi: length of first argument
- StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, false);
+ GenerateCopyCharacters(masm, ecx, edx, edi, ebx, false);
// Load second argument and locate first character.
__ mov(edx, Operand(esp, 1 * kPointerSize));
__ mov(edi, FieldOperand(edx, String::kLengthOffset));
@@ -12393,7 +12361,7 @@ void StringAddStub::Generate(MacroAssembler* masm) {
// ecx: next character of result
// edx: first char of second argument
// edi: length of second argument
- StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, false);
+ GenerateCopyCharacters(masm, ecx, edx, edi, ebx, false);
__ IncrementCounter(&Counters::string_add_native, 1);
__ ret(2 * kPointerSize);
@@ -12403,12 +12371,12 @@ void StringAddStub::Generate(MacroAssembler* masm) {
}
-void StringHelper::GenerateCopyCharacters(MacroAssembler* masm,
- Register dest,
- Register src,
- Register count,
- Register scratch,
- bool ascii) {
+void StringStubBase::GenerateCopyCharacters(MacroAssembler* masm,
+ Register dest,
+ Register src,
+ Register count,
+ Register scratch,
+ bool ascii) {
Label loop;
__ bind(&loop);
// This loop just copies one character at a time, as it is only used for very
@@ -12429,12 +12397,12 @@ void StringHelper::GenerateCopyCharacters(MacroAssembler* masm,
}
-void StringHelper::GenerateCopyCharactersREP(MacroAssembler* masm,
- Register dest,
- Register src,
- Register count,
- Register scratch,
- bool ascii) {
+void StringStubBase::GenerateCopyCharactersREP(MacroAssembler* masm,
+ Register dest,
+ Register src,
+ Register count,
+ Register scratch,
+ bool ascii) {
// Copy characters using rep movs of doublewords. Align destination on 4 byte
// boundary before starting rep movs. Copy remaining characters after running
// rep movs.
@@ -12489,13 +12457,13 @@ void StringHelper::GenerateCopyCharactersREP(MacroAssembler* masm,
}
-void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
- Register c1,
- Register c2,
- Register scratch1,
- Register scratch2,
- Register scratch3,
- Label* not_found) {
+void StringStubBase::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
+ Register c1,
+ Register c2,
+ Register scratch1,
+ Register scratch2,
+ Register scratch3,
+ Label* not_found) {
// Register scratch3 is the general scratch register in this function.
Register scratch = scratch3;
@@ -12609,10 +12577,10 @@ void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
}
-void StringHelper::GenerateHashInit(MacroAssembler* masm,
- Register hash,
- Register character,
- Register scratch) {
+void StringStubBase::GenerateHashInit(MacroAssembler* masm,
+ Register hash,
+ Register character,
+ Register scratch) {
// hash = character + (character << 10);
__ mov(hash, character);
__ shl(hash, 10);
@@ -12624,10 +12592,10 @@ void StringHelper::GenerateHashInit(MacroAssembler* masm,
}
-void StringHelper::GenerateHashAddCharacter(MacroAssembler* masm,
- Register hash,
- Register character,
- Register scratch) {
+void StringStubBase::GenerateHashAddCharacter(MacroAssembler* masm,
+ Register hash,
+ Register character,
+ Register scratch) {
// hash += character;
__ add(hash, Operand(character));
// hash += hash << 10;
@@ -12641,9 +12609,9 @@ void StringHelper::GenerateHashAddCharacter(MacroAssembler* masm,
}
-void StringHelper::GenerateHashGetHash(MacroAssembler* masm,
- Register hash,
- Register scratch) {
+void StringStubBase::GenerateHashGetHash(MacroAssembler* masm,
+ Register hash,
+ Register scratch) {
// hash += hash << 3;
__ mov(scratch, hash);
__ shl(scratch, 3);
@@ -12717,8 +12685,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);
+ GenerateTwoCharacterSymbolTableProbe(masm, ebx, ecx, eax, edx, edi,
+ &make_two_character_string);
__ ret(3 * kPointerSize);
__ bind(&make_two_character_string);
@@ -12757,7 +12725,7 @@ void SubStringStub::Generate(MacroAssembler* masm) {
// edx: original value of esi
// edi: first character of result
// esi: character of sub string start
- StringHelper::GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, true);
+ GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, true);
__ mov(esi, edx); // Restore esi.
__ IncrementCounter(&Counters::sub_string_native, 1);
__ ret(3 * kPointerSize);
@@ -12796,7 +12764,7 @@ void SubStringStub::Generate(MacroAssembler* masm) {
// edx: original value of esi
// edi: first character of result
// esi: character of sub string start
- StringHelper::GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, false);
+ GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, false);
__ mov(esi, edx); // Restore esi.
__ IncrementCounter(&Counters::sub_string_native, 1);
__ ret(3 * kPointerSize);
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698