 Chromium Code Reviews
 Chromium Code Reviews Issue 8187:
  Serendipitously arrange the tags so that String.length() becomes a branch-fre...  (Closed) 
  Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
    
  
    Issue 8187:
  Serendipitously arrange the tags so that String.length() becomes a branch-fre...  (Closed) 
  Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/| Index: src/stub-cache-ia32.cc | 
| =================================================================== | 
| --- src/stub-cache-ia32.cc (revision 595) | 
| +++ src/stub-cache-ia32.cc (working copy) | 
| @@ -159,69 +159,29 @@ | 
| } | 
| -void StubCompiler::GenerateLoadShortStringLength(MacroAssembler* masm, | 
| - Register receiver, | 
| - Register scratch, | 
| - Label* miss_label) { | 
| +void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm, | 
| + Register receiver, | 
| + Register scratch, | 
| + Label* miss_label) { | 
| // Check that the receiver isn't a smi. | 
| __ test(receiver, Immediate(kSmiTagMask)); | 
| __ j(zero, miss_label, not_taken); | 
| - // Check that the object is a short string. | 
| + // Check that the object is a string. | 
| __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 
| __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | 
| - __ and_(scratch, kIsNotStringMask | kStringSizeMask); | 
| - __ cmp(scratch, kStringTag | kShortStringTag); | 
| - __ j(not_equal, miss_label, not_taken); | 
| + ASSERT(kNotStringTag != 0); | 
| + __ test(scratch, Immediate(kNotStringTag)); | 
| + __ j(not_zero, miss_label, not_taken); | 
| - // Load length directly from the string. | 
| - __ mov(eax, FieldOperand(receiver, String::kLengthOffset)); | 
| - __ shr(eax, String::kShortLengthShift); | 
| - __ shl(eax, kSmiTagSize); | 
| - __ ret(0); | 
| -} | 
| + __ and_(scratch, kStringSizeMask); | 
| -void StubCompiler::GenerateLoadMediumStringLength(MacroAssembler* masm, | 
| - Register receiver, | 
| - Register scratch, | 
| - Label* miss_label) { | 
| - // Check that the receiver isn't a smi. | 
| - __ test(receiver, Immediate(kSmiTagMask)); | 
| - __ j(zero, miss_label, not_taken); | 
| - | 
| - // Check that the object is a short string. | 
| - __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 
| - __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | 
| - __ and_(scratch, kIsNotStringMask | kStringSizeMask); | 
| - __ cmp(scratch, kStringTag | kMediumStringTag); | 
| - __ j(not_equal, miss_label, not_taken); | 
| - | 
| // Load length directly from the string. | 
| __ mov(eax, FieldOperand(receiver, String::kLengthOffset)); | 
| - __ shr(eax, String::kMediumLengthShift); | 
| - __ shl(eax, kSmiTagSize); | 
| - __ ret(0); | 
| -} | 
| - | 
| -void StubCompiler::GenerateLoadLongStringLength(MacroAssembler* masm, | 
| - Register receiver, | 
| - Register scratch, | 
| - Label* miss_label) { | 
| - // Check that the receiver isn't a smi. | 
| - __ test(receiver, Immediate(kSmiTagMask)); | 
| - __ j(zero, miss_label, not_taken); | 
| - | 
| - // Check that the object is a short string. | 
| - __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 
| - __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | 
| - __ and_(scratch, kIsNotStringMask | kStringSizeMask); | 
| - __ cmp(scratch, kStringTag | kLongStringTag); | 
| - __ j(not_equal, miss_label, not_taken); | 
| - | 
| - // Load length directly from the string. | 
| - __ mov(eax, FieldOperand(receiver, String::kLengthOffset)); | 
| - __ shr(eax, String::kLongLengthShift); | 
| + // Ecx is also the receiver. | 
| 
Mads Ager (chromium)
2008/10/27 09:37:00
Ecx -> ecx since it is a register name?
 | 
| + __ lea(ecx, Operand(scratch, String::kLongLengthShift)); | 
| + __ shr(eax); // Ecx is implicit shift register. | 
| 
Mads Ager (chromium)
2008/10/27 09:37:00
Ditto?
 | 
| __ shl(eax, kSmiTagSize); | 
| __ ret(0); | 
| } | 
| @@ -1153,7 +1113,7 @@ | 
| } | 
| -Object* KeyedLoadStubCompiler::CompileLoadShortStringLength(String* name) { | 
| +Object* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { | 
| // ----------- S t a t e ------------- | 
| // -- esp[0] : return address | 
| // -- esp[4] : name | 
| @@ -1170,7 +1130,7 @@ | 
| __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 
| __ j(not_equal, &miss, not_taken); | 
| - GenerateLoadShortStringLength(masm(), ecx, edx, &miss); | 
| + GenerateLoadStringLength(masm(), ecx, edx, &miss); | 
| __ bind(&miss); | 
| __ DecrementCounter(&Counters::keyed_load_string_length, 1); | 
| GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| @@ -1180,60 +1140,6 @@ | 
| } | 
| -Object* KeyedLoadStubCompiler::CompileLoadMediumStringLength(String* name) { | 
| - // ----------- S t a t e ------------- | 
| - // -- esp[0] : return address | 
| - // -- esp[4] : name | 
| - // -- esp[8] : receiver | 
| - // ----------------------------------- | 
| - HandleScope scope; | 
| - Label miss; | 
| - | 
| - __ mov(eax, (Operand(esp, kPointerSize))); | 
| - __ mov(ecx, (Operand(esp, 2 * kPointerSize))); | 
| - __ IncrementCounter(&Counters::keyed_load_string_length, 1); | 
| - | 
| - // Check that the name has not changed. | 
| - __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 
| - __ j(not_equal, &miss, not_taken); | 
| - | 
| - GenerateLoadMediumStringLength(masm(), ecx, edx, &miss); | 
| - __ bind(&miss); | 
| - __ DecrementCounter(&Counters::keyed_load_string_length, 1); | 
| - GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| - | 
| - // Return the generated code. | 
| - return GetCode(CALLBACKS); | 
| -} | 
| - | 
| - | 
| -Object* KeyedLoadStubCompiler::CompileLoadLongStringLength(String* name) { | 
| - // ----------- S t a t e ------------- | 
| - // -- esp[0] : return address | 
| - // -- esp[4] : name | 
| - // -- esp[8] : receiver | 
| - // ----------------------------------- | 
| - HandleScope scope; | 
| - Label miss; | 
| - | 
| - __ mov(eax, (Operand(esp, kPointerSize))); | 
| - __ mov(ecx, (Operand(esp, 2 * kPointerSize))); | 
| - __ IncrementCounter(&Counters::keyed_load_string_length, 1); | 
| - | 
| - // Check that the name has not changed. | 
| - __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 
| - __ j(not_equal, &miss, not_taken); | 
| - | 
| - GenerateLoadLongStringLength(masm(), ecx, edx, &miss); | 
| - __ bind(&miss); | 
| - __ DecrementCounter(&Counters::keyed_load_string_length, 1); | 
| - GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| - | 
| - // Return the generated code. | 
| - return GetCode(CALLBACKS); | 
| -} | 
| - | 
| - | 
| Object* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { | 
| // ----------- S t a t e ------------- | 
| // -- esp[0] : return address |