| Index: src/stub-cache-ia32.cc
|
| ===================================================================
|
| --- src/stub-cache-ia32.cc (revision 606)
|
| +++ src/stub-cache-ia32.cc (working copy)
|
| @@ -159,31 +159,55 @@
|
| }
|
|
|
|
|
| -void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm,
|
| - Register receiver,
|
| - Register scratch,
|
| - Label* miss_label) {
|
| - // Check that the receiver isn't a smi.
|
| +// Generate code to check is an object is a string. If the object is
|
| +// a string, the map's instance type is left in the scratch register.
|
| +static void GenerateStringCheck(MacroAssembler* masm,
|
| + Register receiver,
|
| + Register scratch,
|
| + Label* smi,
|
| + Label* non_string_object) {
|
| + // Check that the object isn't a smi.
|
| __ test(receiver, Immediate(kSmiTagMask));
|
| - __ j(zero, miss_label, not_taken);
|
| + __ j(zero, smi, not_taken);
|
|
|
| // Check that the object is a string.
|
| __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
|
| __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
|
| ASSERT(kNotStringTag != 0);
|
| __ test(scratch, Immediate(kNotStringTag));
|
| - __ j(not_zero, miss_label, not_taken);
|
| + __ j(not_zero, non_string_object, not_taken);
|
| +}
|
|
|
| - __ and_(scratch, kStringSizeMask);
|
|
|
| +void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm,
|
| + Register receiver,
|
| + Register scratch,
|
| + Label* miss) {
|
| + Label load_length, check_wrapper;
|
| +
|
| + // Check if the object is a string.
|
| + GenerateStringCheck(masm, receiver, scratch, miss, &check_wrapper);
|
| +
|
| // Load length directly from the string.
|
| + __ bind(&load_length);
|
| + __ and_(scratch, kStringSizeMask);
|
| __ mov(eax, FieldOperand(receiver, String::kLengthOffset));
|
| -
|
| // ecx is also the receiver.
|
| __ lea(ecx, Operand(scratch, String::kLongLengthShift));
|
| __ shr(eax); // ecx is implicit shift register.
|
| __ shl(eax, kSmiTagSize);
|
| __ ret(0);
|
| +
|
| + // Check if the object is a JSValue wrapper.
|
| + __ bind(&check_wrapper);
|
| + __ cmp(receiver, JS_VALUE_TYPE);
|
| + __ j(not_equal, miss, not_taken);
|
| +
|
| + // Check if the wrapped value is a string and load the length
|
| + // directly if it is.
|
| + __ mov(receiver, FieldOperand(receiver, JSValue::kValueOffset));
|
| + GenerateStringCheck(masm, receiver, scratch, miss, miss);
|
| + __ jmp(&load_length);
|
| }
|
|
|
|
|
|
|