Index: src/ia32/ic-ia32.cc |
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc |
index f07018a4f58e2a60593886509851e747cf07d465..cf521a249ccce1d4b81b19f07e28953233648e9e 100644 |
--- a/src/ia32/ic-ia32.cc |
+++ b/src/ia32/ic-ia32.cc |
@@ -491,58 +491,39 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { |
void KeyedLoadIC::GenerateString(MacroAssembler* masm) { |
// ----------- S t a t e ------------- |
- // -- eax : key (index) |
+ // -- eax : key |
// -- edx : receiver |
// -- esp[0] : return address |
// ----------------------------------- |
- Label miss; |
- Label not_positive_smi; |
- Label slow_char_code; |
- Label got_char_code; |
+ Label miss, index_ok; |
- Register receiver = edx; |
- Register index = eax; |
- Register code = ebx; |
- Register scratch = ecx; |
- |
- StringHelper::GenerateFastCharCodeAt(masm, |
- receiver, |
- index, |
- scratch, |
- code, |
- &miss, // When not a string. |
- ¬_positive_smi, |
- &slow_char_code); |
- // If we didn't bail out, code register contains smi tagged char |
- // code. |
- __ bind(&got_char_code); |
- StringHelper::GenerateCharFromCode(masm, code, eax, JUMP_FUNCTION); |
-#ifdef DEBUG |
- __ Abort("Unexpected fall-through from char from code tail call"); |
-#endif |
+ // Pop return address. |
+ // Performing the load early is better in the common case. |
+ __ pop(ebx); |
+ |
+ __ test(edx, Immediate(kSmiTagMask)); |
+ __ j(zero, &miss); |
+ __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); |
+ __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
+ __ test(ecx, Immediate(kIsNotStringMask)); |
+ __ j(not_zero, &miss); |
// Check if key is a smi or a heap number. |
- __ bind(¬_positive_smi); |
- ASSERT(kSmiTag == 0); |
- __ test(index, Immediate(kSmiTagMask)); |
- __ j(zero, &slow_char_code); |
+ __ test(eax, Immediate(kSmiTagMask)); |
+ __ j(zero, &index_ok); |
__ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); |
__ cmp(ecx, Factory::heap_number_map()); |
__ j(not_equal, &miss); |
- // Push receiver and key on the stack (now that we know they are a |
- // string and a number), and call runtime. |
- __ bind(&slow_char_code); |
- __ EnterInternalFrame(); |
- __ push(receiver); |
- __ push(index); |
- __ CallRuntime(Runtime::kStringCharCodeAt, 1); |
- ASSERT(!code.is(eax)); |
- __ mov(code, eax); |
- __ LeaveInternalFrame(); |
- __ jmp(&got_char_code); |
+ __ bind(&index_ok); |
+ // Push receiver and key on the stack, and make a tail call. |
+ __ push(edx); // receiver |
+ __ push(eax); // key |
+ __ push(ebx); // return address |
+ __ InvokeBuiltin(Builtins::STRING_CHAR_AT, JUMP_FUNCTION); |
__ bind(&miss); |
+ __ push(ebx); |
GenerateMiss(masm); |
} |