OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_X64 | 7 #if V8_TARGET_ARCH_X64 |
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 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 } | 129 } |
130 ExternalReference miss = descriptor->miss_handler(); | 130 ExternalReference miss = descriptor->miss_handler(); |
131 __ CallExternalReference(miss, param_count); | 131 __ CallExternalReference(miss, param_count); |
132 } | 132 } |
133 | 133 |
134 __ Ret(); | 134 __ Ret(); |
135 } | 135 } |
136 | 136 |
137 | 137 |
138 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { | 138 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { |
139 __ PushCallerSaved(save_doubles_); | 139 __ PushCallerSaved(save_doubles() ? kSaveFPRegs : kDontSaveFPRegs); |
140 const int argument_count = 1; | 140 const int argument_count = 1; |
141 __ PrepareCallCFunction(argument_count); | 141 __ PrepareCallCFunction(argument_count); |
142 __ LoadAddress(arg_reg_1, | 142 __ LoadAddress(arg_reg_1, |
143 ExternalReference::isolate_address(isolate())); | 143 ExternalReference::isolate_address(isolate())); |
144 | 144 |
145 AllowExternalCallThatCantCauseGC scope(masm); | 145 AllowExternalCallThatCantCauseGC scope(masm); |
146 __ CallCFunction( | 146 __ CallCFunction( |
147 ExternalReference::store_buffer_overflow_function(isolate()), | 147 ExternalReference::store_buffer_overflow_function(isolate()), |
148 argument_count); | 148 argument_count); |
149 __ PopCallerSaved(save_doubles_); | 149 __ PopCallerSaved(save_doubles() ? kSaveFPRegs : kDontSaveFPRegs); |
150 __ ret(0); | 150 __ ret(0); |
151 } | 151 } |
152 | 152 |
153 | 153 |
154 class FloatingPointHelper : public AllStatic { | 154 class FloatingPointHelper : public AllStatic { |
155 public: | 155 public: |
156 enum ConvertUndefined { | 156 enum ConvertUndefined { |
157 CONVERT_UNDEFINED_TO_ZERO, | 157 CONVERT_UNDEFINED_TO_ZERO, |
158 BAILOUT_ON_UNDEFINED | 158 BAILOUT_ON_UNDEFINED |
159 }; | 159 }; |
(...skipping 1457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1617 __ ret(0); | 1617 __ ret(0); |
1618 } | 1618 } |
1619 | 1619 |
1620 __ bind(&check_for_strings); | 1620 __ bind(&check_for_strings); |
1621 | 1621 |
1622 __ JumpIfNotBothSequentialAsciiStrings( | 1622 __ JumpIfNotBothSequentialAsciiStrings( |
1623 rdx, rax, rcx, rbx, &check_unequal_objects); | 1623 rdx, rax, rcx, rbx, &check_unequal_objects); |
1624 | 1624 |
1625 // Inline comparison of ASCII strings. | 1625 // Inline comparison of ASCII strings. |
1626 if (cc == equal) { | 1626 if (cc == equal) { |
1627 StringCompareStub::GenerateFlatAsciiStringEquals(masm, | 1627 StringHelper::GenerateFlatAsciiStringEquals(masm, rdx, rax, rcx, rbx); |
1628 rdx, | |
1629 rax, | |
1630 rcx, | |
1631 rbx); | |
1632 } else { | 1628 } else { |
1633 StringCompareStub::GenerateCompareFlatAsciiStrings(masm, | 1629 StringHelper::GenerateCompareFlatAsciiStrings(masm, rdx, rax, rcx, rbx, rdi, |
1634 rdx, | 1630 r8); |
1635 rax, | |
1636 rcx, | |
1637 rbx, | |
1638 rdi, | |
1639 r8); | |
1640 } | 1631 } |
1641 | 1632 |
1642 #ifdef DEBUG | 1633 #ifdef DEBUG |
1643 __ Abort(kUnexpectedFallThroughFromStringComparison); | 1634 __ Abort(kUnexpectedFallThroughFromStringComparison); |
1644 #endif | 1635 #endif |
1645 | 1636 |
1646 __ bind(&check_unequal_objects); | 1637 __ bind(&check_unequal_objects); |
1647 if (cc == equal && !strict()) { | 1638 if (cc == equal && !strict()) { |
1648 // Not strict equality. Objects are unequal if | 1639 // Not strict equality. Objects are unequal if |
1649 // they are both JSObjects and not undetectable, | 1640 // they are both JSObjects and not undetectable, |
(...skipping 1486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3136 // rcx: sub string length (smi) | 3127 // rcx: sub string length (smi) |
3137 // rdx: from index (smi) | 3128 // rdx: from index (smi) |
3138 StringCharAtGenerator generator( | 3129 StringCharAtGenerator generator( |
3139 rax, rdx, rcx, rax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); | 3130 rax, rdx, rcx, rax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); |
3140 generator.GenerateFast(masm); | 3131 generator.GenerateFast(masm); |
3141 __ ret(SUB_STRING_ARGUMENT_COUNT * kPointerSize); | 3132 __ ret(SUB_STRING_ARGUMENT_COUNT * kPointerSize); |
3142 generator.SkipSlow(masm, &runtime); | 3133 generator.SkipSlow(masm, &runtime); |
3143 } | 3134 } |
3144 | 3135 |
3145 | 3136 |
3146 void StringCompareStub::GenerateFlatAsciiStringEquals(MacroAssembler* masm, | 3137 void StringHelper::GenerateFlatAsciiStringEquals(MacroAssembler* masm, |
3147 Register left, | 3138 Register left, Register right, |
3148 Register right, | 3139 Register scratch1, |
3149 Register scratch1, | 3140 Register scratch2) { |
3150 Register scratch2) { | |
3151 Register length = scratch1; | 3141 Register length = scratch1; |
3152 | 3142 |
3153 // Compare lengths. | 3143 // Compare lengths. |
3154 Label check_zero_length; | 3144 Label check_zero_length; |
3155 __ movp(length, FieldOperand(left, String::kLengthOffset)); | 3145 __ movp(length, FieldOperand(left, String::kLengthOffset)); |
3156 __ SmiCompare(length, FieldOperand(right, String::kLengthOffset)); | 3146 __ SmiCompare(length, FieldOperand(right, String::kLengthOffset)); |
3157 __ j(equal, &check_zero_length, Label::kNear); | 3147 __ j(equal, &check_zero_length, Label::kNear); |
3158 __ Move(rax, Smi::FromInt(NOT_EQUAL)); | 3148 __ Move(rax, Smi::FromInt(NOT_EQUAL)); |
3159 __ ret(0); | 3149 __ ret(0); |
3160 | 3150 |
(...skipping 16 matching lines...) Expand all Loading... |
3177 __ Move(rax, Smi::FromInt(EQUAL)); | 3167 __ Move(rax, Smi::FromInt(EQUAL)); |
3178 __ ret(0); | 3168 __ ret(0); |
3179 | 3169 |
3180 // Characters are not equal. | 3170 // Characters are not equal. |
3181 __ bind(&strings_not_equal); | 3171 __ bind(&strings_not_equal); |
3182 __ Move(rax, Smi::FromInt(NOT_EQUAL)); | 3172 __ Move(rax, Smi::FromInt(NOT_EQUAL)); |
3183 __ ret(0); | 3173 __ ret(0); |
3184 } | 3174 } |
3185 | 3175 |
3186 | 3176 |
3187 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, | 3177 void StringHelper::GenerateCompareFlatAsciiStrings( |
3188 Register left, | 3178 MacroAssembler* masm, Register left, Register right, Register scratch1, |
3189 Register right, | 3179 Register scratch2, Register scratch3, Register scratch4) { |
3190 Register scratch1, | |
3191 Register scratch2, | |
3192 Register scratch3, | |
3193 Register scratch4) { | |
3194 // Ensure that you can always subtract a string length from a non-negative | 3180 // Ensure that you can always subtract a string length from a non-negative |
3195 // number (e.g. another length). | 3181 // number (e.g. another length). |
3196 STATIC_ASSERT(String::kMaxLength < 0x7fffffff); | 3182 STATIC_ASSERT(String::kMaxLength < 0x7fffffff); |
3197 | 3183 |
3198 // Find minimum length and length difference. | 3184 // Find minimum length and length difference. |
3199 __ movp(scratch1, FieldOperand(left, String::kLengthOffset)); | 3185 __ movp(scratch1, FieldOperand(left, String::kLengthOffset)); |
3200 __ movp(scratch4, scratch1); | 3186 __ movp(scratch4, scratch1); |
3201 __ SmiSub(scratch4, | 3187 __ SmiSub(scratch4, |
3202 scratch4, | 3188 scratch4, |
3203 FieldOperand(right, String::kLengthOffset)); | 3189 FieldOperand(right, String::kLengthOffset)); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3251 __ Move(rax, Smi::FromInt(LESS)); | 3237 __ Move(rax, Smi::FromInt(LESS)); |
3252 __ ret(0); | 3238 __ ret(0); |
3253 | 3239 |
3254 // Result is GREATER. | 3240 // Result is GREATER. |
3255 __ bind(&result_greater); | 3241 __ bind(&result_greater); |
3256 __ Move(rax, Smi::FromInt(GREATER)); | 3242 __ Move(rax, Smi::FromInt(GREATER)); |
3257 __ ret(0); | 3243 __ ret(0); |
3258 } | 3244 } |
3259 | 3245 |
3260 | 3246 |
3261 void StringCompareStub::GenerateAsciiCharsCompareLoop( | 3247 void StringHelper::GenerateAsciiCharsCompareLoop( |
3262 MacroAssembler* masm, | 3248 MacroAssembler* masm, Register left, Register right, Register length, |
3263 Register left, | 3249 Register scratch, Label* chars_not_equal, Label::Distance near_jump) { |
3264 Register right, | |
3265 Register length, | |
3266 Register scratch, | |
3267 Label* chars_not_equal, | |
3268 Label::Distance near_jump) { | |
3269 // Change index to run from -length to -1 by adding length to string | 3250 // Change index to run from -length to -1 by adding length to string |
3270 // start. This means that loop ends when index reaches zero, which | 3251 // start. This means that loop ends when index reaches zero, which |
3271 // doesn't need an additional compare. | 3252 // doesn't need an additional compare. |
3272 __ SmiToInteger32(length, length); | 3253 __ SmiToInteger32(length, length); |
3273 __ leap(left, | 3254 __ leap(left, |
3274 FieldOperand(left, length, times_1, SeqOneByteString::kHeaderSize)); | 3255 FieldOperand(left, length, times_1, SeqOneByteString::kHeaderSize)); |
3275 __ leap(right, | 3256 __ leap(right, |
3276 FieldOperand(right, length, times_1, SeqOneByteString::kHeaderSize)); | 3257 FieldOperand(right, length, times_1, SeqOneByteString::kHeaderSize)); |
3277 __ negq(length); | 3258 __ negq(length); |
3278 Register index = length; // index = -length; | 3259 Register index = length; // index = -length; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3313 | 3294 |
3314 // Check that both are sequential ASCII strings. | 3295 // Check that both are sequential ASCII strings. |
3315 __ JumpIfNotBothSequentialAsciiStrings(rdx, rax, rcx, rbx, &runtime); | 3296 __ JumpIfNotBothSequentialAsciiStrings(rdx, rax, rcx, rbx, &runtime); |
3316 | 3297 |
3317 // Inline comparison of ASCII strings. | 3298 // Inline comparison of ASCII strings. |
3318 __ IncrementCounter(counters->string_compare_native(), 1); | 3299 __ IncrementCounter(counters->string_compare_native(), 1); |
3319 // Drop arguments from the stack | 3300 // Drop arguments from the stack |
3320 __ PopReturnAddressTo(rcx); | 3301 __ PopReturnAddressTo(rcx); |
3321 __ addp(rsp, Immediate(2 * kPointerSize)); | 3302 __ addp(rsp, Immediate(2 * kPointerSize)); |
3322 __ PushReturnAddressFrom(rcx); | 3303 __ PushReturnAddressFrom(rcx); |
3323 GenerateCompareFlatAsciiStrings(masm, rdx, rax, rcx, rbx, rdi, r8); | 3304 StringHelper::GenerateCompareFlatAsciiStrings(masm, rdx, rax, rcx, rbx, rdi, |
| 3305 r8); |
3324 | 3306 |
3325 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 3307 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
3326 // tagged as a small integer. | 3308 // tagged as a small integer. |
3327 __ bind(&runtime); | 3309 __ bind(&runtime); |
3328 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 3310 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
3329 } | 3311 } |
3330 | 3312 |
3331 | 3313 |
3332 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { | 3314 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { |
3333 // ----------- S t a t e ------------- | 3315 // ----------- S t a t e ------------- |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3600 __ ret(0); | 3582 __ ret(0); |
3601 __ bind(&do_compare); | 3583 __ bind(&do_compare); |
3602 } | 3584 } |
3603 | 3585 |
3604 // Check that both strings are sequential ASCII. | 3586 // Check that both strings are sequential ASCII. |
3605 Label runtime; | 3587 Label runtime; |
3606 __ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime); | 3588 __ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime); |
3607 | 3589 |
3608 // Compare flat ASCII strings. Returns when done. | 3590 // Compare flat ASCII strings. Returns when done. |
3609 if (equality) { | 3591 if (equality) { |
3610 StringCompareStub::GenerateFlatAsciiStringEquals( | 3592 StringHelper::GenerateFlatAsciiStringEquals(masm, left, right, tmp1, tmp2); |
3611 masm, left, right, tmp1, tmp2); | |
3612 } else { | 3593 } else { |
3613 StringCompareStub::GenerateCompareFlatAsciiStrings( | 3594 StringHelper::GenerateCompareFlatAsciiStrings(masm, left, right, tmp1, tmp2, |
3614 masm, left, right, tmp1, tmp2, tmp3, kScratchRegister); | 3595 tmp3, kScratchRegister); |
3615 } | 3596 } |
3616 | 3597 |
3617 // Handle more complex cases in runtime. | 3598 // Handle more complex cases in runtime. |
3618 __ bind(&runtime); | 3599 __ bind(&runtime); |
3619 __ PopReturnAddressTo(tmp1); | 3600 __ PopReturnAddressTo(tmp1); |
3620 __ Push(left); | 3601 __ Push(left); |
3621 __ Push(right); | 3602 __ Push(right); |
3622 __ PushReturnAddressFrom(tmp1); | 3603 __ PushReturnAddressFrom(tmp1); |
3623 if (equality) { | 3604 if (equality) { |
3624 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); | 3605 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); |
(...skipping 1123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4748 return_value_operand, | 4729 return_value_operand, |
4749 NULL); | 4730 NULL); |
4750 } | 4731 } |
4751 | 4732 |
4752 | 4733 |
4753 #undef __ | 4734 #undef __ |
4754 | 4735 |
4755 } } // namespace v8::internal | 4736 } } // namespace v8::internal |
4756 | 4737 |
4757 #endif // V8_TARGET_ARCH_X64 | 4738 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |