Chromium Code Reviews| Index: src/ia32/codegen-ia32.cc | 
| diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc | 
| index bbbcd3a09a9002d2d067cff4ea1f866606ec91ce..9a4f472abdb8f0010cd0fafaf1b26bf3152e2726 100644 | 
| --- a/src/ia32/codegen-ia32.cc | 
| +++ b/src/ia32/codegen-ia32.cc | 
| @@ -6523,7 +6523,7 @@ void CodeGenerator::GenerateStringCompare(ZoneList<Expression*>* args) { | 
| void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) { | 
| - ASSERT_EQ(args->length(), 4); | 
| + ASSERT_EQ(4, args->length()); | 
| // Load the arguments on the stack and call the stub. | 
| Load(args->at(0)); | 
| @@ -6536,6 +6536,95 @@ void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) { | 
| } | 
| +void CodeGenerator::GenerateRegExpConstructResult(ZoneList<Expression*>* args) { | 
| + // No stub. This code only occurs a few times in regexp.js. | 
| + const int kMaxInlineLength = 100; | 
| + ASSERT_EQ(3, args->length()); | 
| + Load(args->at(0)); // Size of array, smi. | 
| + Load(args->at(1)); // "index" property value. | 
| + Load(args->at(2)); // "input" property value. | 
| + { | 
| + VirtualFrame::SpilledScope spilled_scope; | 
| + | 
| + Label slowcase; | 
| + Label done; | 
| + __ mov(ebx, Operand(esp, kPointerSize * 2)); | 
| + __ test(ebx, Immediate(0x01)); | 
| 
 
Søren Thygesen Gjesse
2010/04/13 07:22:29
kHeapObjectTag?
 
Lasse Reichstein
2010/04/13 09:50:56
Changed to kSmiTagMask.
 
 | 
| + __ j(not_zero, &slowcase); | 
| + __ cmp(Operand(ebx), Immediate(Smi::FromInt(kMaxInlineLength))); | 
| + __ j(above, &slowcase); | 
| + // Smi-tagging is equivalent to multiplying by 2. | 
| + STATIC_ASSERT(kSmiTag == 0); | 
| + STATIC_ASSERT(kSmiTagSize == 1); | 
| + // Allocate RegExpResult followed by FixedArray with size in ebx. | 
| + // JSArray: [Map][empty properties][Elements][Length-smi][index][input] | 
| + // Elements: [Map][Length][..elements..] | 
| + __ AllocateInNewSpace(JSArray::kRegExpResultSize + FixedArray::kHeaderSize, | 
| 
 
Søren Thygesen Gjesse
2010/04/13 07:22:29
JSArray::kRegExpResultSize -> JSRegExpResult::kSiz
 
 | 
| + times_half_pointer_size, | 
| 
 
Lasse Reichstein
2010/04/13 09:50:56
Done.
 
 | 
| + ebx, // In: Number of elements (times 2, being a smi) | 
| + eax, // Out: Start of allocation (tagged). | 
| + ecx, // Out: End of allocation. | 
| + edx, // Scratch register | 
| + &slowcase, | 
| + TAG_OBJECT); | 
| + // eax: Start of allocated area, object-tagged. | 
| + | 
| + // Set JSArray map to global.regexp_result_map(). | 
| + // Set empty properties FixedArray. | 
| + // Set elements to point to FixedArray allocated right after the JSArray. | 
| + // Interleave operations for better latency. | 
| + __ mov(edx, ContextOperand(esi, Context::GLOBAL_INDEX)); | 
| + __ mov(ecx, Immediate(Factory::empty_fixed_array())); | 
| + __ lea(ebx, Operand(eax, JSArray::kRegExpResultSize)); | 
| + __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalContextOffset)); | 
| + __ mov(FieldOperand(eax, JSObject::kElementsOffset), ebx); | 
| + __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ecx); | 
| + __ mov(edx, ContextOperand(edx, Context::REGEXP_RESULT_MAP_INDEX)); | 
| + __ mov(FieldOperand(eax, HeapObject::kMapOffset), edx); | 
| + | 
| + // Set input, index and length fields from arguments. | 
| + __ pop(FieldOperand(eax, JSArray::kSize + kPointerSize)); | 
| 
 
Søren Thygesen Gjesse
2010/04/13 07:22:29
Please add constants JSRegExpResult::kIndexOffset
 
Lasse Reichstein
2010/04/13 09:50:56
Done.
 
 | 
| + __ pop(FieldOperand(eax, JSArray::kSize)); | 
| + __ pop(ecx); | 
| + __ mov(FieldOperand(eax, JSArray::kLengthOffset), ecx); | 
| + | 
| + // Fill out the elements FixedArray. | 
| + // eax: JSArray. | 
| + // ebx: FixedArray. | 
| + // ecx: Number of elements in array, as smi. | 
| + | 
| + // Set map. | 
| + __ mov(FieldOperand(ebx, HeapObject::kMapOffset), | 
| + Immediate(Factory::fixed_array_map())); | 
| + // Set length. | 
| + __ SmiUntag(ecx); | 
| + __ mov(FieldOperand(ebx, FixedArray::kLengthOffset), ecx); | 
| + // Fill contents of fixed-array with the-hole. | 
| + __ mov(edx, Immediate(Factory::the_hole_value())); | 
| + __ lea(ebx, FieldOperand(ebx, FixedArray::kHeaderSize)); | 
| + // Fill fixed array elements with hole. | 
| + // eax: JSArray. | 
| + // ecx: Number of elements to fill. | 
| + // ebx: Start of elements in FixedArray. | 
| + // edx: the hole. | 
| + Label loop; | 
| + __ test(ecx, Operand(ecx)); | 
| + __ bind(&loop); | 
| + __ j(less_equal, &done); // Jump if ecx is negative or zero. | 
| + __ sub(Operand(ecx), Immediate(1)); | 
| + __ mov(Operand(ebx, ecx, times_pointer_size, 0), edx); | 
| + __ jmp(&loop); | 
| + | 
| + __ bind(&slowcase); | 
| + __ CallRuntime(Runtime::kRegExpConstructResult, 3); | 
| + | 
| + __ bind(&done); | 
| + } | 
| + frame_->Forget(3); | 
| + frame_->Push(eax); | 
| +} | 
| + | 
| + | 
| void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) { | 
| ASSERT_EQ(args->length(), 1); |