| Index: src/ia32/ic-ia32.cc
|
| diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
|
| index cf521a249ccce1d4b81b19f07e28953233648e9e..f07018a4f58e2a60593886509851e747cf07d465 100644
|
| --- a/src/ia32/ic-ia32.cc
|
| +++ b/src/ia32/ic-ia32.cc
|
| @@ -491,39 +491,58 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
|
|
| void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
|
| // ----------- S t a t e -------------
|
| - // -- eax : key
|
| + // -- eax : key (index)
|
| // -- edx : receiver
|
| // -- esp[0] : return address
|
| // -----------------------------------
|
| - Label miss, index_ok;
|
| -
|
| - // Pop return address.
|
| - // Performing the load early is better in the common case.
|
| - __ pop(ebx);
|
| + Label miss;
|
| + Label not_positive_smi;
|
| + Label slow_char_code;
|
| + Label got_char_code;
|
|
|
| - __ 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);
|
| + 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
|
|
|
| // Check if key is a smi or a heap number.
|
| - __ test(eax, Immediate(kSmiTagMask));
|
| - __ j(zero, &index_ok);
|
| + __ bind(¬_positive_smi);
|
| + ASSERT(kSmiTag == 0);
|
| + __ test(index, Immediate(kSmiTagMask));
|
| + __ j(zero, &slow_char_code);
|
| __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
|
| __ cmp(ecx, Factory::heap_number_map());
|
| __ j(not_equal, &miss);
|
|
|
| - __ 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);
|
| + // 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(&miss);
|
| - __ push(ebx);
|
| GenerateMiss(masm);
|
| }
|
|
|
|
|