| 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_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 | 136 |
| 137 __ ret(0); | 137 __ ret(0); |
| 138 } | 138 } |
| 139 | 139 |
| 140 | 140 |
| 141 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { | 141 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { |
| 142 // We don't allow a GC during a store buffer overflow so there is no need to | 142 // We don't allow a GC during a store buffer overflow so there is no need to |
| 143 // store the registers in any particular way, but we do have to store and | 143 // store the registers in any particular way, but we do have to store and |
| 144 // restore them. | 144 // restore them. |
| 145 __ pushad(); | 145 __ pushad(); |
| 146 if (save_doubles_ == kSaveFPRegs) { | 146 if (save_doubles()) { |
| 147 __ sub(esp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); | 147 __ sub(esp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); |
| 148 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { | 148 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { |
| 149 XMMRegister reg = XMMRegister::from_code(i); | 149 XMMRegister reg = XMMRegister::from_code(i); |
| 150 __ movsd(Operand(esp, i * kDoubleSize), reg); | 150 __ movsd(Operand(esp, i * kDoubleSize), reg); |
| 151 } | 151 } |
| 152 } | 152 } |
| 153 const int argument_count = 1; | 153 const int argument_count = 1; |
| 154 | 154 |
| 155 AllowExternalCallThatCantCauseGC scope(masm); | 155 AllowExternalCallThatCantCauseGC scope(masm); |
| 156 __ PrepareCallCFunction(argument_count, ecx); | 156 __ PrepareCallCFunction(argument_count, ecx); |
| 157 __ mov(Operand(esp, 0 * kPointerSize), | 157 __ mov(Operand(esp, 0 * kPointerSize), |
| 158 Immediate(ExternalReference::isolate_address(isolate()))); | 158 Immediate(ExternalReference::isolate_address(isolate()))); |
| 159 __ CallCFunction( | 159 __ CallCFunction( |
| 160 ExternalReference::store_buffer_overflow_function(isolate()), | 160 ExternalReference::store_buffer_overflow_function(isolate()), |
| 161 argument_count); | 161 argument_count); |
| 162 if (save_doubles_ == kSaveFPRegs) { | 162 if (save_doubles()) { |
| 163 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { | 163 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { |
| 164 XMMRegister reg = XMMRegister::from_code(i); | 164 XMMRegister reg = XMMRegister::from_code(i); |
| 165 __ movsd(reg, Operand(esp, i * kDoubleSize)); | 165 __ movsd(reg, Operand(esp, i * kDoubleSize)); |
| 166 } | 166 } |
| 167 __ add(esp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); | 167 __ add(esp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); |
| 168 } | 168 } |
| 169 __ popad(); | 169 __ popad(); |
| 170 __ ret(0); | 170 __ ret(0); |
| 171 } | 171 } |
| 172 | 172 |
| (...skipping 1573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1746 __ ret(0); | 1746 __ ret(0); |
| 1747 } | 1747 } |
| 1748 | 1748 |
| 1749 __ bind(&check_for_strings); | 1749 __ bind(&check_for_strings); |
| 1750 | 1750 |
| 1751 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, | 1751 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, |
| 1752 &check_unequal_objects); | 1752 &check_unequal_objects); |
| 1753 | 1753 |
| 1754 // Inline comparison of ASCII strings. | 1754 // Inline comparison of ASCII strings. |
| 1755 if (cc == equal) { | 1755 if (cc == equal) { |
| 1756 StringCompareStub::GenerateFlatAsciiStringEquals(masm, | 1756 StringHelper::GenerateFlatAsciiStringEquals(masm, edx, eax, ecx, ebx); |
| 1757 edx, | |
| 1758 eax, | |
| 1759 ecx, | |
| 1760 ebx); | |
| 1761 } else { | 1757 } else { |
| 1762 StringCompareStub::GenerateCompareFlatAsciiStrings(masm, | 1758 StringHelper::GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, |
| 1763 edx, | 1759 edi); |
| 1764 eax, | |
| 1765 ecx, | |
| 1766 ebx, | |
| 1767 edi); | |
| 1768 } | 1760 } |
| 1769 #ifdef DEBUG | 1761 #ifdef DEBUG |
| 1770 __ Abort(kUnexpectedFallThroughFromStringComparison); | 1762 __ Abort(kUnexpectedFallThroughFromStringComparison); |
| 1771 #endif | 1763 #endif |
| 1772 | 1764 |
| 1773 __ bind(&check_unequal_objects); | 1765 __ bind(&check_unequal_objects); |
| 1774 if (cc == equal && !strict()) { | 1766 if (cc == equal && !strict()) { |
| 1775 // Non-strict equality. Objects are unequal if | 1767 // Non-strict equality. Objects are unequal if |
| 1776 // they are both JSObjects and not undetectable, | 1768 // they are both JSObjects and not undetectable, |
| 1777 // and their pointers are different. | 1769 // and their pointers are different. |
| (...skipping 1410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3188 // ecx: sub string length (smi) | 3180 // ecx: sub string length (smi) |
| 3189 // edx: from index (smi) | 3181 // edx: from index (smi) |
| 3190 StringCharAtGenerator generator( | 3182 StringCharAtGenerator generator( |
| 3191 eax, edx, ecx, eax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); | 3183 eax, edx, ecx, eax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); |
| 3192 generator.GenerateFast(masm); | 3184 generator.GenerateFast(masm); |
| 3193 __ ret(3 * kPointerSize); | 3185 __ ret(3 * kPointerSize); |
| 3194 generator.SkipSlow(masm, &runtime); | 3186 generator.SkipSlow(masm, &runtime); |
| 3195 } | 3187 } |
| 3196 | 3188 |
| 3197 | 3189 |
| 3198 void StringCompareStub::GenerateFlatAsciiStringEquals(MacroAssembler* masm, | 3190 void StringHelper::GenerateFlatAsciiStringEquals(MacroAssembler* masm, |
| 3199 Register left, | 3191 Register left, Register right, |
| 3200 Register right, | 3192 Register scratch1, |
| 3201 Register scratch1, | 3193 Register scratch2) { |
| 3202 Register scratch2) { | |
| 3203 Register length = scratch1; | 3194 Register length = scratch1; |
| 3204 | 3195 |
| 3205 // Compare lengths. | 3196 // Compare lengths. |
| 3206 Label strings_not_equal, check_zero_length; | 3197 Label strings_not_equal, check_zero_length; |
| 3207 __ mov(length, FieldOperand(left, String::kLengthOffset)); | 3198 __ mov(length, FieldOperand(left, String::kLengthOffset)); |
| 3208 __ cmp(length, FieldOperand(right, String::kLengthOffset)); | 3199 __ cmp(length, FieldOperand(right, String::kLengthOffset)); |
| 3209 __ j(equal, &check_zero_length, Label::kNear); | 3200 __ j(equal, &check_zero_length, Label::kNear); |
| 3210 __ bind(&strings_not_equal); | 3201 __ bind(&strings_not_equal); |
| 3211 __ Move(eax, Immediate(Smi::FromInt(NOT_EQUAL))); | 3202 __ Move(eax, Immediate(Smi::FromInt(NOT_EQUAL))); |
| 3212 __ ret(0); | 3203 __ ret(0); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3224 __ bind(&compare_chars); | 3215 __ bind(&compare_chars); |
| 3225 GenerateAsciiCharsCompareLoop(masm, left, right, length, scratch2, | 3216 GenerateAsciiCharsCompareLoop(masm, left, right, length, scratch2, |
| 3226 &strings_not_equal, Label::kNear); | 3217 &strings_not_equal, Label::kNear); |
| 3227 | 3218 |
| 3228 // Characters are equal. | 3219 // Characters are equal. |
| 3229 __ Move(eax, Immediate(Smi::FromInt(EQUAL))); | 3220 __ Move(eax, Immediate(Smi::FromInt(EQUAL))); |
| 3230 __ ret(0); | 3221 __ ret(0); |
| 3231 } | 3222 } |
| 3232 | 3223 |
| 3233 | 3224 |
| 3234 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, | 3225 void StringHelper::GenerateCompareFlatAsciiStrings( |
| 3235 Register left, | 3226 MacroAssembler* masm, Register left, Register right, Register scratch1, |
| 3236 Register right, | 3227 Register scratch2, Register scratch3) { |
| 3237 Register scratch1, | |
| 3238 Register scratch2, | |
| 3239 Register scratch3) { | |
| 3240 Counters* counters = masm->isolate()->counters(); | 3228 Counters* counters = masm->isolate()->counters(); |
| 3241 __ IncrementCounter(counters->string_compare_native(), 1); | 3229 __ IncrementCounter(counters->string_compare_native(), 1); |
| 3242 | 3230 |
| 3243 // Find minimum length. | 3231 // Find minimum length. |
| 3244 Label left_shorter; | 3232 Label left_shorter; |
| 3245 __ mov(scratch1, FieldOperand(left, String::kLengthOffset)); | 3233 __ mov(scratch1, FieldOperand(left, String::kLengthOffset)); |
| 3246 __ mov(scratch3, scratch1); | 3234 __ mov(scratch3, scratch1); |
| 3247 __ sub(scratch3, FieldOperand(right, String::kLengthOffset)); | 3235 __ sub(scratch3, FieldOperand(right, String::kLengthOffset)); |
| 3248 | 3236 |
| 3249 Register length_delta = scratch3; | 3237 Register length_delta = scratch3; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3290 __ Move(eax, Immediate(Smi::FromInt(LESS))); | 3278 __ Move(eax, Immediate(Smi::FromInt(LESS))); |
| 3291 __ ret(0); | 3279 __ ret(0); |
| 3292 | 3280 |
| 3293 // Result is GREATER. | 3281 // Result is GREATER. |
| 3294 __ bind(&result_greater); | 3282 __ bind(&result_greater); |
| 3295 __ Move(eax, Immediate(Smi::FromInt(GREATER))); | 3283 __ Move(eax, Immediate(Smi::FromInt(GREATER))); |
| 3296 __ ret(0); | 3284 __ ret(0); |
| 3297 } | 3285 } |
| 3298 | 3286 |
| 3299 | 3287 |
| 3300 void StringCompareStub::GenerateAsciiCharsCompareLoop( | 3288 void StringHelper::GenerateAsciiCharsCompareLoop( |
| 3301 MacroAssembler* masm, | 3289 MacroAssembler* masm, Register left, Register right, Register length, |
| 3302 Register left, | 3290 Register scratch, Label* chars_not_equal, |
| 3303 Register right, | |
| 3304 Register length, | |
| 3305 Register scratch, | |
| 3306 Label* chars_not_equal, | |
| 3307 Label::Distance chars_not_equal_near) { | 3291 Label::Distance chars_not_equal_near) { |
| 3308 // Change index to run from -length to -1 by adding length to string | 3292 // Change index to run from -length to -1 by adding length to string |
| 3309 // start. This means that loop ends when index reaches zero, which | 3293 // start. This means that loop ends when index reaches zero, which |
| 3310 // doesn't need an additional compare. | 3294 // doesn't need an additional compare. |
| 3311 __ SmiUntag(length); | 3295 __ SmiUntag(length); |
| 3312 __ lea(left, | 3296 __ lea(left, |
| 3313 FieldOperand(left, length, times_1, SeqOneByteString::kHeaderSize)); | 3297 FieldOperand(left, length, times_1, SeqOneByteString::kHeaderSize)); |
| 3314 __ lea(right, | 3298 __ lea(right, |
| 3315 FieldOperand(right, length, times_1, SeqOneByteString::kHeaderSize)); | 3299 FieldOperand(right, length, times_1, SeqOneByteString::kHeaderSize)); |
| 3316 __ neg(length); | 3300 __ neg(length); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3350 __ bind(¬_same); | 3334 __ bind(¬_same); |
| 3351 | 3335 |
| 3352 // Check that both objects are sequential ASCII strings. | 3336 // Check that both objects are sequential ASCII strings. |
| 3353 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, &runtime); | 3337 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, &runtime); |
| 3354 | 3338 |
| 3355 // Compare flat ASCII strings. | 3339 // Compare flat ASCII strings. |
| 3356 // Drop arguments from the stack. | 3340 // Drop arguments from the stack. |
| 3357 __ pop(ecx); | 3341 __ pop(ecx); |
| 3358 __ add(esp, Immediate(2 * kPointerSize)); | 3342 __ add(esp, Immediate(2 * kPointerSize)); |
| 3359 __ push(ecx); | 3343 __ push(ecx); |
| 3360 GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi); | 3344 StringHelper::GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi); |
| 3361 | 3345 |
| 3362 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 3346 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
| 3363 // tagged as a small integer. | 3347 // tagged as a small integer. |
| 3364 __ bind(&runtime); | 3348 __ bind(&runtime); |
| 3365 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 3349 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| 3366 } | 3350 } |
| 3367 | 3351 |
| 3368 | 3352 |
| 3369 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { | 3353 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { |
| 3370 // ----------- S t a t e ------------- | 3354 // ----------- S t a t e ------------- |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3651 __ ret(0); | 3635 __ ret(0); |
| 3652 __ bind(&do_compare); | 3636 __ bind(&do_compare); |
| 3653 } | 3637 } |
| 3654 | 3638 |
| 3655 // Check that both strings are sequential ASCII. | 3639 // Check that both strings are sequential ASCII. |
| 3656 Label runtime; | 3640 Label runtime; |
| 3657 __ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime); | 3641 __ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime); |
| 3658 | 3642 |
| 3659 // Compare flat ASCII strings. Returns when done. | 3643 // Compare flat ASCII strings. Returns when done. |
| 3660 if (equality) { | 3644 if (equality) { |
| 3661 StringCompareStub::GenerateFlatAsciiStringEquals( | 3645 StringHelper::GenerateFlatAsciiStringEquals(masm, left, right, tmp1, tmp2); |
| 3662 masm, left, right, tmp1, tmp2); | |
| 3663 } else { | 3646 } else { |
| 3664 StringCompareStub::GenerateCompareFlatAsciiStrings( | 3647 StringHelper::GenerateCompareFlatAsciiStrings(masm, left, right, tmp1, tmp2, |
| 3665 masm, left, right, tmp1, tmp2, tmp3); | 3648 tmp3); |
| 3666 } | 3649 } |
| 3667 | 3650 |
| 3668 // Handle more complex cases in runtime. | 3651 // Handle more complex cases in runtime. |
| 3669 __ bind(&runtime); | 3652 __ bind(&runtime); |
| 3670 __ pop(tmp1); // Return address. | 3653 __ pop(tmp1); // Return address. |
| 3671 __ push(left); | 3654 __ push(left); |
| 3672 __ push(right); | 3655 __ push(right); |
| 3673 __ push(tmp1); | 3656 __ push(tmp1); |
| 3674 if (equality) { | 3657 if (equality) { |
| 3675 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); | 3658 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); |
| (...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4781 Operand(ebp, 7 * kPointerSize), | 4764 Operand(ebp, 7 * kPointerSize), |
| 4782 NULL); | 4765 NULL); |
| 4783 } | 4766 } |
| 4784 | 4767 |
| 4785 | 4768 |
| 4786 #undef __ | 4769 #undef __ |
| 4787 | 4770 |
| 4788 } } // namespace v8::internal | 4771 } } // namespace v8::internal |
| 4789 | 4772 |
| 4790 #endif // V8_TARGET_ARCH_IA32 | 4773 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |