Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(571)

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 545151: Add support for two byte strings in direct call to RegExp... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 8089 matching lines...) Expand 10 before | Expand all | Expand 10 after
8100 return; 8100 return;
8101 } 8101 }
8102 8102
8103 // Stack frame on entry. 8103 // Stack frame on entry.
8104 // esp[0]: return address 8104 // esp[0]: return address
8105 // esp[4]: last_match_info (expected JSArray) 8105 // esp[4]: last_match_info (expected JSArray)
8106 // esp[8]: previous index 8106 // esp[8]: previous index
8107 // esp[12]: subject string 8107 // esp[12]: subject string
8108 // esp[16]: JSRegExp object 8108 // esp[16]: JSRegExp object
8109 8109
8110 Label runtime; 8110 static const int kLastMatchInfoOffset = 1 * kPointerSize;
8111 static const int kPreviousIndexOffset = 2 * kPointerSize;
8112 static const int kSubjectOffset = 3 * kPointerSize;
8113 static const int kJSRegExpOffset = 4 * kPointerSize;
8114
8115 Label runtime, invoke_regexp;
8116
8117 // Ensure that a RegExp stack is allocated.
8118 ExternalReference address_of_regexp_stack_memory_address =
8119 ExternalReference::address_of_regexp_stack_memory_address();
8120 ExternalReference address_of_regexp_stack_memory_size =
8121 ExternalReference::address_of_regexp_stack_memory_size();
8122 __ mov(ebx, Operand::StaticVariable(address_of_regexp_stack_memory_size));
8123 __ test(ebx, Operand(ebx));
8124 __ j(zero, &runtime, not_taken);
8111 8125
8112 // Check that the first argument is a JSRegExp object. 8126 // Check that the first argument is a JSRegExp object.
8113 __ mov(eax, Operand(esp, 4 * kPointerSize)); 8127 __ mov(eax, Operand(esp, kJSRegExpOffset));
8114 ASSERT_EQ(0, kSmiTag); 8128 ASSERT_EQ(0, kSmiTag);
8115 __ test(eax, Immediate(kSmiTagMask)); 8129 __ test(eax, Immediate(kSmiTagMask));
8116 __ j(zero, &runtime); 8130 __ j(zero, &runtime);
8117 __ CmpObjectType(eax, JS_REGEXP_TYPE, ecx); 8131 __ CmpObjectType(eax, JS_REGEXP_TYPE, ecx);
8118 __ j(not_equal, &runtime); 8132 __ j(not_equal, &runtime);
8119 // Check that the RegExp has been compiled (data contains a fixed array). 8133 // Check that the RegExp has been compiled (data contains a fixed array).
8120 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); 8134 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset));
8121 #ifdef DEBUG 8135 #ifdef DEBUG
8122 __ test(ecx, Immediate(kSmiTagMask)); 8136 __ test(ecx, Immediate(kSmiTagMask));
8123 __ Check(not_zero, "Unexpected type for RegExp data, FixedArray expected"); 8137 __ Check(not_zero, "Unexpected type for RegExp data, FixedArray expected");
(...skipping 15 matching lines...) Expand all
8139 ASSERT_EQ(0, kSmiTag); 8153 ASSERT_EQ(0, kSmiTag);
8140 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); 8154 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize);
8141 __ add(Operand(edx), Immediate(2)); // edx was a smi. 8155 __ add(Operand(edx), Immediate(2)); // edx was a smi.
8142 // Check that the static offsets vector buffer is large enough. 8156 // Check that the static offsets vector buffer is large enough.
8143 __ cmp(edx, OffsetsVector::kStaticOffsetsVectorSize); 8157 __ cmp(edx, OffsetsVector::kStaticOffsetsVectorSize);
8144 __ j(above, &runtime); 8158 __ j(above, &runtime);
8145 8159
8146 // ecx: RegExp data (FixedArray) 8160 // ecx: RegExp data (FixedArray)
8147 // edx: Number of capture registers 8161 // edx: Number of capture registers
8148 // Check that the second argument is a string. 8162 // Check that the second argument is a string.
8149 __ mov(eax, Operand(esp, 3 * kPointerSize)); 8163 __ mov(eax, Operand(esp, kSubjectOffset));
8150 __ test(eax, Immediate(kSmiTagMask)); 8164 __ test(eax, Immediate(kSmiTagMask));
8151 __ j(zero, &runtime); 8165 __ j(zero, &runtime);
8152 Condition is_string = masm->IsObjectStringType(eax, ebx, ebx); 8166 Condition is_string = masm->IsObjectStringType(eax, ebx, ebx);
8153 __ j(NegateCondition(is_string), &runtime); 8167 __ j(NegateCondition(is_string), &runtime);
8154 // Get the length of the string to ebx. 8168 // Get the length of the string to ebx.
8155 __ mov(ebx, FieldOperand(eax, String::kLengthOffset)); 8169 __ mov(ebx, FieldOperand(eax, String::kLengthOffset));
8156 8170
8157 // ebx: Length of subject string 8171 // ebx: Length of subject string
8158 // ecx: RegExp data (FixedArray) 8172 // ecx: RegExp data (FixedArray)
8159 // edx: Number of capture registers 8173 // edx: Number of capture registers
8160 // Check that the third argument is a positive smi. 8174 // Check that the third argument is a positive smi.
8161 __ mov(eax, Operand(esp, 2 * kPointerSize)); 8175 __ mov(eax, Operand(esp, kPreviousIndexOffset));
8162 __ test(eax, Immediate(kSmiTagMask | 0x80000000)); 8176 __ test(eax, Immediate(kSmiTagMask | 0x80000000));
8163 __ j(not_zero, &runtime); 8177 __ j(not_zero, &runtime);
8164 // Check that it is not greater than the subject string length. 8178 // Check that it is not greater than the subject string length.
8165 __ SmiUntag(eax); 8179 __ SmiUntag(eax);
8166 __ cmp(eax, Operand(ebx)); 8180 __ cmp(eax, Operand(ebx));
8167 __ j(greater, &runtime); 8181 __ j(greater, &runtime);
8168 8182
8169 // ecx: RegExp data (FixedArray) 8183 // ecx: RegExp data (FixedArray)
8170 // edx: Number of capture registers 8184 // edx: Number of capture registers
8171 // Check that the fourth object is a JSArray object. 8185 // Check that the fourth object is a JSArray object.
8172 __ mov(eax, Operand(esp, 1 * kPointerSize)); 8186 __ mov(eax, Operand(esp, kLastMatchInfoOffset));
8173 __ test(eax, Immediate(kSmiTagMask)); 8187 __ test(eax, Immediate(kSmiTagMask));
8174 __ j(zero, &runtime); 8188 __ j(zero, &runtime);
8175 __ CmpObjectType(eax, JS_ARRAY_TYPE, ebx); 8189 __ CmpObjectType(eax, JS_ARRAY_TYPE, ebx);
8176 __ j(not_equal, &runtime); 8190 __ j(not_equal, &runtime);
8177 // Check that the JSArray is in fast case. 8191 // Check that the JSArray is in fast case.
8178 __ mov(ebx, FieldOperand(eax, JSArray::kElementsOffset)); 8192 __ mov(ebx, FieldOperand(eax, JSArray::kElementsOffset));
8179 __ mov(eax, FieldOperand(ebx, HeapObject::kMapOffset)); 8193 __ mov(eax, FieldOperand(ebx, HeapObject::kMapOffset));
8180 __ cmp(eax, Factory::fixed_array_map()); 8194 __ cmp(eax, Factory::fixed_array_map());
8181 __ j(not_equal, &runtime); 8195 __ j(not_equal, &runtime);
8182 // Check that the last match info has space for the capture registers and the 8196 // Check that the last match info has space for the capture registers and the
8183 // additional information. 8197 // additional information.
8184 __ mov(eax, FieldOperand(ebx, FixedArray::kLengthOffset)); 8198 __ mov(eax, FieldOperand(ebx, FixedArray::kLengthOffset));
8185 __ add(Operand(edx), Immediate(RegExpImpl::kLastMatchOverhead)); 8199 __ add(Operand(edx), Immediate(RegExpImpl::kLastMatchOverhead));
8186 __ cmp(edx, Operand(eax)); 8200 __ cmp(edx, Operand(eax));
8187 __ j(greater, &runtime); 8201 __ j(greater, &runtime);
8188 8202
8189 // ecx: RegExp data (FixedArray) 8203 // ecx: RegExp data (FixedArray)
8190 // Check the representation and encoding of the subject string (only support 8204 // Check the representation and encoding of the subject string.
8191 // flat ascii strings). 8205 Label seq_string, seq_two_byte_string, check_code;
8192 __ mov(eax, Operand(esp, 3 * kPointerSize)); 8206 const int kStringRepresentationEncodingMask =
8207 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
8208 __ mov(eax, Operand(esp, kSubjectOffset));
8193 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 8209 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
8194 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 8210 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
8195 __ and_(ebx, kStringRepresentationMask | kStringEncodingMask); 8211 __ and_(ebx, kStringRepresentationEncodingMask);
8196 __ cmp(ebx, kSeqStringTag | kAsciiStringTag); 8212 // First check for sequential string.
8213 ASSERT_EQ(0, kStringTag);
8214 ASSERT_EQ(0, kSeqStringTag);
8215 __ test(Operand(ebx),
8216 Immediate(kIsNotStringMask | kStringRepresentationMask));
8217 __ j(zero, &seq_string);
8218
8219 // Check for flat cons string.
8220 // A flat cons string is a cons string where the second part is the empty
8221 // string. In that case the subject string is just the first part of the cons
8222 // string. Also in this case the first part of the cons string is known to be
8223 // a sequential string.
8224 __ mov(edx, ebx);
8225 __ and_(edx, kStringRepresentationMask);
8226 __ cmp(edx, kConsStringTag);
8197 __ j(not_equal, &runtime); 8227 __ j(not_equal, &runtime);
8228 __ mov(edx, FieldOperand(eax, ConsString::kSecondOffset));
8229 __ cmp(Operand(edx), Immediate(Handle<String>(Heap::empty_string())));
8230 __ j(not_equal, &runtime);
8231 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset));
8232 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
8233 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
8234 __ and_(ebx, kStringRepresentationEncodingMask);
8198 8235
8199 // ecx: RegExp data (FixedArray) 8236 __ bind(&seq_string);
8200 // Ensure that a RegExp stack is allocated. 8237 // eax: subject string (sequential either ascii to two byte)
8201 ExternalReference address_of_regexp_stack_memory_address = 8238 // ebx: suject string type & kStringRepresentationEncodingMask
8202 ExternalReference::address_of_regexp_stack_memory_address();
8203 ExternalReference address_of_regexp_stack_memory_size =
8204 ExternalReference::address_of_regexp_stack_memory_size();
8205 __ mov(eax, Operand::StaticVariable(address_of_regexp_stack_memory_size));
8206 __ test(eax, Operand(eax));
8207 __ j(zero, &runtime, not_taken);
8208
8209 // ecx: RegExp data (FixedArray) 8239 // ecx: RegExp data (FixedArray)
8210 // Check that the irregexp code has been generated for an ascii string. If 8240 // Check that the irregexp code has been generated for an ascii string. If
8211 // it has the field contains a code object otherwise it contains the hole. 8241 // it has, the field contains a code object otherwise it contains the hole.
8242 __ cmp(ebx, kStringTag | kSeqStringTag | kTwoByteStringTag);
8243 __ j(equal, &seq_two_byte_string);
8244 #ifdef DEBUG
8245 __ cmp(ebx, kStringTag | kSeqStringTag | kAsciiStringTag);
8246 __ Check(equal, "Expected sequential ascii string");
8247 #endif
8212 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataAsciiCodeOffset)); 8248 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataAsciiCodeOffset));
8249 __ Set(edi, Immediate(1)); // Type is ascii.
8250 __ jmp(&check_code);
8251
8252 __ bind(&seq_two_byte_string);
8253 // eax: subject string
8254 // ecx: RegExp data (FixedArray)
8255 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset));
8256 __ Set(edi, Immediate(0)); // Type is two byte.
8257
8258 __ bind(&check_code);
8259 // Check that the irregexp code has been generated for If it has, the field
8260 // contains a code object otherwise it contains the hole.
8213 __ CmpObjectType(edx, CODE_TYPE, ebx); 8261 __ CmpObjectType(edx, CODE_TYPE, ebx);
8214 __ j(not_equal, &runtime); 8262 __ j(not_equal, &runtime);
8215 8263
8264 // eax: subject string
8265 // edx: code
8266 // edi: encoding of subject string (1 if ascii 0 if two_byte);
8216 // Load used arguments before starting to push arguments for call to native 8267 // Load used arguments before starting to push arguments for call to native
8217 // RegExp code to avoid handling changing stack height. 8268 // RegExp code to avoid handling changing stack height.
8218 __ mov(eax, Operand(esp, 3 * kPointerSize)); // Subject string. 8269 __ mov(ebx, Operand(esp, kPreviousIndexOffset));
8219 __ mov(ebx, Operand(esp, 2 * kPointerSize)); // Previous index. 8270 __ mov(ecx, Operand(esp, kJSRegExpOffset));
8220 __ mov(ecx, Operand(esp, 4 * kPointerSize)); // JSRegExp object. 8271 __ SmiUntag(ebx); // Previous index from smi.
8221 __ SmiUntag(ebx); // Previous index from sim.
8222 8272
8223 // eax: subject string 8273 // eax: subject string
8224 // ebx: previous index 8274 // ebx: previous index
8225 // edx: code 8275 // edx: code
8226 // All checks done. Now push arguments for native regexp code. 8276 // All checks done. Now push arguments for native regexp code.
8227 __ IncrementCounter(&Counters::regexp_entry_native, 1); 8277 __ IncrementCounter(&Counters::regexp_entry_native, 1);
8228 8278
8229 // Argument 8: Indicate that this is a direct call from JavaScript. 8279 // Argument 8: Indicate that this is a direct call from JavaScript.
8230 __ push(Immediate(1)); 8280 __ push(Immediate(1));
8231 8281
8232 // Argument 7: Start (high end) of backtracking stack memory area. 8282 // Argument 7: Start (high end) of backtracking stack memory area.
8233 __ mov(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_address)); 8283 __ mov(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_address));
8234 __ add(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_size)); 8284 __ add(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_size));
8235 __ push(ecx); 8285 __ push(ecx);
8236 8286
8237 // Argument 6: At start of string? 8287 // Argument 6: At start of string?
8238 __ xor_(Operand(ecx), ecx); // setcc only operated on cl (lower byte of ecx). 8288 __ xor_(Operand(ecx), ecx); // setcc only operated on cl (lower byte of ecx).
8239 __ test(ebx, Operand(ebx)); 8289 __ test(ebx, Operand(ebx));
8240 __ setcc(zero, ecx); // 1 if 0 (start of string), 0 if positive. 8290 __ setcc(zero, ecx); // 1 if 0 (start of string), 0 if positive.
8241 __ push(ecx); 8291 __ push(ecx);
8242 8292
8243 // Argument 5: static offsets vector buffer. 8293 // Argument 5: static offsets vector buffer.
8244 __ push(Immediate(ExternalReference::address_of_static_offsets_vector())); 8294 __ push(Immediate(ExternalReference::address_of_static_offsets_vector()));
8245 8295
8246 // Argument 4: End of string data. 8296 // Argument 4: End of string data
8247 __ mov(ecx, FieldOperand(eax, String::kLengthOffset)); 8297 // Argument 3: Start of string data
8248 __ add(ecx, Operand(eax)); 8298 Label push_two_byte, push_rest;
8249 __ add(Operand(ecx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); 8299 __ test(edi, Operand(edi));
8250 __ push(ecx); 8300 __ mov(edi, FieldOperand(eax, String::kLengthOffset));
8301 __ j(zero, &push_two_byte);
8302 __ lea(ecx, FieldOperand(eax, edi, times_1, SeqAsciiString::kHeaderSize));
8303 __ push(ecx); // Argument 4.
8304 __ lea(ecx, FieldOperand(eax, ebx, times_1, SeqAsciiString::kHeaderSize));
8305 __ push(ecx); // Argument 3.
8306 __ jmp(&push_rest);
8251 8307
8252 // Argument 3: Start of string data. 8308 __ bind(&push_two_byte);
8253 __ mov(ecx, ebx); 8309 ASSERT(kShortSize == 2);
8254 __ add(ebx, Operand(eax)); // String is ASCII. 8310 __ lea(ecx, FieldOperand(eax, edi, times_2, SeqTwoByteString::kHeaderSize));
8255 __ add(Operand(ebx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); 8311 __ push(ecx); // Argument 4.
8256 __ push(ebx); 8312 __ lea(ecx, FieldOperand(eax, ebx, times_2, SeqTwoByteString::kHeaderSize));
8313 __ push(ecx); // Argument 3.
8314
8315 __ bind(&push_rest);
8257 8316
8258 // Argument 2: Previous index. 8317 // Argument 2: Previous index.
8259 __ push(ecx); 8318 __ push(ebx);
8260 8319
8261 // Argument 1: Subject string. 8320 // Argument 1: Subject string.
8262 __ push(eax); 8321 __ push(eax);
8263 8322
8264 // Locate the code entry and call it. 8323 // Locate the code entry and call it.
8265 __ add(Operand(edx), Immediate(Code::kHeaderSize - kHeapObjectTag)); 8324 __ add(Operand(edx), Immediate(Code::kHeaderSize - kHeapObjectTag));
8266 __ call(Operand(edx)); 8325 __ call(Operand(edx));
8267 // Remove arguments. 8326 // Remove arguments.
8268 __ add(Operand(esp), Immediate(8 * kPointerSize)); 8327 __ add(Operand(esp), Immediate(8 * kPointerSize));
8269 8328
(...skipping 15 matching lines...) Expand all
8285 Operand::StaticVariable(ExternalReference::the_hole_value_location())); 8344 Operand::StaticVariable(ExternalReference::the_hole_value_location()));
8286 __ cmp(eax, Operand::StaticVariable(pending_exception)); 8345 __ cmp(eax, Operand::StaticVariable(pending_exception));
8287 __ j(equal, &runtime); 8346 __ j(equal, &runtime);
8288 __ bind(&failure); 8347 __ bind(&failure);
8289 // For failure and exception return null. 8348 // For failure and exception return null.
8290 __ mov(Operand(eax), Factory::null_value()); 8349 __ mov(Operand(eax), Factory::null_value());
8291 __ ret(4 * kPointerSize); 8350 __ ret(4 * kPointerSize);
8292 8351
8293 // Load RegExp data. 8352 // Load RegExp data.
8294 __ bind(&success); 8353 __ bind(&success);
8295 __ mov(eax, Operand(esp, 4 * kPointerSize)); 8354 __ mov(eax, Operand(esp, kJSRegExpOffset));
8296 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); 8355 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset));
8297 __ mov(edx, FieldOperand(ecx, JSRegExp::kIrregexpCaptureCountOffset)); 8356 __ mov(edx, FieldOperand(ecx, JSRegExp::kIrregexpCaptureCountOffset));
8298 // Calculate number of capture registers (number_of_captures + 1) * 2. 8357 // Calculate number of capture registers (number_of_captures + 1) * 2.
8299 __ add(Operand(edx), Immediate(2)); // edx was a smi. 8358 __ add(Operand(edx), Immediate(2)); // edx was a smi.
8300 8359
8301 // edx: Number of capture registers 8360 // edx: Number of capture registers
8302 // Load last_match_info which is still known to be a fast case JSArray. 8361 // Load last_match_info which is still known to be a fast case JSArray.
8303 __ mov(eax, Operand(esp, 1 * kPointerSize)); 8362 __ mov(eax, Operand(esp, kLastMatchInfoOffset));
8304 __ mov(ebx, FieldOperand(eax, JSArray::kElementsOffset)); 8363 __ mov(ebx, FieldOperand(eax, JSArray::kElementsOffset));
8305 8364
8306 // ebx: last_match_info backing store (FixedArray) 8365 // ebx: last_match_info backing store (FixedArray)
8307 // edx: number of capture registers 8366 // edx: number of capture registers
8308 // Store the capture count. 8367 // Store the capture count.
8309 __ SmiTag(edx); // Number of capture registers to smi. 8368 __ SmiTag(edx); // Number of capture registers to smi.
8310 __ mov(FieldOperand(ebx, RegExpImpl::kLastCaptureCountOffset), edx); 8369 __ mov(FieldOperand(ebx, RegExpImpl::kLastCaptureCountOffset), edx);
8311 __ SmiUntag(edx); // Number of capture registers back from smi. 8370 __ SmiUntag(edx); // Number of capture registers back from smi.
8312 // Store last subject and last input. 8371 // Store last subject and last input.
8313 __ mov(eax, Operand(esp, 3 * kPointerSize)); 8372 __ mov(eax, Operand(esp, kSubjectOffset));
8314 __ mov(FieldOperand(ebx, RegExpImpl::kLastSubjectOffset), eax); 8373 __ mov(FieldOperand(ebx, RegExpImpl::kLastSubjectOffset), eax);
8315 __ mov(ecx, ebx); 8374 __ mov(ecx, ebx);
8316 __ RecordWrite(ecx, RegExpImpl::kLastSubjectOffset, eax, edi); 8375 __ RecordWrite(ecx, RegExpImpl::kLastSubjectOffset, eax, edi);
8317 __ mov(eax, Operand(esp, 3 * kPointerSize)); 8376 __ mov(eax, Operand(esp, kSubjectOffset));
8318 __ mov(FieldOperand(ebx, RegExpImpl::kLastInputOffset), eax); 8377 __ mov(FieldOperand(ebx, RegExpImpl::kLastInputOffset), eax);
8319 __ mov(ecx, ebx); 8378 __ mov(ecx, ebx);
8320 __ RecordWrite(ecx, RegExpImpl::kLastInputOffset, eax, edi); 8379 __ RecordWrite(ecx, RegExpImpl::kLastInputOffset, eax, edi);
8321 8380
8322 // Get the static offsets vector filled by the native regexp code. 8381 // Get the static offsets vector filled by the native regexp code.
8323 ExternalReference address_of_static_offsets_vector = 8382 ExternalReference address_of_static_offsets_vector =
8324 ExternalReference::address_of_static_offsets_vector(); 8383 ExternalReference::address_of_static_offsets_vector();
8325 __ mov(ecx, Immediate(address_of_static_offsets_vector)); 8384 __ mov(ecx, Immediate(address_of_static_offsets_vector));
8326 8385
8327 // ebx: last_match_info backing store (FixedArray) 8386 // ebx: last_match_info backing store (FixedArray)
8328 // ecx: offsets vector 8387 // ecx: offsets vector
8329 // edx: number of capture registers 8388 // edx: number of capture registers
8330 Label next_capture, done; 8389 Label next_capture, done;
8331 __ mov(eax, Operand(esp, 2 * kPointerSize)); // Read previous index. 8390 __ mov(eax, Operand(esp, kPreviousIndexOffset));
8332 // Capture register counter starts from number of capture registers and 8391 // Capture register counter starts from number of capture registers and
8333 // counts down until wraping after zero. 8392 // counts down until wraping after zero.
8334 __ bind(&next_capture); 8393 __ bind(&next_capture);
8335 __ sub(Operand(edx), Immediate(1)); 8394 __ sub(Operand(edx), Immediate(1));
8336 __ j(negative, &done); 8395 __ j(negative, &done);
8337 // Read the value from the static offsets vector buffer. 8396 // Read the value from the static offsets vector buffer.
8338 __ mov(edi, Operand(ecx, edx, times_pointer_size, 0)); 8397 __ mov(edi, Operand(ecx, edx, times_pointer_size, 0));
8339 // Perform explicit shift 8398 // Perform explicit shift
8340 ASSERT_EQ(0, kSmiTag); 8399 ASSERT_EQ(0, kSmiTag);
8341 __ shl(edi, kSmiTagSize); 8400 __ shl(edi, kSmiTagSize);
8342 // Add previous index (from its stack slot) if value is not negative. 8401 // Add previous index (from its stack slot) if value is not negative.
8343 Label capture_negative; 8402 Label capture_negative;
8344 // Carry flag set by shift above. 8403 // Carry flag set by shift above.
8345 __ j(negative, &capture_negative, not_taken); 8404 __ j(negative, &capture_negative, not_taken);
8346 __ add(edi, Operand(eax)); // Add previous index (adding smi to smi). 8405 __ add(edi, Operand(eax)); // Add previous index (adding smi to smi).
8347 __ bind(&capture_negative); 8406 __ bind(&capture_negative);
8348 // Store the smi value in the last match info. 8407 // Store the smi value in the last match info.
8349 __ mov(FieldOperand(ebx, 8408 __ mov(FieldOperand(ebx,
8350 edx, 8409 edx,
8351 times_pointer_size, 8410 times_pointer_size,
8352 RegExpImpl::kFirstCaptureOffset), 8411 RegExpImpl::kFirstCaptureOffset),
8353 edi); 8412 edi);
8354 __ jmp(&next_capture); 8413 __ jmp(&next_capture);
8355 __ bind(&done); 8414 __ bind(&done);
8356 8415
8357 // Return last match info. 8416 // Return last match info.
8358 __ mov(eax, Operand(esp, 1 * kPointerSize)); 8417 __ mov(eax, Operand(esp, kLastMatchInfoOffset));
8359 __ ret(4 * kPointerSize); 8418 __ ret(4 * kPointerSize);
8360 8419
8361 // Do the runtime call to execute the regexp. 8420 // Do the runtime call to execute the regexp.
8362 __ bind(&runtime); 8421 __ bind(&runtime);
8363 __ TailCallRuntime(ExternalReference(Runtime::kRegExpExec), 4, 1); 8422 __ TailCallRuntime(ExternalReference(Runtime::kRegExpExec), 4, 1);
8364 } 8423 }
8365 8424
8366 8425
8367 void CompareStub::Generate(MacroAssembler* masm) { 8426 void CompareStub::Generate(MacroAssembler* masm) {
8368 Label call_builtin, done; 8427 Label call_builtin, done;
(...skipping 1365 matching lines...) Expand 10 before | Expand all | Expand 10 after
9734 9793
9735 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 9794 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
9736 // tagged as a small integer. 9795 // tagged as a small integer.
9737 __ bind(&runtime); 9796 __ bind(&runtime);
9738 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); 9797 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1);
9739 } 9798 }
9740 9799
9741 #undef __ 9800 #undef __
9742 9801
9743 } } // namespace v8::internal 9802 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698