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 |