| 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);
|
| }
|
|
|
|
|