Change GenerateLoadStringLength to have two scratch registers on all platforms. This is needed so that the LoadIC can pass the receiver in a register, and not have it overwritten, and also simplifies the code.
Review URL: http://codereview.chromium.org/596011 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3820 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
df1df78c48
commit
503bbeb8c4
@ -190,7 +190,7 @@ void LoadIC::GenerateStringLength(MacroAssembler* masm) {
|
|||||||
|
|
||||||
__ ldr(r0, MemOperand(sp, 0));
|
__ ldr(r0, MemOperand(sp, 0));
|
||||||
|
|
||||||
StubCompiler::GenerateLoadStringLength2(masm, r0, r1, r3, &miss);
|
StubCompiler::GenerateLoadStringLength(masm, r0, r1, r3, &miss);
|
||||||
// Cache miss: Jump to runtime.
|
// Cache miss: Jump to runtime.
|
||||||
__ bind(&miss);
|
__ bind(&miss);
|
||||||
StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
|
StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
|
||||||
|
@ -215,7 +215,7 @@ static void GenerateStringCheck(MacroAssembler* masm,
|
|||||||
// If the receiver object is not a string or a wrapped string object the
|
// If the receiver object is not a string or a wrapped string object the
|
||||||
// execution continues at the miss label. The register containing the
|
// execution continues at the miss label. The register containing the
|
||||||
// receiver is potentially clobbered.
|
// receiver is potentially clobbered.
|
||||||
void StubCompiler::GenerateLoadStringLength2(MacroAssembler* masm,
|
void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm,
|
||||||
Register receiver,
|
Register receiver,
|
||||||
Register scratch1,
|
Register scratch1,
|
||||||
Register scratch2,
|
Register scratch2,
|
||||||
@ -1672,7 +1672,7 @@ Object* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) {
|
|||||||
__ cmp(r2, Operand(Handle<String>(name)));
|
__ cmp(r2, Operand(Handle<String>(name)));
|
||||||
__ b(ne, &miss);
|
__ b(ne, &miss);
|
||||||
|
|
||||||
GenerateLoadStringLength2(masm(), r0, r1, r3, &miss);
|
GenerateLoadStringLength(masm(), r0, r1, r3, &miss);
|
||||||
__ bind(&miss);
|
__ bind(&miss);
|
||||||
__ DecrementCounter(&Counters::keyed_load_string_length, 1, r1, r3);
|
__ DecrementCounter(&Counters::keyed_load_string_length, 1, r1, r3);
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ void LoadIC::GenerateStringLength(MacroAssembler* masm) {
|
|||||||
|
|
||||||
__ mov(eax, Operand(esp, kPointerSize));
|
__ mov(eax, Operand(esp, kPointerSize));
|
||||||
|
|
||||||
StubCompiler::GenerateLoadStringLength(masm, eax, edx, &miss);
|
StubCompiler::GenerateLoadStringLength(masm, eax, edx, ebx, &miss);
|
||||||
__ bind(&miss);
|
__ bind(&miss);
|
||||||
StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
|
StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
|
||||||
}
|
}
|
||||||
|
@ -226,13 +226,14 @@ static void GenerateStringCheck(MacroAssembler* masm,
|
|||||||
|
|
||||||
void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm,
|
void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm,
|
||||||
Register receiver,
|
Register receiver,
|
||||||
Register scratch,
|
Register scratch1,
|
||||||
|
Register scratch2,
|
||||||
Label* miss) {
|
Label* miss) {
|
||||||
Label load_length, check_wrapper;
|
Label load_length, check_wrapper;
|
||||||
|
|
||||||
// Check if the object is a string leaving the instance type in the
|
// Check if the object is a string leaving the instance type in the
|
||||||
// scratch register.
|
// scratch register.
|
||||||
GenerateStringCheck(masm, receiver, scratch, miss, &check_wrapper);
|
GenerateStringCheck(masm, receiver, scratch1, miss, &check_wrapper);
|
||||||
|
|
||||||
// Load length from the string and convert to a smi.
|
// Load length from the string and convert to a smi.
|
||||||
__ bind(&load_length);
|
__ bind(&load_length);
|
||||||
@ -242,13 +243,13 @@ void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm,
|
|||||||
|
|
||||||
// Check if the object is a JSValue wrapper.
|
// Check if the object is a JSValue wrapper.
|
||||||
__ bind(&check_wrapper);
|
__ bind(&check_wrapper);
|
||||||
__ cmp(scratch, JS_VALUE_TYPE);
|
__ cmp(scratch1, JS_VALUE_TYPE);
|
||||||
__ j(not_equal, miss, not_taken);
|
__ j(not_equal, miss, not_taken);
|
||||||
|
|
||||||
// Check if the wrapped value is a string and load the length
|
// Check if the wrapped value is a string and load the length
|
||||||
// directly if it is.
|
// directly if it is.
|
||||||
__ mov(receiver, FieldOperand(receiver, JSValue::kValueOffset));
|
__ mov(scratch2, FieldOperand(receiver, JSValue::kValueOffset));
|
||||||
GenerateStringCheck(masm, receiver, scratch, miss, miss);
|
GenerateStringCheck(masm, scratch2, scratch1, miss, miss);
|
||||||
__ jmp(&load_length);
|
__ jmp(&load_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1773,7 +1774,7 @@ Object* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) {
|
|||||||
__ cmp(Operand(eax), Immediate(Handle<String>(name)));
|
__ cmp(Operand(eax), Immediate(Handle<String>(name)));
|
||||||
__ j(not_equal, &miss, not_taken);
|
__ j(not_equal, &miss, not_taken);
|
||||||
|
|
||||||
GenerateLoadStringLength(masm(), ecx, edx, &miss);
|
GenerateLoadStringLength(masm(), ecx, edx, ebx, &miss);
|
||||||
__ bind(&miss);
|
__ bind(&miss);
|
||||||
__ DecrementCounter(&Counters::keyed_load_string_length, 1);
|
__ DecrementCounter(&Counters::keyed_load_string_length, 1);
|
||||||
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
|
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
|
||||||
|
@ -355,10 +355,6 @@ class StubCompiler BASE_EMBEDDED {
|
|||||||
Register scratch,
|
Register scratch,
|
||||||
Label* miss_label);
|
Label* miss_label);
|
||||||
static void GenerateLoadStringLength(MacroAssembler* masm,
|
static void GenerateLoadStringLength(MacroAssembler* masm,
|
||||||
Register receiver,
|
|
||||||
Register scratch,
|
|
||||||
Label* miss_label);
|
|
||||||
static void GenerateLoadStringLength2(MacroAssembler* masm,
|
|
||||||
Register receiver,
|
Register receiver,
|
||||||
Register scratch1,
|
Register scratch1,
|
||||||
Register scratch2,
|
Register scratch2,
|
||||||
|
@ -1302,7 +1302,7 @@ void LoadIC::GenerateStringLength(MacroAssembler* masm) {
|
|||||||
|
|
||||||
__ movq(rax, Operand(rsp, kPointerSize));
|
__ movq(rax, Operand(rsp, kPointerSize));
|
||||||
|
|
||||||
StubCompiler::GenerateLoadStringLength(masm, rax, rdx, &miss);
|
StubCompiler::GenerateLoadStringLength(masm, rax, rdx, rbx, &miss);
|
||||||
__ bind(&miss);
|
__ bind(&miss);
|
||||||
StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
|
StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
|
||||||
}
|
}
|
||||||
|
@ -314,13 +314,14 @@ static void GenerateStringCheck(MacroAssembler* masm,
|
|||||||
|
|
||||||
void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm,
|
void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm,
|
||||||
Register receiver,
|
Register receiver,
|
||||||
Register scratch,
|
Register scratch1,
|
||||||
|
Register scratch2,
|
||||||
Label* miss) {
|
Label* miss) {
|
||||||
Label load_length, check_wrapper;
|
Label load_length, check_wrapper;
|
||||||
|
|
||||||
// Check if the object is a string leaving the instance type in the
|
// Check if the object is a string leaving the instance type in the
|
||||||
// scratch register.
|
// scratch register.
|
||||||
GenerateStringCheck(masm, receiver, scratch, miss, &check_wrapper);
|
GenerateStringCheck(masm, receiver, scratch1, miss, &check_wrapper);
|
||||||
|
|
||||||
// Load length directly from the string.
|
// Load length directly from the string.
|
||||||
__ bind(&load_length);
|
__ bind(&load_length);
|
||||||
@ -330,13 +331,14 @@ void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm,
|
|||||||
|
|
||||||
// Check if the object is a JSValue wrapper.
|
// Check if the object is a JSValue wrapper.
|
||||||
__ bind(&check_wrapper);
|
__ bind(&check_wrapper);
|
||||||
__ cmpl(scratch, Immediate(JS_VALUE_TYPE));
|
__ cmpl(scratch1, Immediate(JS_VALUE_TYPE));
|
||||||
__ j(not_equal, miss);
|
__ j(not_equal, miss);
|
||||||
|
|
||||||
// Check if the wrapped value is a string and load the length
|
// Check if the wrapped value is a string and load the length
|
||||||
// directly if it is.
|
// directly if it is.
|
||||||
__ movq(receiver, FieldOperand(receiver, JSValue::kValueOffset));
|
__ movq(scratch2, FieldOperand(receiver, JSValue::kValueOffset));
|
||||||
GenerateStringCheck(masm, receiver, scratch, miss, miss);
|
GenerateStringCheck(masm, scratch2, scratch1, miss, miss);
|
||||||
|
__ movq(receiver, scratch2);
|
||||||
__ jmp(&load_length);
|
__ jmp(&load_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1325,7 +1327,7 @@ Object* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) {
|
|||||||
__ Cmp(rax, Handle<String>(name));
|
__ Cmp(rax, Handle<String>(name));
|
||||||
__ j(not_equal, &miss);
|
__ j(not_equal, &miss);
|
||||||
|
|
||||||
GenerateLoadStringLength(masm(), rcx, rdx, &miss);
|
GenerateLoadStringLength(masm(), rcx, rdx, rbx, &miss);
|
||||||
__ bind(&miss);
|
__ bind(&miss);
|
||||||
__ DecrementCounter(&Counters::keyed_load_string_length, 1);
|
__ DecrementCounter(&Counters::keyed_load_string_length, 1);
|
||||||
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
|
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
|
||||||
|
Loading…
Reference in New Issue
Block a user