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