OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 3325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3336 if (!string_check_) { | 3336 if (!string_check_) { |
3337 __ movq(r8, FieldOperand(rax, HeapObject::kMapOffset)); | 3337 __ movq(r8, FieldOperand(rax, HeapObject::kMapOffset)); |
3338 __ movq(r9, FieldOperand(rdx, HeapObject::kMapOffset)); | 3338 __ movq(r9, FieldOperand(rdx, HeapObject::kMapOffset)); |
3339 } | 3339 } |
3340 // Get the instance types of the two strings as they will be needed soon. | 3340 // Get the instance types of the two strings as they will be needed soon. |
3341 __ movzxbl(r8, FieldOperand(r8, Map::kInstanceTypeOffset)); | 3341 __ movzxbl(r8, FieldOperand(r8, Map::kInstanceTypeOffset)); |
3342 __ movzxbl(r9, FieldOperand(r9, Map::kInstanceTypeOffset)); | 3342 __ movzxbl(r9, FieldOperand(r9, Map::kInstanceTypeOffset)); |
3343 | 3343 |
3344 // Look at the length of the result of adding the two strings. | 3344 // Look at the length of the result of adding the two strings. |
3345 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue / 2); | 3345 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue / 2); |
3346 __ SmiAdd(rbx, rbx, rcx, NULL); | 3346 __ SmiAdd(rbx, rbx, rcx); |
3347 // Use the runtime system when adding two one character strings, as it | 3347 // Use the runtime system when adding two one character strings, as it |
3348 // contains optimizations for this specific case using the symbol table. | 3348 // contains optimizations for this specific case using the symbol table. |
3349 __ SmiCompare(rbx, Smi::FromInt(2)); | 3349 __ SmiCompare(rbx, Smi::FromInt(2)); |
3350 __ j(not_equal, &longer_than_two); | 3350 __ j(not_equal, &longer_than_two); |
3351 | 3351 |
3352 // Check that both strings are non-external ascii strings. | 3352 // Check that both strings are non-external ascii strings. |
3353 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r8, r9, rbx, rcx, | 3353 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r8, r9, rbx, rcx, |
3354 &string_add_runtime); | 3354 &string_add_runtime); |
3355 | 3355 |
3356 // Get the two characters forming the sub string. | 3356 // Get the two characters forming the sub string. |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3796 __ j(NegateCondition(is_string), &runtime); | 3796 __ j(NegateCondition(is_string), &runtime); |
3797 | 3797 |
3798 // rax: string | 3798 // rax: string |
3799 // rbx: instance type | 3799 // rbx: instance type |
3800 // Calculate length of sub string using the smi values. | 3800 // Calculate length of sub string using the smi values. |
3801 Label result_longer_than_two; | 3801 Label result_longer_than_two; |
3802 __ movq(rcx, Operand(rsp, kToOffset)); | 3802 __ movq(rcx, Operand(rsp, kToOffset)); |
3803 __ movq(rdx, Operand(rsp, kFromOffset)); | 3803 __ movq(rdx, Operand(rsp, kFromOffset)); |
3804 __ JumpIfNotBothPositiveSmi(rcx, rdx, &runtime); | 3804 __ JumpIfNotBothPositiveSmi(rcx, rdx, &runtime); |
3805 | 3805 |
3806 __ SmiSub(rcx, rcx, rdx, NULL); // Overflow doesn't happen. | 3806 __ SmiSub(rcx, rcx, rdx); // Overflow doesn't happen. |
3807 __ cmpq(FieldOperand(rax, String::kLengthOffset), rcx); | 3807 __ cmpq(FieldOperand(rax, String::kLengthOffset), rcx); |
3808 Label return_rax; | 3808 Label return_rax; |
3809 __ j(equal, &return_rax); | 3809 __ j(equal, &return_rax); |
3810 // Special handling of sub-strings of length 1 and 2. One character strings | 3810 // Special handling of sub-strings of length 1 and 2. One character strings |
3811 // are handled in the runtime system (looked up in the single character | 3811 // are handled in the runtime system (looked up in the single character |
3812 // cache). Two character strings are looked for in the symbol cache. | 3812 // cache). Two character strings are looked for in the symbol cache. |
3813 __ SmiToInteger32(rcx, rcx); | 3813 __ SmiToInteger32(rcx, rcx); |
3814 __ cmpl(rcx, Immediate(2)); | 3814 __ cmpl(rcx, Immediate(2)); |
3815 __ j(greater, &result_longer_than_two); | 3815 __ j(greater, &result_longer_than_two); |
3816 __ j(less, &runtime); | 3816 __ j(less, &runtime); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3929 Register scratch4) { | 3929 Register scratch4) { |
3930 // Ensure that you can always subtract a string length from a non-negative | 3930 // Ensure that you can always subtract a string length from a non-negative |
3931 // number (e.g. another length). | 3931 // number (e.g. another length). |
3932 STATIC_ASSERT(String::kMaxLength < 0x7fffffff); | 3932 STATIC_ASSERT(String::kMaxLength < 0x7fffffff); |
3933 | 3933 |
3934 // Find minimum length and length difference. | 3934 // Find minimum length and length difference. |
3935 __ movq(scratch1, FieldOperand(left, String::kLengthOffset)); | 3935 __ movq(scratch1, FieldOperand(left, String::kLengthOffset)); |
3936 __ movq(scratch4, scratch1); | 3936 __ movq(scratch4, scratch1); |
3937 __ SmiSub(scratch4, | 3937 __ SmiSub(scratch4, |
3938 scratch4, | 3938 scratch4, |
3939 FieldOperand(right, String::kLengthOffset), | 3939 FieldOperand(right, String::kLengthOffset)); |
3940 NULL); | |
3941 // Register scratch4 now holds left.length - right.length. | 3940 // Register scratch4 now holds left.length - right.length. |
3942 const Register length_difference = scratch4; | 3941 const Register length_difference = scratch4; |
3943 NearLabel left_shorter; | 3942 NearLabel left_shorter; |
3944 __ j(less, &left_shorter); | 3943 __ j(less, &left_shorter); |
3945 // The right string isn't longer that the left one. | 3944 // The right string isn't longer that the left one. |
3946 // Get the right string's length by subtracting the (non-negative) difference | 3945 // Get the right string's length by subtracting the (non-negative) difference |
3947 // from the left string's length. | 3946 // from the left string's length. |
3948 __ SmiSub(scratch1, scratch1, length_difference, NULL); | 3947 __ SmiSub(scratch1, scratch1, length_difference); |
3949 __ bind(&left_shorter); | 3948 __ bind(&left_shorter); |
3950 // Register scratch1 now holds Min(left.length, right.length). | 3949 // Register scratch1 now holds Min(left.length, right.length). |
3951 const Register min_length = scratch1; | 3950 const Register min_length = scratch1; |
3952 | 3951 |
3953 NearLabel compare_lengths; | 3952 NearLabel compare_lengths; |
3954 // If min-length is zero, go directly to comparing lengths. | 3953 // If min-length is zero, go directly to comparing lengths. |
3955 __ SmiTest(min_length); | 3954 __ SmiTest(min_length); |
3956 __ j(zero, &compare_lengths); | 3955 __ j(zero, &compare_lengths); |
3957 | 3956 |
3958 __ SmiToInteger32(min_length, min_length); | 3957 __ SmiToInteger32(min_length, min_length); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4046 // tagged as a small integer. | 4045 // tagged as a small integer. |
4047 __ bind(&runtime); | 4046 __ bind(&runtime); |
4048 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 4047 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
4049 } | 4048 } |
4050 | 4049 |
4051 #undef __ | 4050 #undef __ |
4052 | 4051 |
4053 } } // namespace v8::internal | 4052 } } // namespace v8::internal |
4054 | 4053 |
4055 #endif // V8_TARGET_ARCH_X64 | 4054 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |