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

Side by Side Diff: src/mips/code-stubs-mips.cc

Issue 12374073: MIPS: Refactor RegExpStub to check lazily. (Closed) Base URL: https://v8.googlecode.com/svn/branches/3.16
Patch Set: Created 7 years, 9 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 | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 5126 matching lines...) Expand 10 before | Expand all | Expand 10 after
5137 // sp[8]: subject string 5137 // sp[8]: subject string
5138 // sp[12]: JSRegExp object 5138 // sp[12]: JSRegExp object
5139 5139
5140 const int kLastMatchInfoOffset = 0 * kPointerSize; 5140 const int kLastMatchInfoOffset = 0 * kPointerSize;
5141 const int kPreviousIndexOffset = 1 * kPointerSize; 5141 const int kPreviousIndexOffset = 1 * kPointerSize;
5142 const int kSubjectOffset = 2 * kPointerSize; 5142 const int kSubjectOffset = 2 * kPointerSize;
5143 const int kJSRegExpOffset = 3 * kPointerSize; 5143 const int kJSRegExpOffset = 3 * kPointerSize;
5144 5144
5145 Isolate* isolate = masm->isolate(); 5145 Isolate* isolate = masm->isolate();
5146 5146
5147 Label runtime, invoke_regexp; 5147 Label runtime;
5148
5149 // Allocation of registers for this function. These are in callee save 5148 // Allocation of registers for this function. These are in callee save
5150 // registers and will be preserved by the call to the native RegExp code, as 5149 // registers and will be preserved by the call to the native RegExp code, as
5151 // this code is called using the normal C calling convention. When calling 5150 // this code is called using the normal C calling convention. When calling
5152 // directly from generated code the native RegExp code will not do a GC and 5151 // directly from generated code the native RegExp code will not do a GC and
5153 // therefore the content of these registers are safe to use after the call. 5152 // therefore the content of these registers are safe to use after the call.
5154 // MIPS - using s0..s2, since we are not using CEntry Stub. 5153 // MIPS - using s0..s2, since we are not using CEntry Stub.
5155 Register subject = s0; 5154 Register subject = s0;
5156 Register regexp_data = s1; 5155 Register regexp_data = s1;
5157 Register last_match_info_elements = s2; 5156 Register last_match_info_elements = s2;
5158 5157
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
5190 5189
5191 // regexp_data: RegExp data (FixedArray) 5190 // regexp_data: RegExp data (FixedArray)
5192 // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP. 5191 // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP.
5193 __ lw(a0, FieldMemOperand(regexp_data, JSRegExp::kDataTagOffset)); 5192 __ lw(a0, FieldMemOperand(regexp_data, JSRegExp::kDataTagOffset));
5194 __ Branch(&runtime, ne, a0, Operand(Smi::FromInt(JSRegExp::IRREGEXP))); 5193 __ Branch(&runtime, ne, a0, Operand(Smi::FromInt(JSRegExp::IRREGEXP)));
5195 5194
5196 // regexp_data: RegExp data (FixedArray) 5195 // regexp_data: RegExp data (FixedArray)
5197 // Check that the number of captures fit in the static offsets vector buffer. 5196 // Check that the number of captures fit in the static offsets vector buffer.
5198 __ lw(a2, 5197 __ lw(a2,
5199 FieldMemOperand(regexp_data, JSRegExp::kIrregexpCaptureCountOffset)); 5198 FieldMemOperand(regexp_data, JSRegExp::kIrregexpCaptureCountOffset));
5200 // Calculate number of capture registers (number_of_captures + 1) * 2. This 5199 // Check (number_of_captures + 1) * 2 <= offsets vector size
5201 // uses the asumption that smis are 2 * their untagged value. 5200 // Or number_of_captures * 2 <= offsets vector size - 2
5201 // Multiplying by 2 comes for free since a2 is smi-tagged.
5202 STATIC_ASSERT(kSmiTag == 0); 5202 STATIC_ASSERT(kSmiTag == 0);
5203 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); 5203 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
5204 __ Addu(a2, a2, Operand(2)); // a2 was a smi. 5204 STATIC_ASSERT(Isolate::kJSRegexpStaticOffsetsVectorSize >= 2);
5205 // Check that the static offsets vector buffer is large enough.
5206 __ Branch( 5205 __ Branch(
5207 &runtime, hi, a2, Operand(Isolate::kJSRegexpStaticOffsetsVectorSize)); 5206 &runtime, hi, a2, Operand(Isolate::kJSRegexpStaticOffsetsVectorSize - 2));
5208
5209 // a2: Number of capture registers
5210 // regexp_data: RegExp data (FixedArray)
5211 // Check that the second argument is a string.
5212 __ lw(subject, MemOperand(sp, kSubjectOffset));
5213 __ JumpIfSmi(subject, &runtime);
5214 __ GetObjectType(subject, a0, a0);
5215 __ And(a0, a0, Operand(kIsNotStringMask));
5216 STATIC_ASSERT(kStringTag == 0);
5217 __ Branch(&runtime, ne, a0, Operand(zero_reg));
5218
5219 // Get the length of the string to r3.
5220 __ lw(a3, FieldMemOperand(subject, String::kLengthOffset));
5221
5222 // a2: Number of capture registers
5223 // a3: Length of subject string as a smi
5224 // subject: Subject string
5225 // regexp_data: RegExp data (FixedArray)
5226 // Check that the third argument is a positive smi less than the subject
5227 // string length. A negative value will be greater (unsigned comparison).
5228 __ lw(a0, MemOperand(sp, kPreviousIndexOffset));
5229 __ JumpIfNotSmi(a0, &runtime);
5230 __ Branch(&runtime, ls, a3, Operand(a0));
5231
5232 // a2: Number of capture registers
5233 // subject: Subject string
5234 // regexp_data: RegExp data (FixedArray)
5235 // Check that the fourth object is a JSArray object.
5236 __ lw(a0, MemOperand(sp, kLastMatchInfoOffset));
5237 __ JumpIfSmi(a0, &runtime);
5238 __ GetObjectType(a0, a1, a1);
5239 __ Branch(&runtime, ne, a1, Operand(JS_ARRAY_TYPE));
5240 // Check that the JSArray is in fast case.
5241 __ lw(last_match_info_elements,
5242 FieldMemOperand(a0, JSArray::kElementsOffset));
5243 __ lw(a0, FieldMemOperand(last_match_info_elements, HeapObject::kMapOffset));
5244 __ Branch(&runtime, ne, a0, Operand(
5245 isolate->factory()->fixed_array_map()));
5246 // Check that the last match info has space for the capture registers and the
5247 // additional information.
5248 __ lw(a0,
5249 FieldMemOperand(last_match_info_elements, FixedArray::kLengthOffset));
5250 __ Addu(a2, a2, Operand(RegExpImpl::kLastMatchOverhead));
5251 __ sra(at, a0, kSmiTagSize); // Untag length for comparison.
5252 __ Branch(&runtime, gt, a2, Operand(at));
5253 5207
5254 // Reset offset for possibly sliced string. 5208 // Reset offset for possibly sliced string.
5255 __ mov(t0, zero_reg); 5209 __ mov(t0, zero_reg);
5256 // subject: Subject string 5210 __ lw(subject, MemOperand(sp, kSubjectOffset));
5257 // regexp_data: RegExp data (FixedArray) 5211 __ JumpIfSmi(subject, &runtime);
5258 // Check the representation and encoding of the subject string. 5212 __ mov(a3, subject); // Make a copy of the original subject string.
5259 Label seq_string;
5260 __ lw(a0, FieldMemOperand(subject, HeapObject::kMapOffset)); 5213 __ lw(a0, FieldMemOperand(subject, HeapObject::kMapOffset));
5261 __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset)); 5214 __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset));
5262 // First check for flat string. None of the following string type tests will 5215 // subject: subject string
5263 // succeed if subject is not a string or a short external string. 5216 // a3: subject string
5217 // a0: subject string instance type
5218 // regexp_data: RegExp data (FixedArray)
5219 // Handle subject string according to its encoding and representation:
5220 // (1) Sequential string? If yes, go to (5).
5221 // (2) Anything but sequential or cons? If yes, go to (6).
5222 // (3) Cons string. If the string is flat, replace subject with first string.
5223 // Otherwise bailout.
5224 // (4) Is subject external? If yes, go to (7).
5225 // (5) Sequential string. Load regexp code according to encoding.
5226 // (E) Carry on.
5227 /// [...]
5228
5229 // Deferred code at the end of the stub:
5230 // (6) Not a long external string? If yes, go to (8).
5231 // (7) External string. Make it, offset-wise, look like a sequential string.
5232 // Go to (5).
5233 // (8) Short external string or not a string? If yes, bail out to runtime.
5234 // (9) Sliced string. Replace subject with parent. Go to (4).
5235
5236 Label seq_string /* 5 */, external_string /* 7 */,
5237 check_underlying /* 4 */, not_seq_nor_cons /* 6 */,
5238 not_long_external /* 8 */;
5239
5240 // (1) Sequential string? If yes, go to (5).
5264 __ And(a1, 5241 __ And(a1,
5265 a0, 5242 a0,
5266 Operand(kIsNotStringMask | 5243 Operand(kIsNotStringMask |
5267 kStringRepresentationMask | 5244 kStringRepresentationMask |
5268 kShortExternalStringMask)); 5245 kShortExternalStringMask));
5269 STATIC_ASSERT((kStringTag | kSeqStringTag) == 0); 5246 STATIC_ASSERT((kStringTag | kSeqStringTag) == 0);
5270 __ Branch(&seq_string, eq, a1, Operand(zero_reg)); 5247 __ Branch(&seq_string, eq, a1, Operand(zero_reg)); // Go to (5).
5271 5248
5272 // subject: Subject string 5249 // (2) Anything but sequential or cons? If yes, go to (6).
5273 // a0: instance type if Subject string
5274 // regexp_data: RegExp data (FixedArray)
5275 // a1: whether subject is a string and if yes, its string representation
5276 // Check for flat cons string or sliced string.
5277 // A flat cons string is a cons string where the second part is the empty
5278 // string. In that case the subject string is just the first part of the cons
5279 // string. Also in this case the first part of the cons string is known to be
5280 // a sequential string or an external string.
5281 // In the case of a sliced string its offset has to be taken into account.
5282 Label cons_string, external_string, check_encoding;
5283 STATIC_ASSERT(kConsStringTag < kExternalStringTag); 5250 STATIC_ASSERT(kConsStringTag < kExternalStringTag);
5284 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); 5251 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag);
5285 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag); 5252 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag);
5286 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag); 5253 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag);
5287 __ Branch(&cons_string, lt, a1, Operand(kExternalStringTag)); 5254 // Go to (6).
5288 __ Branch(&external_string, eq, a1, Operand(kExternalStringTag)); 5255 __ Branch(&not_seq_nor_cons, ge, a1, Operand(kExternalStringTag));
5289 5256
5290 // Catch non-string subject or short external string. 5257 // (3) Cons string. Check that it's flat.
5291 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0); 5258 // Replace subject with first string and reload instance type.
5292 __ And(at, a1, Operand(kIsNotStringMask | kShortExternalStringMask));
5293 __ Branch(&runtime, ne, at, Operand(zero_reg));
5294
5295 // String is sliced.
5296 __ lw(t0, FieldMemOperand(subject, SlicedString::kOffsetOffset));
5297 __ sra(t0, t0, kSmiTagSize);
5298 __ lw(subject, FieldMemOperand(subject, SlicedString::kParentOffset));
5299 // t5: offset of sliced string, smi-tagged.
5300 __ jmp(&check_encoding);
5301 // String is a cons string, check whether it is flat.
5302 __ bind(&cons_string);
5303 __ lw(a0, FieldMemOperand(subject, ConsString::kSecondOffset)); 5259 __ lw(a0, FieldMemOperand(subject, ConsString::kSecondOffset));
5304 __ LoadRoot(a1, Heap::kEmptyStringRootIndex); 5260 __ LoadRoot(a1, Heap::kEmptyStringRootIndex);
5305 __ Branch(&runtime, ne, a0, Operand(a1)); 5261 __ Branch(&runtime, ne, a0, Operand(a1));
5306 __ lw(subject, FieldMemOperand(subject, ConsString::kFirstOffset)); 5262 __ lw(subject, FieldMemOperand(subject, ConsString::kFirstOffset));
5307 // Is first part of cons or parent of slice a flat string? 5263
5308 __ bind(&check_encoding); 5264 // (4) Is subject external? If yes, go to (7).
5265 __ bind(&check_underlying);
5309 __ lw(a0, FieldMemOperand(subject, HeapObject::kMapOffset)); 5266 __ lw(a0, FieldMemOperand(subject, HeapObject::kMapOffset));
5310 __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset)); 5267 __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset));
5311 STATIC_ASSERT(kSeqStringTag == 0); 5268 STATIC_ASSERT(kSeqStringTag == 0);
5312 __ And(at, a0, Operand(kStringRepresentationMask)); 5269 __ And(at, a0, Operand(kStringRepresentationMask));
5313 __ Branch(&external_string, ne, at, Operand(zero_reg)); 5270 // The underlying external string is never a short external string.
5271 STATIC_CHECK(ExternalString::kMaxShortLength < ConsString::kMinLength);
5272 STATIC_CHECK(ExternalString::kMaxShortLength < SlicedString::kMinLength);
5273 __ Branch(&external_string, ne, at, Operand(zero_reg)); // Go to (7).
5314 5274
5275 // (5) Sequential string. Load regexp code according to encoding.
5315 __ bind(&seq_string); 5276 __ bind(&seq_string);
5316 // subject: Subject string 5277 // subject: sequential subject string (or look-alike, external string)
5317 // regexp_data: RegExp data (FixedArray) 5278 // a3: original subject string
5318 // a0: Instance type of subject string 5279 // Load previous index and check range before a3 is overwritten. We have to
5280 // use a3 instead of subject here because subject might have been only made
5281 // to look like a sequential string when it actually is an external string.
5282 __ lw(a1, MemOperand(sp, kPreviousIndexOffset));
5283 __ JumpIfNotSmi(a1, &runtime);
5284 __ lw(a3, FieldMemOperand(a3, String::kLengthOffset));
5285 __ Branch(&runtime, ls, a3, Operand(a1));
5286 __ sra(a1, a1, kSmiTagSize); // Untag the Smi.
5287
5319 STATIC_ASSERT(kStringEncodingMask == 4); 5288 STATIC_ASSERT(kStringEncodingMask == 4);
5320 STATIC_ASSERT(kOneByteStringTag == 4); 5289 STATIC_ASSERT(kOneByteStringTag == 4);
5321 STATIC_ASSERT(kTwoByteStringTag == 0); 5290 STATIC_ASSERT(kTwoByteStringTag == 0);
5322 // Find the code object based on the assumptions above.
5323 __ And(a0, a0, Operand(kStringEncodingMask)); // Non-zero for ASCII. 5291 __ And(a0, a0, Operand(kStringEncodingMask)); // Non-zero for ASCII.
5324 __ lw(t9, FieldMemOperand(regexp_data, JSRegExp::kDataAsciiCodeOffset)); 5292 __ lw(t9, FieldMemOperand(regexp_data, JSRegExp::kDataAsciiCodeOffset));
5325 __ sra(a3, a0, 2); // a3 is 1 for ASCII, 0 for UC16 (used below). 5293 __ sra(a3, a0, 2); // a3 is 1 for ASCII, 0 for UC16 (used below).
5326 __ lw(t1, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset)); 5294 __ lw(t1, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset));
5327 __ Movz(t9, t1, a0); // If UC16 (a0 is 0), replace t9 w/kDataUC16CodeOffset. 5295 __ Movz(t9, t1, a0); // If UC16 (a0 is 0), replace t9 w/kDataUC16CodeOffset.
5328 5296
5297 // (E) Carry on. String handling is done.
5298 // t9: irregexp code
5329 // Check that the irregexp code has been generated for the actual string 5299 // Check that the irregexp code has been generated for the actual string
5330 // encoding. If it has, the field contains a code object otherwise it contains 5300 // encoding. If it has, the field contains a code object otherwise it contains
5331 // a smi (code flushing support). 5301 // a smi (code flushing support).
5332 __ JumpIfSmi(t9, &runtime); 5302 __ JumpIfSmi(t9, &runtime);
5333 5303
5334 // a3: encoding of subject string (1 if ASCII, 0 if two_byte);
5335 // t9: code
5336 // subject: Subject string
5337 // regexp_data: RegExp data (FixedArray)
5338 // Load used arguments before starting to push arguments for call to native
5339 // RegExp code to avoid handling changing stack height.
5340 __ lw(a1, MemOperand(sp, kPreviousIndexOffset));
5341 __ sra(a1, a1, kSmiTagSize); // Untag the Smi.
5342
5343 // a1: previous index 5304 // a1: previous index
5344 // a3: encoding of subject string (1 if ASCII, 0 if two_byte); 5305 // a3: encoding of subject string (1 if ASCII, 0 if two_byte);
5345 // t9: code 5306 // t9: code
5346 // subject: Subject string 5307 // subject: Subject string
5347 // regexp_data: RegExp data (FixedArray) 5308 // regexp_data: RegExp data (FixedArray)
5348 // All checks done. Now push arguments for native regexp code. 5309 // All checks done. Now push arguments for native regexp code.
5349 __ IncrementCounter(isolate->counters()->regexp_entry_native(), 5310 __ IncrementCounter(isolate->counters()->regexp_entry_native(),
5350 1, a0, a2); 5311 1, a0, a2);
5351 5312
5352 // Isolates: note we add an additional parameter here (isolate pointer). 5313 // Isolates: note we add an additional parameter here (isolate pointer).
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
5427 __ Addu(t9, t9, Operand(Code::kHeaderSize - kHeapObjectTag)); 5388 __ Addu(t9, t9, Operand(Code::kHeaderSize - kHeapObjectTag));
5428 DirectCEntryStub stub; 5389 DirectCEntryStub stub;
5429 stub.GenerateCall(masm, t9); 5390 stub.GenerateCall(masm, t9);
5430 5391
5431 __ LeaveExitFrame(false, no_reg); 5392 __ LeaveExitFrame(false, no_reg);
5432 5393
5433 // v0: result 5394 // v0: result
5434 // subject: subject string (callee saved) 5395 // subject: subject string (callee saved)
5435 // regexp_data: RegExp data (callee saved) 5396 // regexp_data: RegExp data (callee saved)
5436 // last_match_info_elements: Last match info elements (callee saved) 5397 // last_match_info_elements: Last match info elements (callee saved)
5437
5438 // Check the result. 5398 // Check the result.
5439
5440 Label success; 5399 Label success;
5441 __ Branch(&success, eq, v0, Operand(1)); 5400 __ Branch(&success, eq, v0, Operand(1));
5442 // We expect exactly one result since we force the called regexp to behave 5401 // We expect exactly one result since we force the called regexp to behave
5443 // as non-global. 5402 // as non-global.
5444 Label failure; 5403 Label failure;
5445 __ Branch(&failure, eq, v0, Operand(NativeRegExpMacroAssembler::FAILURE)); 5404 __ Branch(&failure, eq, v0, Operand(NativeRegExpMacroAssembler::FAILURE));
5446 // If not exception it can only be retry. Handle that in the runtime system. 5405 // If not exception it can only be retry. Handle that in the runtime system.
5447 __ Branch(&runtime, ne, v0, Operand(NativeRegExpMacroAssembler::EXCEPTION)); 5406 __ Branch(&runtime, ne, v0, Operand(NativeRegExpMacroAssembler::EXCEPTION));
5448 // Result must now be exception. If there is no pending exception already a 5407 // Result must now be exception. If there is no pending exception already a
5449 // stack overflow (on the backtrack stack) was detected in RegExp code but 5408 // stack overflow (on the backtrack stack) was detected in RegExp code but
(...skipping 20 matching lines...) Expand all
5470 __ bind(&failure); 5429 __ bind(&failure);
5471 // For failure and exception return null. 5430 // For failure and exception return null.
5472 __ li(v0, Operand(isolate->factory()->null_value())); 5431 __ li(v0, Operand(isolate->factory()->null_value()));
5473 __ DropAndRet(4); 5432 __ DropAndRet(4);
5474 5433
5475 // Process the result from the native regexp code. 5434 // Process the result from the native regexp code.
5476 __ bind(&success); 5435 __ bind(&success);
5477 __ lw(a1, 5436 __ lw(a1,
5478 FieldMemOperand(regexp_data, JSRegExp::kIrregexpCaptureCountOffset)); 5437 FieldMemOperand(regexp_data, JSRegExp::kIrregexpCaptureCountOffset));
5479 // Calculate number of capture registers (number_of_captures + 1) * 2. 5438 // Calculate number of capture registers (number_of_captures + 1) * 2.
5439 // Multiplying by 2 comes for free since r1 is smi-tagged.
5480 STATIC_ASSERT(kSmiTag == 0); 5440 STATIC_ASSERT(kSmiTag == 0);
5481 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); 5441 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
5482 __ Addu(a1, a1, Operand(2)); // a1 was a smi. 5442 __ Addu(a1, a1, Operand(2)); // a1 was a smi.
5483 5443
5444 __ lw(a0, MemOperand(sp, kLastMatchInfoOffset));
5445 __ JumpIfSmi(a0, &runtime);
5446 __ GetObjectType(a0, a2, a2);
5447 __ Branch(&runtime, ne, a2, Operand(JS_ARRAY_TYPE));
5448 // Check that the JSArray is in fast case.
5449 __ lw(last_match_info_elements,
5450 FieldMemOperand(a0, JSArray::kElementsOffset));
5451 __ lw(a0, FieldMemOperand(last_match_info_elements, HeapObject::kMapOffset));
5452 __ LoadRoot(at, Heap::kFixedArrayMapRootIndex);
5453 __ Branch(&runtime, ne, a0, Operand(at));
5454 // Check that the last match info has space for the capture registers and the
5455 // additional information.
5456 __ lw(a0,
5457 FieldMemOperand(last_match_info_elements, FixedArray::kLengthOffset));
5458 __ Addu(a2, a1, Operand(RegExpImpl::kLastMatchOverhead));
5459 __ sra(at, a0, kSmiTagSize);
5460 __ Branch(&runtime, gt, a2, Operand(at));
5461
5484 // a1: number of capture registers 5462 // a1: number of capture registers
5485 // subject: subject string 5463 // subject: subject string
5486 // Store the capture count. 5464 // Store the capture count.
5487 __ sll(a2, a1, kSmiTagSize + kSmiShiftSize); // To smi. 5465 __ sll(a2, a1, kSmiTagSize + kSmiShiftSize); // To smi.
5488 __ sw(a2, FieldMemOperand(last_match_info_elements, 5466 __ sw(a2, FieldMemOperand(last_match_info_elements,
5489 RegExpImpl::kLastCaptureCountOffset)); 5467 RegExpImpl::kLastCaptureCountOffset));
5490 // Store last subject and last input. 5468 // Store last subject and last input.
5491 __ sw(subject, 5469 __ sw(subject,
5492 FieldMemOperand(last_match_info_elements, 5470 FieldMemOperand(last_match_info_elements,
5493 RegExpImpl::kLastSubjectOffset)); 5471 RegExpImpl::kLastSubjectOffset));
5494 __ mov(a2, subject); 5472 __ mov(a2, subject);
5495 __ RecordWriteField(last_match_info_elements, 5473 __ RecordWriteField(last_match_info_elements,
5496 RegExpImpl::kLastSubjectOffset, 5474 RegExpImpl::kLastSubjectOffset,
5497 a2, 5475 subject,
5498 t3, 5476 t3,
5499 kRAHasNotBeenSaved, 5477 kRAHasNotBeenSaved,
5500 kDontSaveFPRegs); 5478 kDontSaveFPRegs);
5479 __ mov(subject, a2);
5501 __ sw(subject, 5480 __ sw(subject,
5502 FieldMemOperand(last_match_info_elements, 5481 FieldMemOperand(last_match_info_elements,
5503 RegExpImpl::kLastInputOffset)); 5482 RegExpImpl::kLastInputOffset));
5504 __ RecordWriteField(last_match_info_elements, 5483 __ RecordWriteField(last_match_info_elements,
5505 RegExpImpl::kLastInputOffset, 5484 RegExpImpl::kLastInputOffset,
5506 subject, 5485 subject,
5507 t3, 5486 t3,
5508 kRAHasNotBeenSaved, 5487 kRAHasNotBeenSaved,
5509 kDontSaveFPRegs); 5488 kDontSaveFPRegs);
5510 5489
(...skipping 21 matching lines...) Expand all
5532 __ sw(a3, MemOperand(a0, 0)); 5511 __ sw(a3, MemOperand(a0, 0));
5533 __ Branch(&next_capture, USE_DELAY_SLOT); 5512 __ Branch(&next_capture, USE_DELAY_SLOT);
5534 __ addiu(a0, a0, kPointerSize); // In branch delay slot. 5513 __ addiu(a0, a0, kPointerSize); // In branch delay slot.
5535 5514
5536 __ bind(&done); 5515 __ bind(&done);
5537 5516
5538 // Return last match info. 5517 // Return last match info.
5539 __ lw(v0, MemOperand(sp, kLastMatchInfoOffset)); 5518 __ lw(v0, MemOperand(sp, kLastMatchInfoOffset));
5540 __ DropAndRet(4); 5519 __ DropAndRet(4);
5541 5520
5542 // External string. Short external strings have already been ruled out. 5521 // Do the runtime call to execute the regexp.
5543 // a0: scratch 5522 __ bind(&runtime);
5523 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
5524
5525 // Deferred code for string handling.
5526 // (6) Not a long external string? If yes, go to (8).
5527 __ bind(&not_seq_nor_cons);
5528 // Go to (8).
5529 __ Branch(&not_long_external, gt, a1, Operand(kExternalStringTag));
5530
5531 // (7) External string. Make it, offset-wise, look like a sequential string.
5544 __ bind(&external_string); 5532 __ bind(&external_string);
5545 __ lw(a0, FieldMemOperand(subject, HeapObject::kMapOffset)); 5533 __ lw(a0, FieldMemOperand(subject, HeapObject::kMapOffset));
5546 __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset)); 5534 __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset));
5547 if (FLAG_debug_code) { 5535 if (FLAG_debug_code) {
5548 // Assert that we do not have a cons or slice (indirect strings) here. 5536 // Assert that we do not have a cons or slice (indirect strings) here.
5549 // Sequential strings have already been ruled out. 5537 // Sequential strings have already been ruled out.
5550 __ And(at, a0, Operand(kIsIndirectStringMask)); 5538 __ And(at, a0, Operand(kIsIndirectStringMask));
5551 __ Assert(eq, 5539 __ Assert(eq,
5552 "external string expected, but not found", 5540 "external string expected, but not found",
5553 at, 5541 at,
5554 Operand(zero_reg)); 5542 Operand(zero_reg));
5555 } 5543 }
5556 __ lw(subject, 5544 __ lw(subject,
5557 FieldMemOperand(subject, ExternalString::kResourceDataOffset)); 5545 FieldMemOperand(subject, ExternalString::kResourceDataOffset));
5558 // Move the pointer so that offset-wise, it looks like a sequential string. 5546 // Move the pointer so that offset-wise, it looks like a sequential string.
5559 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); 5547 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
5560 __ Subu(subject, 5548 __ Subu(subject,
5561 subject, 5549 subject,
5562 SeqTwoByteString::kHeaderSize - kHeapObjectTag); 5550 SeqTwoByteString::kHeaderSize - kHeapObjectTag);
5563 __ jmp(&seq_string); 5551 __ jmp(&seq_string); // Go to (5).
5564 5552
5565 // Do the runtime call to execute the regexp. 5553 // (8) Short external string or not a string? If yes, bail out to runtime.
5566 __ bind(&runtime); 5554 __ bind(&not_long_external);
5567 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); 5555 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0);
5556 __ And(at, a1, Operand(kIsNotStringMask | kShortExternalStringMask));
5557 __ Branch(&runtime, ne, at, Operand(zero_reg));
5558
5559 // (9) Sliced string. Replace subject with parent. Go to (4).
5560 // Load offset into t0 and replace subject string with parent.
5561 __ lw(t0, FieldMemOperand(subject, SlicedString::kOffsetOffset));
5562 __ sra(t0, t0, kSmiTagSize);
5563 __ lw(subject, FieldMemOperand(subject, SlicedString::kParentOffset));
5564 __ jmp(&check_underlying); // Go to (4).
5568 #endif // V8_INTERPRETED_REGEXP 5565 #endif // V8_INTERPRETED_REGEXP
5569 } 5566 }
5570 5567
5571 5568
5572 void RegExpConstructResultStub::Generate(MacroAssembler* masm) { 5569 void RegExpConstructResultStub::Generate(MacroAssembler* masm) {
5573 const int kMaxInlineLength = 100; 5570 const int kMaxInlineLength = 100;
5574 Label slowcase; 5571 Label slowcase;
5575 Label done; 5572 Label done;
5576 __ lw(a1, MemOperand(sp, kPointerSize * 2)); 5573 __ lw(a1, MemOperand(sp, kPointerSize * 2));
5577 STATIC_ASSERT(kSmiTag == 0); 5574 STATIC_ASSERT(kSmiTag == 0);
(...skipping 2058 matching lines...) Expand 10 before | Expand all | Expand 10 after
7636 struct AheadOfTimeWriteBarrierStubList { 7633 struct AheadOfTimeWriteBarrierStubList {
7637 Register object, value, address; 7634 Register object, value, address;
7638 RememberedSetAction action; 7635 RememberedSetAction action;
7639 }; 7636 };
7640 7637
7641 #define REG(Name) { kRegister_ ## Name ## _Code } 7638 #define REG(Name) { kRegister_ ## Name ## _Code }
7642 7639
7643 static const AheadOfTimeWriteBarrierStubList kAheadOfTime[] = { 7640 static const AheadOfTimeWriteBarrierStubList kAheadOfTime[] = {
7644 // Used in RegExpExecStub. 7641 // Used in RegExpExecStub.
7645 { REG(s2), REG(s0), REG(t3), EMIT_REMEMBERED_SET }, 7642 { REG(s2), REG(s0), REG(t3), EMIT_REMEMBERED_SET },
7646 { REG(s2), REG(a2), REG(t3), EMIT_REMEMBERED_SET },
7647 // Used in CompileArrayPushCall. 7643 // Used in CompileArrayPushCall.
7648 // Also used in StoreIC::GenerateNormal via GenerateDictionaryStore. 7644 // Also used in StoreIC::GenerateNormal via GenerateDictionaryStore.
7649 // Also used in KeyedStoreIC::GenerateGeneric. 7645 // Also used in KeyedStoreIC::GenerateGeneric.
7650 { REG(a3), REG(t0), REG(t1), EMIT_REMEMBERED_SET }, 7646 { REG(a3), REG(t0), REG(t1), EMIT_REMEMBERED_SET },
7651 // Used in CompileStoreGlobal. 7647 // Used in CompileStoreGlobal.
7652 { REG(t0), REG(a1), REG(a2), OMIT_REMEMBERED_SET }, 7648 { REG(t0), REG(a1), REG(a2), OMIT_REMEMBERED_SET },
7653 // Used in StoreStubCompiler::CompileStoreField via GenerateStoreField. 7649 // Used in StoreStubCompiler::CompileStoreField via GenerateStoreField.
7654 { REG(a1), REG(a2), REG(a3), EMIT_REMEMBERED_SET }, 7650 { REG(a1), REG(a2), REG(a3), EMIT_REMEMBERED_SET },
7655 { REG(a3), REG(a2), REG(a1), EMIT_REMEMBERED_SET }, 7651 { REG(a3), REG(a2), REG(a1), EMIT_REMEMBERED_SET },
7656 // Used in KeyedStoreStubCompiler::CompileStoreField via GenerateStoreField. 7652 // Used in KeyedStoreStubCompiler::CompileStoreField via GenerateStoreField.
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
8061 __ Pop(ra, t1, a1); 8057 __ Pop(ra, t1, a1);
8062 __ Ret(); 8058 __ Ret();
8063 } 8059 }
8064 8060
8065 8061
8066 #undef __ 8062 #undef __
8067 8063
8068 } } // namespace v8::internal 8064 } } // namespace v8::internal
8069 8065
8070 #endif // V8_TARGET_ARCH_MIPS 8066 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698