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

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

Issue 7477045: Tentative implementation of string slices (hidden under the flag --string-slices). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Some more suggested changes. Created 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 2285 matching lines...) Expand 10 before | Expand all | Expand 10 after
2296 // Ensure that a RegExp stack is allocated. 2296 // Ensure that a RegExp stack is allocated.
2297 Isolate* isolate = masm->isolate(); 2297 Isolate* isolate = masm->isolate();
2298 ExternalReference address_of_regexp_stack_memory_address = 2298 ExternalReference address_of_regexp_stack_memory_address =
2299 ExternalReference::address_of_regexp_stack_memory_address(isolate); 2299 ExternalReference::address_of_regexp_stack_memory_address(isolate);
2300 ExternalReference address_of_regexp_stack_memory_size = 2300 ExternalReference address_of_regexp_stack_memory_size =
2301 ExternalReference::address_of_regexp_stack_memory_size(isolate); 2301 ExternalReference::address_of_regexp_stack_memory_size(isolate);
2302 __ Load(kScratchRegister, address_of_regexp_stack_memory_size); 2302 __ Load(kScratchRegister, address_of_regexp_stack_memory_size);
2303 __ testq(kScratchRegister, kScratchRegister); 2303 __ testq(kScratchRegister, kScratchRegister);
2304 __ j(zero, &runtime); 2304 __ j(zero, &runtime);
2305 2305
2306
2307 // Check that the first argument is a JSRegExp object. 2306 // Check that the first argument is a JSRegExp object.
2308 __ movq(rax, Operand(rsp, kJSRegExpOffset)); 2307 __ movq(rax, Operand(rsp, kJSRegExpOffset));
2309 __ JumpIfSmi(rax, &runtime); 2308 __ JumpIfSmi(rax, &runtime);
2310 __ CmpObjectType(rax, JS_REGEXP_TYPE, kScratchRegister); 2309 __ CmpObjectType(rax, JS_REGEXP_TYPE, kScratchRegister);
2311 __ j(not_equal, &runtime); 2310 __ j(not_equal, &runtime);
2312 // Check that the RegExp has been compiled (data contains a fixed array). 2311 // Check that the RegExp has been compiled (data contains a fixed array).
2313 __ movq(rax, FieldOperand(rax, JSRegExp::kDataOffset)); 2312 __ movq(rax, FieldOperand(rax, JSRegExp::kDataOffset));
2314 if (FLAG_debug_code) { 2313 if (FLAG_debug_code) {
2315 Condition is_smi = masm->CheckSmi(rax); 2314 Condition is_smi = masm->CheckSmi(rax);
2316 __ Check(NegateCondition(is_smi), 2315 __ Check(NegateCondition(is_smi),
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2367 Heap::kFixedArrayMapRootIndex); 2366 Heap::kFixedArrayMapRootIndex);
2368 __ j(not_equal, &runtime); 2367 __ j(not_equal, &runtime);
2369 // Check that the last match info has space for the capture registers and the 2368 // Check that the last match info has space for the capture registers and the
2370 // additional information. Ensure no overflow in add. 2369 // additional information. Ensure no overflow in add.
2371 STATIC_ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset); 2370 STATIC_ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset);
2372 __ SmiToInteger32(rdi, FieldOperand(rbx, FixedArray::kLengthOffset)); 2371 __ SmiToInteger32(rdi, FieldOperand(rbx, FixedArray::kLengthOffset));
2373 __ addl(rdx, Immediate(RegExpImpl::kLastMatchOverhead)); 2372 __ addl(rdx, Immediate(RegExpImpl::kLastMatchOverhead));
2374 __ cmpl(rdx, rdi); 2373 __ cmpl(rdx, rdi);
2375 __ j(greater, &runtime); 2374 __ j(greater, &runtime);
2376 2375
2376 // Reset offset for possibly sliced string.
2377 __ Set(r14, 0);
2377 // rax: RegExp data (FixedArray) 2378 // rax: RegExp data (FixedArray)
2378 // Check the representation and encoding of the subject string. 2379 // Check the representation and encoding of the subject string.
2379 Label seq_ascii_string, seq_two_byte_string, check_code; 2380 Label seq_ascii_string, seq_two_byte_string, check_code;
2380 __ movq(rdi, Operand(rsp, kSubjectOffset)); 2381 __ movq(rdi, Operand(rsp, kSubjectOffset));
2382 // Make a copy of the original subject string.
2383 __ movq(r15, rdi);
2381 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); 2384 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
2382 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset)); 2385 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
2383 // First check for flat two byte string. 2386 // First check for flat two byte string.
2384 __ andb(rbx, Immediate( 2387 __ andb(rbx, Immediate(
2385 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask)); 2388 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask));
2386 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); 2389 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0);
2387 __ j(zero, &seq_two_byte_string, Label::kNear); 2390 __ j(zero, &seq_two_byte_string, Label::kNear);
2388 // Any other flat string must be a flat ascii string. 2391 // Any other flat string must be a flat ascii string.
2389 __ testb(rbx, Immediate(kIsNotStringMask | kStringRepresentationMask)); 2392 __ andb(rbx, Immediate(kIsNotStringMask | kStringRepresentationMask));
2390 __ j(zero, &seq_ascii_string, Label::kNear); 2393 __ j(zero, &seq_ascii_string, Label::kNear);
2391 2394
2392 // Check for flat cons string. 2395 // Check for flat cons string or sliced string.
2393 // A flat cons string is a cons string where the second part is the empty 2396 // A flat cons string is a cons string where the second part is the empty
2394 // string. In that case the subject string is just the first part of the cons 2397 // string. In that case the subject string is just the first part of the cons
2395 // string. Also in this case the first part of the cons string is known to be 2398 // string. Also in this case the first part of the cons string is known to be
2396 // a sequential string or an external string. 2399 // a sequential string or an external string.
2397 STATIC_ASSERT(kExternalStringTag !=0); 2400 // In the case of a sliced string its offset has to be taken into account.
2398 STATIC_ASSERT((kConsStringTag & kExternalStringTag) == 0); 2401 Label cons_string, check_encoding;
2399 __ testb(rbx, Immediate(kIsNotStringMask | kExternalStringTag)); 2402 STATIC_ASSERT((kConsStringTag < kExternalStringTag));
2400 __ j(not_zero, &runtime); 2403 STATIC_ASSERT((kSlicedStringTag > kExternalStringTag));
2401 // String is a cons string. 2404 __ cmpq(rbx, Immediate(kExternalStringTag));
2405 __ j(less, &cons_string, Label::kNear);
2406 __ j(equal, &runtime);
2407
2408 // String is sliced.
2409 __ SmiToInteger32(r14, FieldOperand(rdi, SlicedString::kOffsetOffset));
2410 __ movq(rdi, FieldOperand(rdi, SlicedString::kParentOffset));
2411 // r14: slice offset
2412 // r15: original subject string
2413 // rdi: parent string
2414 __ jmp(&check_encoding, Label::kNear);
2415 // String is a cons string, check whether it is flat.
2416 __ bind(&cons_string);
2402 __ CompareRoot(FieldOperand(rdi, ConsString::kSecondOffset), 2417 __ CompareRoot(FieldOperand(rdi, ConsString::kSecondOffset),
2403 Heap::kEmptyStringRootIndex); 2418 Heap::kEmptyStringRootIndex);
2404 __ j(not_equal, &runtime); 2419 __ j(not_equal, &runtime);
2405 __ movq(rdi, FieldOperand(rdi, ConsString::kFirstOffset)); 2420 __ movq(rdi, FieldOperand(rdi, ConsString::kFirstOffset));
2421 // rdi: first part of cons string or parent of sliced string.
2422 // rbx: map of first part of cons string or map of parent of sliced string.
2423 // Is first part of cons or parent of slice a flat two byte string?
2424 __ bind(&check_encoding);
2406 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); 2425 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
2407 // String is a cons string with empty second part.
2408 // rdi: first part of cons string.
2409 // rbx: map of first part of cons string.
2410 // Is first part a flat two byte string?
2411 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset), 2426 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset),
2412 Immediate(kStringRepresentationMask | kStringEncodingMask)); 2427 Immediate(kStringRepresentationMask | kStringEncodingMask));
2413 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0); 2428 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
2414 __ j(zero, &seq_two_byte_string, Label::kNear); 2429 __ j(zero, &seq_two_byte_string, Label::kNear);
2415 // Any other flat string must be ascii. 2430 // Any other flat string must be ascii.
2416 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset), 2431 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset),
2417 Immediate(kStringRepresentationMask)); 2432 Immediate(kStringRepresentationMask));
2418 __ j(not_zero, &runtime); 2433 __ j(not_zero, &runtime);
2419 2434
2420 __ bind(&seq_ascii_string); 2435 __ bind(&seq_ascii_string);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
2497 Register arg3 = rdx; 2512 Register arg3 = rdx;
2498 Register arg2 = rsi; 2513 Register arg2 = rsi;
2499 Register arg1 = rdi; 2514 Register arg1 = rdi;
2500 #endif 2515 #endif
2501 2516
2502 // Keep track on aliasing between argX defined above and the registers used. 2517 // Keep track on aliasing between argX defined above and the registers used.
2503 // rdi: subject string 2518 // rdi: subject string
2504 // rbx: previous index 2519 // rbx: previous index
2505 // rcx: encoding of subject string (1 if ascii 0 if two_byte); 2520 // rcx: encoding of subject string (1 if ascii 0 if two_byte);
2506 // r11: code 2521 // r11: code
2522 // r14: slice offset
2523 // r15: original subject string
2524
2525 // Argument 2: Previous index.
2526 __ movq(arg2, rbx);
2507 2527
2508 // Argument 4: End of string data 2528 // Argument 4: End of string data
2509 // Argument 3: Start of string data 2529 // Argument 3: Start of string data
2510 Label setup_two_byte, setup_rest; 2530 Label setup_two_byte, setup_rest, got_length, length_not_from_slice;
2531 // Prepare start and end index of the input.
2532 // Load the length from the original sliced string if that is the case.
2533 __ addq(rbx, r14);
2534 __ SmiToInteger32(arg3, FieldOperand(r15, String::kLengthOffset));
2535 __ addq(r14, arg3); // Using arg3 as scratch.
2536
2537 // rbx: start index of the input
2538 // r14: end index of the input
2539 // r15: original subject string
2511 __ testb(rcx, rcx); // Last use of rcx as encoding of subject string. 2540 __ testb(rcx, rcx); // Last use of rcx as encoding of subject string.
2512 __ j(zero, &setup_two_byte, Label::kNear); 2541 __ j(zero, &setup_two_byte, Label::kNear);
2513 __ SmiToInteger32(rcx, FieldOperand(rdi, String::kLengthOffset)); 2542 __ lea(arg4, FieldOperand(rdi, r14, times_1, SeqAsciiString::kHeaderSize));
2514 __ lea(arg4, FieldOperand(rdi, rcx, times_1, SeqAsciiString::kHeaderSize));
2515 __ lea(arg3, FieldOperand(rdi, rbx, times_1, SeqAsciiString::kHeaderSize)); 2543 __ lea(arg3, FieldOperand(rdi, rbx, times_1, SeqAsciiString::kHeaderSize));
2516 __ jmp(&setup_rest, Label::kNear); 2544 __ jmp(&setup_rest, Label::kNear);
2517 __ bind(&setup_two_byte); 2545 __ bind(&setup_two_byte);
2518 __ SmiToInteger32(rcx, FieldOperand(rdi, String::kLengthOffset)); 2546 __ lea(arg4, FieldOperand(rdi, r14, times_2, SeqTwoByteString::kHeaderSize));
2519 __ lea(arg4, FieldOperand(rdi, rcx, times_2, SeqTwoByteString::kHeaderSize));
2520 __ lea(arg3, FieldOperand(rdi, rbx, times_2, SeqTwoByteString::kHeaderSize)); 2547 __ lea(arg3, FieldOperand(rdi, rbx, times_2, SeqTwoByteString::kHeaderSize));
2548 __ bind(&setup_rest);
2521 2549
2522 __ bind(&setup_rest); 2550 // Argument 1: Original subject string.
2523 // Argument 2: Previous index. 2551 // The original subject is in the previous stack frame. Therefore we have to
2524 __ movq(arg2, rbx); 2552 // use rbp, which points exactly to one pointer size below the previous rsp.
2525 2553 // (Because creating a new stack frame pushes the previous rbp onto the stack
2526 // Argument 1: Subject string. 2554 // and thereby moves up rsp by one kPointerSize.)
2527 #ifdef _WIN64 2555 __ movq(arg1, r15);
2528 __ movq(arg1, rdi);
2529 #else
2530 // Already there in AMD64 calling convention.
2531 ASSERT(arg1.is(rdi));
2532 USE(arg1);
2533 #endif
2534 2556
2535 // Locate the code entry and call it. 2557 // Locate the code entry and call it.
2536 __ addq(r11, Immediate(Code::kHeaderSize - kHeapObjectTag)); 2558 __ addq(r11, Immediate(Code::kHeaderSize - kHeapObjectTag));
2537 __ call(r11); 2559 __ call(r11);
2538 2560
2539 __ LeaveApiExitFrame(); 2561 __ LeaveApiExitFrame();
2540 2562
2541 // Check the result. 2563 // Check the result.
2542 Label success; 2564 Label success;
2543 Label exception; 2565 Label exception;
(...skipping 1229 matching lines...) Expand 10 before | Expand all | Expand 10 after
3773 } 3795 }
3774 3796
3775 3797
3776 // ------------------------------------------------------------------------- 3798 // -------------------------------------------------------------------------
3777 // StringCharCodeAtGenerator 3799 // StringCharCodeAtGenerator
3778 3800
3779 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 3801 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
3780 Label flat_string; 3802 Label flat_string;
3781 Label ascii_string; 3803 Label ascii_string;
3782 Label got_char_code; 3804 Label got_char_code;
3805 Label sliced_string;
3783 3806
3784 // If the receiver is a smi trigger the non-string case. 3807 // If the receiver is a smi trigger the non-string case.
3785 __ JumpIfSmi(object_, receiver_not_string_); 3808 __ JumpIfSmi(object_, receiver_not_string_);
3786 3809
3787 // Fetch the instance type of the receiver into result register. 3810 // Fetch the instance type of the receiver into result register.
3788 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset)); 3811 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset));
3789 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 3812 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
3790 // If the receiver is not a string trigger the non-string case. 3813 // If the receiver is not a string trigger the non-string case.
3791 __ testb(result_, Immediate(kIsNotStringMask)); 3814 __ testb(result_, Immediate(kIsNotStringMask));
3792 __ j(not_zero, receiver_not_string_); 3815 __ j(not_zero, receiver_not_string_);
3793 3816
3794 // If the index is non-smi trigger the non-smi case. 3817 // If the index is non-smi trigger the non-smi case.
3795 __ JumpIfNotSmi(index_, &index_not_smi_); 3818 __ JumpIfNotSmi(index_, &index_not_smi_);
3796 3819
3797 // Put smi-tagged index into scratch register. 3820 // Put smi-tagged index into scratch register.
3798 __ movq(scratch_, index_); 3821 __ movq(scratch_, index_);
3799 __ bind(&got_smi_index_); 3822 __ bind(&got_smi_index_);
3800 3823
3801 // Check for index out of range. 3824 // Check for index out of range.
3802 __ SmiCompare(scratch_, FieldOperand(object_, String::kLengthOffset)); 3825 __ SmiCompare(scratch_, FieldOperand(object_, String::kLengthOffset));
3803 __ j(above_equal, index_out_of_range_); 3826 __ j(above_equal, index_out_of_range_);
3804 3827
3805 // We need special handling for non-flat strings. 3828 // We need special handling for non-flat strings.
3806 STATIC_ASSERT(kSeqStringTag == 0); 3829 STATIC_ASSERT(kSeqStringTag == 0);
3807 __ testb(result_, Immediate(kStringRepresentationMask)); 3830 __ testb(result_, Immediate(kStringRepresentationMask));
3808 __ j(zero, &flat_string); 3831 __ j(zero, &flat_string);
3809 3832
3810 // Handle non-flat strings. 3833 // Handle non-flat strings.
3811 __ testb(result_, Immediate(kIsConsStringMask)); 3834 __ and_(result_, Immediate(kStringRepresentationMask));
3812 __ j(zero, &call_runtime_); 3835 STATIC_ASSERT((kConsStringTag < kExternalStringTag));
3836 STATIC_ASSERT((kSlicedStringTag > kExternalStringTag));
3837 __ cmpb(result_, Immediate(kExternalStringTag));
3838 __ j(greater, &sliced_string);
3839 __ j(equal, &call_runtime_);
3813 3840
3814 // ConsString. 3841 // ConsString.
3815 // Check whether the right hand side is the empty string (i.e. if 3842 // Check whether the right hand side is the empty string (i.e. if
3816 // this is really a flat string in a cons string). If that is not 3843 // this is really a flat string in a cons string). If that is not
3817 // the case we would rather go to the runtime system now to flatten 3844 // the case we would rather go to the runtime system now to flatten
3818 // the string. 3845 // the string.
3846 Label assure_seq_string;
3819 __ CompareRoot(FieldOperand(object_, ConsString::kSecondOffset), 3847 __ CompareRoot(FieldOperand(object_, ConsString::kSecondOffset),
3820 Heap::kEmptyStringRootIndex); 3848 Heap::kEmptyStringRootIndex);
3821 __ j(not_equal, &call_runtime_); 3849 __ j(not_equal, &call_runtime_);
3822 // Get the first of the two strings and load its instance type. 3850 // Get the first of the two strings and load its instance type.
3823 __ movq(object_, FieldOperand(object_, ConsString::kFirstOffset)); 3851 __ movq(object_, FieldOperand(object_, ConsString::kFirstOffset));
3852 __ jmp(&assure_seq_string, Label::kNear);
3853
3854 // SlicedString, unpack and add offset.
3855 __ bind(&sliced_string);
3856 __ addq(scratch_, FieldOperand(object_, SlicedString::kOffsetOffset));
3857 __ movq(object_, FieldOperand(object_, SlicedString::kParentOffset));
3858
3859 __ bind(&assure_seq_string);
3824 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset)); 3860 __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset));
3825 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 3861 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
3826 // If the first cons component is also non-flat, then go to runtime. 3862 // If the first cons component is also non-flat, then go to runtime.
3827 STATIC_ASSERT(kSeqStringTag == 0); 3863 STATIC_ASSERT(kSeqStringTag == 0);
3828 __ testb(result_, Immediate(kStringRepresentationMask)); 3864 __ testb(result_, Immediate(kStringRepresentationMask));
3829 __ j(not_zero, &call_runtime_); 3865 __ j(not_zero, &call_runtime_);
3866 __ jmp(&flat_string);
3830 3867
3831 // Check for 1-byte or 2-byte string. 3868 // Check for 1-byte or 2-byte string.
3832 __ bind(&flat_string); 3869 __ bind(&flat_string);
3833 STATIC_ASSERT(kAsciiStringTag != 0); 3870 STATIC_ASSERT(kAsciiStringTag != 0);
3834 __ testb(result_, Immediate(kStringEncodingMask)); 3871 __ testb(result_, Immediate(kStringEncodingMask));
3835 __ j(not_zero, &ascii_string); 3872 __ j(not_zero, &ascii_string);
3836 3873
3837 // 2-byte string. 3874 // 2-byte string.
3838 // Load the 2-byte character code into the result register. 3875 // Load the 2-byte character code into the result register.
3839 __ SmiToInteger32(scratch_, scratch_); 3876 __ SmiToInteger32(scratch_, scratch_);
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
4130 __ bind(&string_add_flat_result); 4167 __ bind(&string_add_flat_result);
4131 __ SmiToInteger32(rbx, rbx); 4168 __ SmiToInteger32(rbx, rbx);
4132 __ movl(rcx, r8); 4169 __ movl(rcx, r8);
4133 __ and_(rcx, Immediate(kStringRepresentationMask)); 4170 __ and_(rcx, Immediate(kStringRepresentationMask));
4134 __ cmpl(rcx, Immediate(kExternalStringTag)); 4171 __ cmpl(rcx, Immediate(kExternalStringTag));
4135 __ j(equal, &string_add_runtime); 4172 __ j(equal, &string_add_runtime);
4136 __ movl(rcx, r9); 4173 __ movl(rcx, r9);
4137 __ and_(rcx, Immediate(kStringRepresentationMask)); 4174 __ and_(rcx, Immediate(kStringRepresentationMask));
4138 __ cmpl(rcx, Immediate(kExternalStringTag)); 4175 __ cmpl(rcx, Immediate(kExternalStringTag));
4139 __ j(equal, &string_add_runtime); 4176 __ j(equal, &string_add_runtime);
4177 // We cannot encounter sliced strings here since:
4178 STATIC_ASSERT(SlicedString::kMinLength >= String::kMinNonFlatLength);
4140 // Now check if both strings are ascii strings. 4179 // Now check if both strings are ascii strings.
4141 // rax: first string 4180 // rax: first string
4142 // rbx: length of resulting flat string 4181 // rbx: length of resulting flat string
4143 // rdx: second string 4182 // rdx: second string
4144 // r8: instance type of first string 4183 // r8: instance type of first string
4145 // r9: instance type of second string 4184 // r9: instance type of second string
4146 Label non_ascii_string_add_flat_result; 4185 Label non_ascii_string_add_flat_result;
4147 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag); 4186 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag);
4148 __ testl(r8, Immediate(kAsciiStringTag)); 4187 __ testl(r8, Immediate(kAsciiStringTag));
4149 __ j(zero, &non_ascii_string_add_flat_result); 4188 __ j(zero, &non_ascii_string_add_flat_result);
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
4522 // if (hash == 0) hash = 27; 4561 // if (hash == 0) hash = 27;
4523 Label hash_not_zero; 4562 Label hash_not_zero;
4524 __ j(not_zero, &hash_not_zero); 4563 __ j(not_zero, &hash_not_zero);
4525 __ Set(hash, 27); 4564 __ Set(hash, 27);
4526 __ bind(&hash_not_zero); 4565 __ bind(&hash_not_zero);
4527 } 4566 }
4528 4567
4529 void SubStringStub::Generate(MacroAssembler* masm) { 4568 void SubStringStub::Generate(MacroAssembler* masm) {
4530 Label runtime; 4569 Label runtime;
4531 4570
4571 if (FLAG_string_slices) {
4572 __ jmp(&runtime);
4573 }
4532 // Stack frame on entry. 4574 // Stack frame on entry.
4533 // rsp[0]: return address 4575 // rsp[0]: return address
4534 // rsp[8]: to 4576 // rsp[8]: to
4535 // rsp[16]: from 4577 // rsp[16]: from
4536 // rsp[24]: string 4578 // rsp[24]: string
4537 4579
4538 const int kToOffset = 1 * kPointerSize; 4580 const int kToOffset = 1 * kPointerSize;
4539 const int kFromOffset = kToOffset + kPointerSize; 4581 const int kFromOffset = kToOffset + kPointerSize;
4540 const int kStringOffset = kFromOffset + kPointerSize; 4582 const int kStringOffset = kFromOffset + kPointerSize;
4541 const int kArgumentsSize = (kStringOffset + kPointerSize) - kToOffset; 4583 const int kArgumentsSize = (kStringOffset + kPointerSize) - kToOffset;
(...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after
5283 __ Drop(1); 5325 __ Drop(1);
5284 __ ret(2 * kPointerSize); 5326 __ ret(2 * kPointerSize);
5285 } 5327 }
5286 5328
5287 5329
5288 #undef __ 5330 #undef __
5289 5331
5290 } } // namespace v8::internal 5332 } } // namespace v8::internal
5291 5333
5292 #endif // V8_TARGET_ARCH_X64 5334 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698