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