OLD | NEW |
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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X87 | 7 #if V8_TARGET_ARCH_X87 |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 1419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1430 __ ret(0); | 1430 __ ret(0); |
1431 } | 1431 } |
1432 | 1432 |
1433 __ bind(&check_for_strings); | 1433 __ bind(&check_for_strings); |
1434 | 1434 |
1435 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, | 1435 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, |
1436 &check_unequal_objects); | 1436 &check_unequal_objects); |
1437 | 1437 |
1438 // Inline comparison of ASCII strings. | 1438 // Inline comparison of ASCII strings. |
1439 if (cc == equal) { | 1439 if (cc == equal) { |
1440 StringCompareStub::GenerateFlatAsciiStringEquals(masm, | 1440 StringHelper::GenerateFlatAsciiStringEquals(masm, edx, eax, ecx, ebx); |
1441 edx, | |
1442 eax, | |
1443 ecx, | |
1444 ebx); | |
1445 } else { | 1441 } else { |
1446 StringCompareStub::GenerateCompareFlatAsciiStrings(masm, | 1442 StringHelper::GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, |
1447 edx, | 1443 edi); |
1448 eax, | |
1449 ecx, | |
1450 ebx, | |
1451 edi); | |
1452 } | 1444 } |
1453 #ifdef DEBUG | 1445 #ifdef DEBUG |
1454 __ Abort(kUnexpectedFallThroughFromStringComparison); | 1446 __ Abort(kUnexpectedFallThroughFromStringComparison); |
1455 #endif | 1447 #endif |
1456 | 1448 |
1457 __ bind(&check_unequal_objects); | 1449 __ bind(&check_unequal_objects); |
1458 if (cc == equal && !strict()) { | 1450 if (cc == equal && !strict()) { |
1459 // Non-strict equality. Objects are unequal if | 1451 // Non-strict equality. Objects are unequal if |
1460 // they are both JSObjects and not undetectable, | 1452 // they are both JSObjects and not undetectable, |
1461 // and their pointers are different. | 1453 // and their pointers are different. |
(...skipping 1402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2864 // ecx: sub string length (smi) | 2856 // ecx: sub string length (smi) |
2865 // edx: from index (smi) | 2857 // edx: from index (smi) |
2866 StringCharAtGenerator generator( | 2858 StringCharAtGenerator generator( |
2867 eax, edx, ecx, eax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); | 2859 eax, edx, ecx, eax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); |
2868 generator.GenerateFast(masm); | 2860 generator.GenerateFast(masm); |
2869 __ ret(3 * kPointerSize); | 2861 __ ret(3 * kPointerSize); |
2870 generator.SkipSlow(masm, &runtime); | 2862 generator.SkipSlow(masm, &runtime); |
2871 } | 2863 } |
2872 | 2864 |
2873 | 2865 |
2874 void StringCompareStub::GenerateFlatAsciiStringEquals(MacroAssembler* masm, | 2866 void StringHelper::GenerateFlatAsciiStringEquals(MacroAssembler* masm, |
2875 Register left, | 2867 Register left, Register right, |
2876 Register right, | 2868 Register scratch1, |
2877 Register scratch1, | 2869 Register scratch2) { |
2878 Register scratch2) { | |
2879 Register length = scratch1; | 2870 Register length = scratch1; |
2880 | 2871 |
2881 // Compare lengths. | 2872 // Compare lengths. |
2882 Label strings_not_equal, check_zero_length; | 2873 Label strings_not_equal, check_zero_length; |
2883 __ mov(length, FieldOperand(left, String::kLengthOffset)); | 2874 __ mov(length, FieldOperand(left, String::kLengthOffset)); |
2884 __ cmp(length, FieldOperand(right, String::kLengthOffset)); | 2875 __ cmp(length, FieldOperand(right, String::kLengthOffset)); |
2885 __ j(equal, &check_zero_length, Label::kNear); | 2876 __ j(equal, &check_zero_length, Label::kNear); |
2886 __ bind(&strings_not_equal); | 2877 __ bind(&strings_not_equal); |
2887 __ Move(eax, Immediate(Smi::FromInt(NOT_EQUAL))); | 2878 __ Move(eax, Immediate(Smi::FromInt(NOT_EQUAL))); |
2888 __ ret(0); | 2879 __ ret(0); |
(...skipping 11 matching lines...) Expand all Loading... |
2900 __ bind(&compare_chars); | 2891 __ bind(&compare_chars); |
2901 GenerateAsciiCharsCompareLoop(masm, left, right, length, scratch2, | 2892 GenerateAsciiCharsCompareLoop(masm, left, right, length, scratch2, |
2902 &strings_not_equal, Label::kNear); | 2893 &strings_not_equal, Label::kNear); |
2903 | 2894 |
2904 // Characters are equal. | 2895 // Characters are equal. |
2905 __ Move(eax, Immediate(Smi::FromInt(EQUAL))); | 2896 __ Move(eax, Immediate(Smi::FromInt(EQUAL))); |
2906 __ ret(0); | 2897 __ ret(0); |
2907 } | 2898 } |
2908 | 2899 |
2909 | 2900 |
2910 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, | 2901 void StringHelper::GenerateCompareFlatAsciiStrings( |
2911 Register left, | 2902 MacroAssembler* masm, Register left, Register right, Register scratch1, |
2912 Register right, | 2903 Register scratch2, Register scratch3) { |
2913 Register scratch1, | |
2914 Register scratch2, | |
2915 Register scratch3) { | |
2916 Counters* counters = masm->isolate()->counters(); | 2904 Counters* counters = masm->isolate()->counters(); |
2917 __ IncrementCounter(counters->string_compare_native(), 1); | 2905 __ IncrementCounter(counters->string_compare_native(), 1); |
2918 | 2906 |
2919 // Find minimum length. | 2907 // Find minimum length. |
2920 Label left_shorter; | 2908 Label left_shorter; |
2921 __ mov(scratch1, FieldOperand(left, String::kLengthOffset)); | 2909 __ mov(scratch1, FieldOperand(left, String::kLengthOffset)); |
2922 __ mov(scratch3, scratch1); | 2910 __ mov(scratch3, scratch1); |
2923 __ sub(scratch3, FieldOperand(right, String::kLengthOffset)); | 2911 __ sub(scratch3, FieldOperand(right, String::kLengthOffset)); |
2924 | 2912 |
2925 Register length_delta = scratch3; | 2913 Register length_delta = scratch3; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2966 __ Move(eax, Immediate(Smi::FromInt(LESS))); | 2954 __ Move(eax, Immediate(Smi::FromInt(LESS))); |
2967 __ ret(0); | 2955 __ ret(0); |
2968 | 2956 |
2969 // Result is GREATER. | 2957 // Result is GREATER. |
2970 __ bind(&result_greater); | 2958 __ bind(&result_greater); |
2971 __ Move(eax, Immediate(Smi::FromInt(GREATER))); | 2959 __ Move(eax, Immediate(Smi::FromInt(GREATER))); |
2972 __ ret(0); | 2960 __ ret(0); |
2973 } | 2961 } |
2974 | 2962 |
2975 | 2963 |
2976 void StringCompareStub::GenerateAsciiCharsCompareLoop( | 2964 void StringHelper::GenerateAsciiCharsCompareLoop( |
2977 MacroAssembler* masm, | 2965 MacroAssembler* masm, Register left, Register right, Register length, |
2978 Register left, | 2966 Register scratch, Label* chars_not_equal, |
2979 Register right, | |
2980 Register length, | |
2981 Register scratch, | |
2982 Label* chars_not_equal, | |
2983 Label::Distance chars_not_equal_near) { | 2967 Label::Distance chars_not_equal_near) { |
2984 // Change index to run from -length to -1 by adding length to string | 2968 // Change index to run from -length to -1 by adding length to string |
2985 // start. This means that loop ends when index reaches zero, which | 2969 // start. This means that loop ends when index reaches zero, which |
2986 // doesn't need an additional compare. | 2970 // doesn't need an additional compare. |
2987 __ SmiUntag(length); | 2971 __ SmiUntag(length); |
2988 __ lea(left, | 2972 __ lea(left, |
2989 FieldOperand(left, length, times_1, SeqOneByteString::kHeaderSize)); | 2973 FieldOperand(left, length, times_1, SeqOneByteString::kHeaderSize)); |
2990 __ lea(right, | 2974 __ lea(right, |
2991 FieldOperand(right, length, times_1, SeqOneByteString::kHeaderSize)); | 2975 FieldOperand(right, length, times_1, SeqOneByteString::kHeaderSize)); |
2992 __ neg(length); | 2976 __ neg(length); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3026 __ bind(¬_same); | 3010 __ bind(¬_same); |
3027 | 3011 |
3028 // Check that both objects are sequential ASCII strings. | 3012 // Check that both objects are sequential ASCII strings. |
3029 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, &runtime); | 3013 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, &runtime); |
3030 | 3014 |
3031 // Compare flat ASCII strings. | 3015 // Compare flat ASCII strings. |
3032 // Drop arguments from the stack. | 3016 // Drop arguments from the stack. |
3033 __ pop(ecx); | 3017 __ pop(ecx); |
3034 __ add(esp, Immediate(2 * kPointerSize)); | 3018 __ add(esp, Immediate(2 * kPointerSize)); |
3035 __ push(ecx); | 3019 __ push(ecx); |
3036 GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi); | 3020 StringHelper::GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi); |
3037 | 3021 |
3038 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 3022 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
3039 // tagged as a small integer. | 3023 // tagged as a small integer. |
3040 __ bind(&runtime); | 3024 __ bind(&runtime); |
3041 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 3025 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
3042 } | 3026 } |
3043 | 3027 |
3044 | 3028 |
3045 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { | 3029 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { |
3046 // ----------- S t a t e ------------- | 3030 // ----------- S t a t e ------------- |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3299 __ ret(0); | 3283 __ ret(0); |
3300 __ bind(&do_compare); | 3284 __ bind(&do_compare); |
3301 } | 3285 } |
3302 | 3286 |
3303 // Check that both strings are sequential ASCII. | 3287 // Check that both strings are sequential ASCII. |
3304 Label runtime; | 3288 Label runtime; |
3305 __ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime); | 3289 __ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime); |
3306 | 3290 |
3307 // Compare flat ASCII strings. Returns when done. | 3291 // Compare flat ASCII strings. Returns when done. |
3308 if (equality) { | 3292 if (equality) { |
3309 StringCompareStub::GenerateFlatAsciiStringEquals( | 3293 StringHelper::GenerateFlatAsciiStringEquals(masm, left, right, tmp1, tmp2); |
3310 masm, left, right, tmp1, tmp2); | |
3311 } else { | 3294 } else { |
3312 StringCompareStub::GenerateCompareFlatAsciiStrings( | 3295 StringHelper::GenerateCompareFlatAsciiStrings(masm, left, right, tmp1, tmp2, |
3313 masm, left, right, tmp1, tmp2, tmp3); | 3296 tmp3); |
3314 } | 3297 } |
3315 | 3298 |
3316 // Handle more complex cases in runtime. | 3299 // Handle more complex cases in runtime. |
3317 __ bind(&runtime); | 3300 __ bind(&runtime); |
3318 __ pop(tmp1); // Return address. | 3301 __ pop(tmp1); // Return address. |
3319 __ push(left); | 3302 __ push(left); |
3320 __ push(right); | 3303 __ push(right); |
3321 __ push(tmp1); | 3304 __ push(tmp1); |
3322 if (equality) { | 3305 if (equality) { |
3323 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); | 3306 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); |
(...skipping 1098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4422 Operand(ebp, 7 * kPointerSize), | 4405 Operand(ebp, 7 * kPointerSize), |
4423 NULL); | 4406 NULL); |
4424 } | 4407 } |
4425 | 4408 |
4426 | 4409 |
4427 #undef __ | 4410 #undef __ |
4428 | 4411 |
4429 } } // namespace v8::internal | 4412 } } // namespace v8::internal |
4430 | 4413 |
4431 #endif // V8_TARGET_ARCH_X87 | 4414 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |