Chromium Code Reviews| 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_ARM | 7 #if V8_TARGET_ARCH_ARM |
| 8 | 8 |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 803 | 803 |
| 804 // Check for both being sequential ASCII strings, and inline if that is the | 804 // Check for both being sequential ASCII strings, and inline if that is the |
| 805 // case. | 805 // case. |
| 806 __ bind(&flat_string_check); | 806 __ bind(&flat_string_check); |
| 807 | 807 |
| 808 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs, rhs, r2, r3, &slow); | 808 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs, rhs, r2, r3, &slow); |
| 809 | 809 |
| 810 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, r2, | 810 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, r2, |
| 811 r3); | 811 r3); |
| 812 if (cc == eq) { | 812 if (cc == eq) { |
| 813 StringCompareStub::GenerateFlatAsciiStringEquals(masm, | 813 StringHelper::GenerateFlatAsciiStringEquals(masm, lhs, rhs, r2, r3, r4); |
| 814 lhs, | |
| 815 rhs, | |
| 816 r2, | |
| 817 r3, | |
| 818 r4); | |
| 819 } else { | 814 } else { |
| 820 StringCompareStub::GenerateCompareFlatAsciiStrings(masm, | 815 StringHelper::GenerateCompareFlatAsciiStrings(masm, lhs, rhs, r2, r3, r4, |
| 821 lhs, | 816 r5); |
| 822 rhs, | |
| 823 r2, | |
| 824 r3, | |
| 825 r4, | |
| 826 r5); | |
| 827 } | 817 } |
| 828 // Never falls through to here. | 818 // Never falls through to here. |
| 829 | 819 |
| 830 __ bind(&slow); | 820 __ bind(&slow); |
| 831 | 821 |
| 832 __ Push(lhs, rhs); | 822 __ Push(lhs, rhs); |
| 833 // Figure out which native to call and setup the arguments. | 823 // Figure out which native to call and setup the arguments. |
| 834 Builtins::JavaScript native; | 824 Builtins::JavaScript native; |
| 835 if (cc == eq) { | 825 if (cc == eq) { |
| 836 native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS; | 826 native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 857 | 847 |
| 858 | 848 |
| 859 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { | 849 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { |
| 860 // We don't allow a GC during a store buffer overflow so there is no need to | 850 // We don't allow a GC during a store buffer overflow so there is no need to |
| 861 // store the registers in any particular way, but we do have to store and | 851 // store the registers in any particular way, but we do have to store and |
| 862 // restore them. | 852 // restore them. |
| 863 __ stm(db_w, sp, kCallerSaved | lr.bit()); | 853 __ stm(db_w, sp, kCallerSaved | lr.bit()); |
| 864 | 854 |
| 865 const Register scratch = r1; | 855 const Register scratch = r1; |
| 866 | 856 |
| 867 if (save_doubles_ == kSaveFPRegs) { | 857 if (save_doubles()) { |
|
mvstanton
2014/09/02 12:38:35
This is a nice thing to do.
| |
| 868 __ SaveFPRegs(sp, scratch); | 858 __ SaveFPRegs(sp, scratch); |
| 869 } | 859 } |
| 870 const int argument_count = 1; | 860 const int argument_count = 1; |
| 871 const int fp_argument_count = 0; | 861 const int fp_argument_count = 0; |
| 872 | 862 |
| 873 AllowExternalCallThatCantCauseGC scope(masm); | 863 AllowExternalCallThatCantCauseGC scope(masm); |
| 874 __ PrepareCallCFunction(argument_count, fp_argument_count, scratch); | 864 __ PrepareCallCFunction(argument_count, fp_argument_count, scratch); |
| 875 __ mov(r0, Operand(ExternalReference::isolate_address(isolate()))); | 865 __ mov(r0, Operand(ExternalReference::isolate_address(isolate()))); |
| 876 __ CallCFunction( | 866 __ CallCFunction( |
| 877 ExternalReference::store_buffer_overflow_function(isolate()), | 867 ExternalReference::store_buffer_overflow_function(isolate()), |
| 878 argument_count); | 868 argument_count); |
| 879 if (save_doubles_ == kSaveFPRegs) { | 869 if (save_doubles()) { |
| 880 __ RestoreFPRegs(sp, scratch); | 870 __ RestoreFPRegs(sp, scratch); |
| 881 } | 871 } |
| 882 __ ldm(ia_w, sp, kCallerSaved | pc.bit()); // Also pop pc to get Ret(0). | 872 __ ldm(ia_w, sp, kCallerSaved | pc.bit()); // Also pop pc to get Ret(0). |
| 883 } | 873 } |
| 884 | 874 |
| 885 | 875 |
| 886 void MathPowStub::Generate(MacroAssembler* masm) { | 876 void MathPowStub::Generate(MacroAssembler* masm) { |
| 887 const Register base = r1; | 877 const Register base = r1; |
| 888 const Register exponent = r2; | 878 const Register exponent = r2; |
| 889 const Register heapnumbermap = r5; | 879 const Register heapnumbermap = r5; |
| (...skipping 2398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3288 __ SmiTag(r3, r3); | 3278 __ SmiTag(r3, r3); |
| 3289 StringCharAtGenerator generator( | 3279 StringCharAtGenerator generator( |
| 3290 r0, r3, r2, r0, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); | 3280 r0, r3, r2, r0, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); |
| 3291 generator.GenerateFast(masm); | 3281 generator.GenerateFast(masm); |
| 3292 __ Drop(3); | 3282 __ Drop(3); |
| 3293 __ Ret(); | 3283 __ Ret(); |
| 3294 generator.SkipSlow(masm, &runtime); | 3284 generator.SkipSlow(masm, &runtime); |
| 3295 } | 3285 } |
| 3296 | 3286 |
| 3297 | 3287 |
| 3298 void StringCompareStub::GenerateFlatAsciiStringEquals(MacroAssembler* masm, | 3288 void StringHelper::GenerateFlatAsciiStringEquals(MacroAssembler* masm, |
| 3299 Register left, | 3289 Register left, Register right, |
| 3300 Register right, | 3290 Register scratch1, |
| 3301 Register scratch1, | 3291 Register scratch2, |
| 3302 Register scratch2, | 3292 Register scratch3) { |
| 3303 Register scratch3) { | |
| 3304 Register length = scratch1; | 3293 Register length = scratch1; |
| 3305 | 3294 |
| 3306 // Compare lengths. | 3295 // Compare lengths. |
| 3307 Label strings_not_equal, check_zero_length; | 3296 Label strings_not_equal, check_zero_length; |
| 3308 __ ldr(length, FieldMemOperand(left, String::kLengthOffset)); | 3297 __ ldr(length, FieldMemOperand(left, String::kLengthOffset)); |
| 3309 __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset)); | 3298 __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset)); |
| 3310 __ cmp(length, scratch2); | 3299 __ cmp(length, scratch2); |
| 3311 __ b(eq, &check_zero_length); | 3300 __ b(eq, &check_zero_length); |
| 3312 __ bind(&strings_not_equal); | 3301 __ bind(&strings_not_equal); |
| 3313 __ mov(r0, Operand(Smi::FromInt(NOT_EQUAL))); | 3302 __ mov(r0, Operand(Smi::FromInt(NOT_EQUAL))); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 3327 GenerateAsciiCharsCompareLoop(masm, | 3316 GenerateAsciiCharsCompareLoop(masm, |
| 3328 left, right, length, scratch2, scratch3, | 3317 left, right, length, scratch2, scratch3, |
| 3329 &strings_not_equal); | 3318 &strings_not_equal); |
| 3330 | 3319 |
| 3331 // Characters are equal. | 3320 // Characters are equal. |
| 3332 __ mov(r0, Operand(Smi::FromInt(EQUAL))); | 3321 __ mov(r0, Operand(Smi::FromInt(EQUAL))); |
| 3333 __ Ret(); | 3322 __ Ret(); |
| 3334 } | 3323 } |
| 3335 | 3324 |
| 3336 | 3325 |
| 3337 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, | 3326 void StringHelper::GenerateCompareFlatAsciiStrings( |
| 3338 Register left, | 3327 MacroAssembler* masm, Register left, Register right, Register scratch1, |
| 3339 Register right, | 3328 Register scratch2, Register scratch3, Register scratch4) { |
| 3340 Register scratch1, | |
| 3341 Register scratch2, | |
| 3342 Register scratch3, | |
| 3343 Register scratch4) { | |
| 3344 Label result_not_equal, compare_lengths; | 3329 Label result_not_equal, compare_lengths; |
| 3345 // Find minimum length and length difference. | 3330 // Find minimum length and length difference. |
| 3346 __ ldr(scratch1, FieldMemOperand(left, String::kLengthOffset)); | 3331 __ ldr(scratch1, FieldMemOperand(left, String::kLengthOffset)); |
| 3347 __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset)); | 3332 __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset)); |
| 3348 __ sub(scratch3, scratch1, Operand(scratch2), SetCC); | 3333 __ sub(scratch3, scratch1, Operand(scratch2), SetCC); |
| 3349 Register length_delta = scratch3; | 3334 Register length_delta = scratch3; |
| 3350 __ mov(scratch1, scratch2, LeaveCC, gt); | 3335 __ mov(scratch1, scratch2, LeaveCC, gt); |
| 3351 Register min_length = scratch1; | 3336 Register min_length = scratch1; |
| 3352 STATIC_ASSERT(kSmiTag == 0); | 3337 STATIC_ASSERT(kSmiTag == 0); |
| 3353 __ cmp(min_length, Operand::Zero()); | 3338 __ cmp(min_length, Operand::Zero()); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 3365 __ mov(r0, Operand(length_delta), SetCC); | 3350 __ mov(r0, Operand(length_delta), SetCC); |
| 3366 __ bind(&result_not_equal); | 3351 __ bind(&result_not_equal); |
| 3367 // Conditionally update the result based either on length_delta or | 3352 // Conditionally update the result based either on length_delta or |
| 3368 // the last comparion performed in the loop above. | 3353 // the last comparion performed in the loop above. |
| 3369 __ mov(r0, Operand(Smi::FromInt(GREATER)), LeaveCC, gt); | 3354 __ mov(r0, Operand(Smi::FromInt(GREATER)), LeaveCC, gt); |
| 3370 __ mov(r0, Operand(Smi::FromInt(LESS)), LeaveCC, lt); | 3355 __ mov(r0, Operand(Smi::FromInt(LESS)), LeaveCC, lt); |
| 3371 __ Ret(); | 3356 __ Ret(); |
| 3372 } | 3357 } |
| 3373 | 3358 |
| 3374 | 3359 |
| 3375 void StringCompareStub::GenerateAsciiCharsCompareLoop( | 3360 void StringHelper::GenerateAsciiCharsCompareLoop( |
| 3376 MacroAssembler* masm, | 3361 MacroAssembler* masm, Register left, Register right, Register length, |
| 3377 Register left, | 3362 Register scratch1, Register scratch2, Label* chars_not_equal) { |
| 3378 Register right, | |
| 3379 Register length, | |
| 3380 Register scratch1, | |
| 3381 Register scratch2, | |
| 3382 Label* chars_not_equal) { | |
| 3383 // Change index to run from -length to -1 by adding length to string | 3363 // Change index to run from -length to -1 by adding length to string |
| 3384 // start. This means that loop ends when index reaches zero, which | 3364 // start. This means that loop ends when index reaches zero, which |
| 3385 // doesn't need an additional compare. | 3365 // doesn't need an additional compare. |
| 3386 __ SmiUntag(length); | 3366 __ SmiUntag(length); |
| 3387 __ add(scratch1, length, | 3367 __ add(scratch1, length, |
| 3388 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); | 3368 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); |
| 3389 __ add(left, left, Operand(scratch1)); | 3369 __ add(left, left, Operand(scratch1)); |
| 3390 __ add(right, right, Operand(scratch1)); | 3370 __ add(right, right, Operand(scratch1)); |
| 3391 __ rsb(length, length, Operand::Zero()); | 3371 __ rsb(length, length, Operand::Zero()); |
| 3392 Register index = length; // index = -length; | 3372 Register index = length; // index = -length; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3424 __ Ret(); | 3404 __ Ret(); |
| 3425 | 3405 |
| 3426 __ bind(¬_same); | 3406 __ bind(¬_same); |
| 3427 | 3407 |
| 3428 // Check that both objects are sequential ASCII strings. | 3408 // Check that both objects are sequential ASCII strings. |
| 3429 __ JumpIfNotBothSequentialAsciiStrings(r1, r0, r2, r3, &runtime); | 3409 __ JumpIfNotBothSequentialAsciiStrings(r1, r0, r2, r3, &runtime); |
| 3430 | 3410 |
| 3431 // Compare flat ASCII strings natively. Remove arguments from stack first. | 3411 // Compare flat ASCII strings natively. Remove arguments from stack first. |
| 3432 __ IncrementCounter(counters->string_compare_native(), 1, r2, r3); | 3412 __ IncrementCounter(counters->string_compare_native(), 1, r2, r3); |
| 3433 __ add(sp, sp, Operand(2 * kPointerSize)); | 3413 __ add(sp, sp, Operand(2 * kPointerSize)); |
| 3434 GenerateCompareFlatAsciiStrings(masm, r1, r0, r2, r3, r4, r5); | 3414 StringHelper::GenerateCompareFlatAsciiStrings(masm, r1, r0, r2, r3, r4, r5); |
| 3435 | 3415 |
| 3436 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 3416 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
| 3437 // tagged as a small integer. | 3417 // tagged as a small integer. |
| 3438 __ bind(&runtime); | 3418 __ bind(&runtime); |
| 3439 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 3419 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| 3440 } | 3420 } |
| 3441 | 3421 |
| 3442 | 3422 |
| 3443 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { | 3423 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { |
| 3444 // ----------- S t a t e ------------- | 3424 // ----------- S t a t e ------------- |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3697 __ Ret(eq); | 3677 __ Ret(eq); |
| 3698 } | 3678 } |
| 3699 | 3679 |
| 3700 // Check that both strings are sequential ASCII. | 3680 // Check that both strings are sequential ASCII. |
| 3701 Label runtime; | 3681 Label runtime; |
| 3702 __ JumpIfBothInstanceTypesAreNotSequentialAscii( | 3682 __ JumpIfBothInstanceTypesAreNotSequentialAscii( |
| 3703 tmp1, tmp2, tmp3, tmp4, &runtime); | 3683 tmp1, tmp2, tmp3, tmp4, &runtime); |
| 3704 | 3684 |
| 3705 // Compare flat ASCII strings. Returns when done. | 3685 // Compare flat ASCII strings. Returns when done. |
| 3706 if (equality) { | 3686 if (equality) { |
| 3707 StringCompareStub::GenerateFlatAsciiStringEquals( | 3687 StringHelper::GenerateFlatAsciiStringEquals(masm, left, right, tmp1, tmp2, |
| 3708 masm, left, right, tmp1, tmp2, tmp3); | 3688 tmp3); |
| 3709 } else { | 3689 } else { |
| 3710 StringCompareStub::GenerateCompareFlatAsciiStrings( | 3690 StringHelper::GenerateCompareFlatAsciiStrings(masm, left, right, tmp1, tmp2, |
| 3711 masm, left, right, tmp1, tmp2, tmp3, tmp4); | 3691 tmp3, tmp4); |
| 3712 } | 3692 } |
| 3713 | 3693 |
| 3714 // Handle more complex cases in runtime. | 3694 // Handle more complex cases in runtime. |
| 3715 __ bind(&runtime); | 3695 __ bind(&runtime); |
| 3716 __ Push(left, right); | 3696 __ Push(left, right); |
| 3717 if (equality) { | 3697 if (equality) { |
| 3718 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); | 3698 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); |
| 3719 } else { | 3699 } else { |
| 3720 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 3700 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| 3721 } | 3701 } |
| (...skipping 1131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4853 MemOperand(fp, 6 * kPointerSize), | 4833 MemOperand(fp, 6 * kPointerSize), |
| 4854 NULL); | 4834 NULL); |
| 4855 } | 4835 } |
| 4856 | 4836 |
| 4857 | 4837 |
| 4858 #undef __ | 4838 #undef __ |
| 4859 | 4839 |
| 4860 } } // namespace v8::internal | 4840 } } // namespace v8::internal |
| 4861 | 4841 |
| 4862 #endif // V8_TARGET_ARCH_ARM | 4842 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |