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

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

Issue 2355793003: [stubs] Port SubStringStub to TurboFan (Closed)
Patch Set: Address comments Created 4 years, 3 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_MIPS64 5 #if V8_TARGET_ARCH_MIPS64
6 6
7 #include "src/code-stubs.h" 7 #include "src/code-stubs.h"
8 #include "src/api-arguments.h" 8 #include "src/api-arguments.h"
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 2253 matching lines...) Expand 10 before | Expand all | Expand 10 after
2264 __ lbu(scratch, MemOperand(src)); 2264 __ lbu(scratch, MemOperand(src));
2265 __ daddiu(src, src, 1); 2265 __ daddiu(src, src, 1);
2266 __ sb(scratch, MemOperand(dest)); 2266 __ sb(scratch, MemOperand(dest));
2267 __ daddiu(dest, dest, 1); 2267 __ daddiu(dest, dest, 1);
2268 __ bind(&loop_entry); 2268 __ bind(&loop_entry);
2269 __ Branch(&loop, lt, dest, Operand(limit)); 2269 __ Branch(&loop, lt, dest, Operand(limit));
2270 2270
2271 __ bind(&done); 2271 __ bind(&done);
2272 } 2272 }
2273 2273
2274
2275 void SubStringStub::Generate(MacroAssembler* masm) {
2276 Label runtime;
2277 // Stack frame on entry.
2278 // ra: return address
2279 // sp[0]: to
2280 // sp[4]: from
2281 // sp[8]: string
2282
2283 // This stub is called from the native-call %_SubString(...), so
2284 // nothing can be assumed about the arguments. It is tested that:
2285 // "string" is a sequential string,
2286 // both "from" and "to" are smis, and
2287 // 0 <= from <= to <= string.length.
2288 // If any of these assumptions fail, we call the runtime system.
2289
2290 const int kToOffset = 0 * kPointerSize;
2291 const int kFromOffset = 1 * kPointerSize;
2292 const int kStringOffset = 2 * kPointerSize;
2293
2294 __ ld(a2, MemOperand(sp, kToOffset));
2295 __ ld(a3, MemOperand(sp, kFromOffset));
2296
2297 STATIC_ASSERT(kSmiTag == 0);
2298
2299 // Utilize delay slots. SmiUntag doesn't emit a jump, everything else is
2300 // safe in this case.
2301 __ JumpIfNotSmi(a2, &runtime);
2302 __ JumpIfNotSmi(a3, &runtime);
2303 // Both a2 and a3 are untagged integers.
2304
2305 __ SmiUntag(a2, a2);
2306 __ SmiUntag(a3, a3);
2307 __ Branch(&runtime, lt, a3, Operand(zero_reg)); // From < 0.
2308
2309 __ Branch(&runtime, gt, a3, Operand(a2)); // Fail if from > to.
2310 __ Dsubu(a2, a2, a3);
2311
2312 // Make sure first argument is a string.
2313 __ ld(v0, MemOperand(sp, kStringOffset));
2314 __ JumpIfSmi(v0, &runtime);
2315 __ ld(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
2316 __ lbu(a1, FieldMemOperand(a1, Map::kInstanceTypeOffset));
2317 __ And(a4, a1, Operand(kIsNotStringMask));
2318
2319 __ Branch(&runtime, ne, a4, Operand(zero_reg));
2320
2321 Label single_char;
2322 __ Branch(&single_char, eq, a2, Operand(1));
2323
2324 // Short-cut for the case of trivial substring.
2325 Label return_v0;
2326 // v0: original string
2327 // a2: result string length
2328 __ ld(a4, FieldMemOperand(v0, String::kLengthOffset));
2329 __ SmiUntag(a4);
2330 // Return original string.
2331 __ Branch(&return_v0, eq, a2, Operand(a4));
2332 // Longer than original string's length or negative: unsafe arguments.
2333 __ Branch(&runtime, hi, a2, Operand(a4));
2334 // Shorter than original string's length: an actual substring.
2335
2336 // Deal with different string types: update the index if necessary
2337 // and put the underlying string into a5.
2338 // v0: original string
2339 // a1: instance type
2340 // a2: length
2341 // a3: from index (untagged)
2342 Label underlying_unpacked, sliced_string, seq_or_external_string;
2343 // If the string is not indirect, it can only be sequential or external.
2344 STATIC_ASSERT(kIsIndirectStringMask == (kSlicedStringTag & kConsStringTag));
2345 STATIC_ASSERT(kIsIndirectStringMask != 0);
2346 __ And(a4, a1, Operand(kIsIndirectStringMask));
2347 __ Branch(USE_DELAY_SLOT, &seq_or_external_string, eq, a4, Operand(zero_reg));
2348 // a4 is used as a scratch register and can be overwritten in either case.
2349 __ And(a4, a1, Operand(kSlicedNotConsMask));
2350 __ Branch(&sliced_string, ne, a4, Operand(zero_reg));
2351 // Cons string. Check whether it is flat, then fetch first part.
2352 __ ld(a5, FieldMemOperand(v0, ConsString::kSecondOffset));
2353 __ LoadRoot(a4, Heap::kempty_stringRootIndex);
2354 __ Branch(&runtime, ne, a5, Operand(a4));
2355 __ ld(a5, FieldMemOperand(v0, ConsString::kFirstOffset));
2356 // Update instance type.
2357 __ ld(a1, FieldMemOperand(a5, HeapObject::kMapOffset));
2358 __ lbu(a1, FieldMemOperand(a1, Map::kInstanceTypeOffset));
2359 __ jmp(&underlying_unpacked);
2360
2361 __ bind(&sliced_string);
2362 // Sliced string. Fetch parent and correct start index by offset.
2363 __ ld(a5, FieldMemOperand(v0, SlicedString::kParentOffset));
2364 __ ld(a4, FieldMemOperand(v0, SlicedString::kOffsetOffset));
2365 __ SmiUntag(a4); // Add offset to index.
2366 __ Daddu(a3, a3, a4);
2367 // Update instance type.
2368 __ ld(a1, FieldMemOperand(a5, HeapObject::kMapOffset));
2369 __ lbu(a1, FieldMemOperand(a1, Map::kInstanceTypeOffset));
2370 __ jmp(&underlying_unpacked);
2371
2372 __ bind(&seq_or_external_string);
2373 // Sequential or external string. Just move string to the expected register.
2374 __ mov(a5, v0);
2375
2376 __ bind(&underlying_unpacked);
2377
2378 if (FLAG_string_slices) {
2379 Label copy_routine;
2380 // a5: underlying subject string
2381 // a1: instance type of underlying subject string
2382 // a2: length
2383 // a3: adjusted start index (untagged)
2384 // Short slice. Copy instead of slicing.
2385 __ Branch(&copy_routine, lt, a2, Operand(SlicedString::kMinLength));
2386 // Allocate new sliced string. At this point we do not reload the instance
2387 // type including the string encoding because we simply rely on the info
2388 // provided by the original string. It does not matter if the original
2389 // string's encoding is wrong because we always have to recheck encoding of
2390 // the newly created string's parent anyways due to externalized strings.
2391 Label two_byte_slice, set_slice_header;
2392 STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0);
2393 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
2394 __ And(a4, a1, Operand(kStringEncodingMask));
2395 __ Branch(&two_byte_slice, eq, a4, Operand(zero_reg));
2396 __ AllocateOneByteSlicedString(v0, a2, a6, a7, &runtime);
2397 __ jmp(&set_slice_header);
2398 __ bind(&two_byte_slice);
2399 __ AllocateTwoByteSlicedString(v0, a2, a6, a7, &runtime);
2400 __ bind(&set_slice_header);
2401 __ SmiTag(a3);
2402 __ sd(a5, FieldMemOperand(v0, SlicedString::kParentOffset));
2403 __ sd(a3, FieldMemOperand(v0, SlicedString::kOffsetOffset));
2404 __ jmp(&return_v0);
2405
2406 __ bind(&copy_routine);
2407 }
2408
2409 // a5: underlying subject string
2410 // a1: instance type of underlying subject string
2411 // a2: length
2412 // a3: adjusted start index (untagged)
2413 Label two_byte_sequential, sequential_string, allocate_result;
2414 STATIC_ASSERT(kExternalStringTag != 0);
2415 STATIC_ASSERT(kSeqStringTag == 0);
2416 __ And(a4, a1, Operand(kExternalStringTag));
2417 __ Branch(&sequential_string, eq, a4, Operand(zero_reg));
2418
2419 // Handle external string.
2420 // Rule out short external strings.
2421 STATIC_ASSERT(kShortExternalStringTag != 0);
2422 __ And(a4, a1, Operand(kShortExternalStringTag));
2423 __ Branch(&runtime, ne, a4, Operand(zero_reg));
2424 __ ld(a5, FieldMemOperand(a5, ExternalString::kResourceDataOffset));
2425 // a5 already points to the first character of underlying string.
2426 __ jmp(&allocate_result);
2427
2428 __ bind(&sequential_string);
2429 // Locate first character of underlying subject string.
2430 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
2431 __ Daddu(a5, a5, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
2432
2433 __ bind(&allocate_result);
2434 // Sequential acii string. Allocate the result.
2435 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0);
2436 __ And(a4, a1, Operand(kStringEncodingMask));
2437 __ Branch(&two_byte_sequential, eq, a4, Operand(zero_reg));
2438
2439 // Allocate and copy the resulting one_byte string.
2440 __ AllocateOneByteString(v0, a2, a4, a6, a7, &runtime);
2441
2442 // Locate first character of substring to copy.
2443 __ Daddu(a5, a5, a3);
2444
2445 // Locate first character of result.
2446 __ Daddu(a1, v0, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
2447
2448 // v0: result string
2449 // a1: first character of result string
2450 // a2: result string length
2451 // a5: first character of substring to copy
2452 STATIC_ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0);
2453 StringHelper::GenerateCopyCharacters(
2454 masm, a1, a5, a2, a3, String::ONE_BYTE_ENCODING);
2455 __ jmp(&return_v0);
2456
2457 // Allocate and copy the resulting two-byte string.
2458 __ bind(&two_byte_sequential);
2459 __ AllocateTwoByteString(v0, a2, a4, a6, a7, &runtime);
2460
2461 // Locate first character of substring to copy.
2462 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
2463 __ Dlsa(a5, a5, a3, 1);
2464 // Locate first character of result.
2465 __ Daddu(a1, v0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
2466
2467 // v0: result string.
2468 // a1: first character of result.
2469 // a2: result length.
2470 // a5: first character of substring to copy.
2471 STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
2472 StringHelper::GenerateCopyCharacters(
2473 masm, a1, a5, a2, a3, String::TWO_BYTE_ENCODING);
2474
2475 __ bind(&return_v0);
2476 Counters* counters = isolate()->counters();
2477 __ IncrementCounter(counters->sub_string_native(), 1, a3, a4);
2478 __ DropAndRet(3);
2479
2480 // Just jump to runtime to create the sub string.
2481 __ bind(&runtime);
2482 __ TailCallRuntime(Runtime::kSubString);
2483
2484 __ bind(&single_char);
2485 // v0: original string
2486 // a1: instance type
2487 // a2: length
2488 // a3: from index (untagged)
2489 __ SmiTag(a3);
2490 StringCharAtGenerator generator(v0, a3, a2, v0, &runtime, &runtime, &runtime,
2491 RECEIVER_IS_STRING);
2492 generator.GenerateFast(masm);
2493 __ DropAndRet(3);
2494 generator.SkipSlow(masm, &runtime);
2495 }
2496
2497 void ToStringStub::Generate(MacroAssembler* masm) { 2274 void ToStringStub::Generate(MacroAssembler* masm) {
2498 // The ToString stub takes on argument in a0. 2275 // The ToString stub takes on argument in a0.
2499 Label is_number; 2276 Label is_number;
2500 __ JumpIfSmi(a0, &is_number); 2277 __ JumpIfSmi(a0, &is_number);
2501 2278
2502 Label not_string; 2279 Label not_string;
2503 __ GetObjectType(a0, a1, a1); 2280 __ GetObjectType(a0, a1, a1);
2504 // a0: receiver 2281 // a0: receiver
2505 // a1: receiver instance type 2282 // a1: receiver instance type
2506 __ Branch(&not_string, ge, a1, Operand(FIRST_NONSTRING_TYPE)); 2283 __ Branch(&not_string, ge, a1, Operand(FIRST_NONSTRING_TYPE));
(...skipping 2884 matching lines...) Expand 10 before | Expand all | Expand 10 after
5391 kStackUnwindSpace, kInvalidStackOffset, 5168 kStackUnwindSpace, kInvalidStackOffset,
5392 return_value_operand, NULL); 5169 return_value_operand, NULL);
5393 } 5170 }
5394 5171
5395 #undef __ 5172 #undef __
5396 5173
5397 } // namespace internal 5174 } // namespace internal
5398 } // namespace v8 5175 } // namespace v8
5399 5176
5400 #endif // V8_TARGET_ARCH_MIPS64 5177 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« src/code-stubs.cc ('K') | « src/mips/code-stubs-mips.cc ('k') | src/ppc/code-stubs-ppc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698