}
-// Generate code to check if an object is a string. If the object is
-// a string, the map's instance type is left in the scratch1 register.
+// Generate code to check if an object is a string. If the object is a
+// heap object, its map's instance type is left in the scratch1 register.
+// If this is not needed, scratch1 and scratch2 may be the same register.
static void GenerateStringCheck(MacroAssembler* masm,
Register receiver,
Register scratch1,
Register scratch1,
Register scratch2,
Label* miss) {
- Label check_string, check_wrapper;
+ Label check_wrapper;
- __ bind(&check_string);
// Check if the object is a string leaving the instance type in the
// scratch1 register.
- GenerateStringCheck(masm, receiver, scratch1, scratch2,
- miss, &check_wrapper);
+ GenerateStringCheck(masm, receiver, scratch1, scratch2, miss, &check_wrapper);
// Load length directly from the string.
__ ldr(r0, FieldMemOperand(receiver, String::kLengthOffset));
__ cmp(scratch1, Operand(JS_VALUE_TYPE));
__ b(ne, miss);
- // Unwrap the value in place and check if the wrapped value is a string.
- __ ldr(receiver, FieldMemOperand(receiver, JSValue::kValueOffset));
- __ b(&check_string);
+ // Unwrap the value and check if the wrapped value is a string.
+ __ ldr(scratch1, FieldMemOperand(receiver, JSValue::kValueOffset));
+ GenerateStringCheck(masm, scratch1, scratch2, scratch2, miss, miss);
+ __ ldr(r0, FieldMemOperand(scratch1, String::kLengthOffset));
+ __ mov(r0, Operand(r0, LSL, kSmiTagSize));
+ __ Ret();
}
Register scratch1,
Register scratch2,
Label* miss) {
- Label load_length, check_wrapper;
+ Label check_wrapper;
// Check if the object is a string leaving the instance type in the
// scratch register.
GenerateStringCheck(masm, receiver, scratch1, miss, &check_wrapper);
// Load length from the string and convert to a smi.
- __ bind(&load_length);
__ mov(eax, FieldOperand(receiver, String::kLengthOffset));
__ SmiTag(eax);
__ ret(0);
// directly if it is.
__ mov(scratch2, FieldOperand(receiver, JSValue::kValueOffset));
GenerateStringCheck(masm, scratch2, scratch1, miss, miss);
- __ jmp(&load_length);
+ __ mov(eax, FieldOperand(scratch2, String::kLengthOffset));
+ __ SmiTag(eax);
+ __ ret(0);
}
static void GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
int index,
Register prototype);
+
static void GenerateFastPropertyLoad(MacroAssembler* masm,
Register dst, Register src,
JSObject* holder, int index);
Register receiver,
Register scratch,
Label* miss_label);
+
static void GenerateLoadStringLength(MacroAssembler* masm,
- Register receiver,
- Register scratch1,
- Register scratch2,
- Label* miss_label);
+ Register receiver,
+ Register scratch1,
+ Register scratch2,
+ Label* miss_label);
+
static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
Register receiver,
Register scratch1,
Register scratch2,
Label* miss_label);
+
static void GenerateStoreField(MacroAssembler* masm,
Builtins::Name storage_extend,
JSObject* object,
Register name_reg,
Register scratch,
Label* miss_label);
+
static void GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind);
// Check the integrity of the prototype chain to make sure that the
Register scratch1,
Register scratch2,
Label* miss) {
- Label load_length, check_wrapper;
+ Label check_wrapper;
// Check if the object is a string leaving the instance type in the
// scratch register.
GenerateStringCheck(masm, receiver, scratch1, miss, &check_wrapper);
// Load length directly from the string.
- __ bind(&load_length);
__ movl(rax, FieldOperand(receiver, String::kLengthOffset));
__ Integer32ToSmi(rax, rax);
__ ret(0);
// directly if it is.
__ movq(scratch2, FieldOperand(receiver, JSValue::kValueOffset));
GenerateStringCheck(masm, scratch2, scratch1, miss, miss);
- __ movq(receiver, scratch2);
- __ jmp(&load_length);
+ __ movl(rax, FieldOperand(scratch2, String::kLengthOffset));
+ __ Integer32ToSmi(rax, rax);
+ __ ret(0);
}