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 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 __ Cmp(right, left); | 216 __ Cmp(right, left); |
217 __ B(ne, ¬_identical); | 217 __ B(ne, ¬_identical); |
218 | 218 |
219 // Test for NaN. Sadly, we can't just compare to factory::nan_value(), | 219 // Test for NaN. Sadly, we can't just compare to factory::nan_value(), |
220 // so we do the second best thing - test it ourselves. | 220 // so we do the second best thing - test it ourselves. |
221 // They are both equal and they are not both Smis so both of them are not | 221 // They are both equal and they are not both Smis so both of them are not |
222 // Smis. If it's not a heap number, then return equal. | 222 // Smis. If it's not a heap number, then return equal. |
223 Register right_type = scratch; | 223 Register right_type = scratch; |
224 if ((cond == lt) || (cond == gt)) { | 224 if ((cond == lt) || (cond == gt)) { |
225 // Call runtime on identical JSObjects. Otherwise return equal. | 225 // Call runtime on identical JSObjects. Otherwise return equal. |
226 __ JumpIfObjectType(right, right_type, right_type, FIRST_SPEC_OBJECT_TYPE, | 226 __ JumpIfObjectType(right, right_type, right_type, FIRST_JS_RECEIVER_TYPE, |
227 slow, ge); | 227 slow, ge); |
228 // Call runtime on identical symbols since we need to throw a TypeError. | 228 // Call runtime on identical symbols since we need to throw a TypeError. |
229 __ Cmp(right_type, SYMBOL_TYPE); | 229 __ Cmp(right_type, SYMBOL_TYPE); |
230 __ B(eq, slow); | 230 __ B(eq, slow); |
231 // Call runtime on identical SIMD values since we must throw a TypeError. | 231 // Call runtime on identical SIMD values since we must throw a TypeError. |
232 __ Cmp(right_type, SIMD128_VALUE_TYPE); | 232 __ Cmp(right_type, SIMD128_VALUE_TYPE); |
233 __ B(eq, slow); | 233 __ B(eq, slow); |
234 if (is_strong(strength)) { | 234 if (is_strong(strength)) { |
235 // Call the runtime on anything that is converted in the semantics, since | 235 // Call the runtime on anything that is converted in the semantics, since |
236 // we need to throw a TypeError. Smis have already been ruled out. | 236 // we need to throw a TypeError. Smis have already been ruled out. |
237 __ Cmp(right_type, Operand(HEAP_NUMBER_TYPE)); | 237 __ Cmp(right_type, Operand(HEAP_NUMBER_TYPE)); |
238 __ B(eq, &return_equal); | 238 __ B(eq, &return_equal); |
239 __ Tst(right_type, Operand(kIsNotStringMask)); | 239 __ Tst(right_type, Operand(kIsNotStringMask)); |
240 __ B(ne, slow); | 240 __ B(ne, slow); |
241 } | 241 } |
242 } else if (cond == eq) { | 242 } else if (cond == eq) { |
243 __ JumpIfHeapNumber(right, &heap_number); | 243 __ JumpIfHeapNumber(right, &heap_number); |
244 } else { | 244 } else { |
245 __ JumpIfObjectType(right, right_type, right_type, HEAP_NUMBER_TYPE, | 245 __ JumpIfObjectType(right, right_type, right_type, HEAP_NUMBER_TYPE, |
246 &heap_number); | 246 &heap_number); |
247 // Comparing JS objects with <=, >= is complicated. | 247 // Comparing JS objects with <=, >= is complicated. |
248 __ Cmp(right_type, FIRST_SPEC_OBJECT_TYPE); | 248 __ Cmp(right_type, FIRST_JS_RECEIVER_TYPE); |
249 __ B(ge, slow); | 249 __ B(ge, slow); |
250 // Call runtime on identical symbols since we need to throw a TypeError. | 250 // Call runtime on identical symbols since we need to throw a TypeError. |
251 __ Cmp(right_type, SYMBOL_TYPE); | 251 __ Cmp(right_type, SYMBOL_TYPE); |
252 __ B(eq, slow); | 252 __ B(eq, slow); |
253 // Call runtime on identical SIMD values since we must throw a TypeError. | 253 // Call runtime on identical SIMD values since we must throw a TypeError. |
254 __ Cmp(right_type, SIMD128_VALUE_TYPE); | 254 __ Cmp(right_type, SIMD128_VALUE_TYPE); |
255 __ B(eq, slow); | 255 __ B(eq, slow); |
256 if (is_strong(strength)) { | 256 if (is_strong(strength)) { |
257 // Call the runtime on anything that is converted in the semantics, | 257 // Call the runtime on anything that is converted in the semantics, |
258 // since we need to throw a TypeError. Smis and heap numbers have | 258 // since we need to throw a TypeError. Smis and heap numbers have |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 | 329 |
330 if (masm->emit_debug_code()) { | 330 if (masm->emit_debug_code()) { |
331 // We assume that the arguments are not identical. | 331 // We assume that the arguments are not identical. |
332 __ Cmp(left, right); | 332 __ Cmp(left, right); |
333 __ Assert(ne, kExpectedNonIdenticalObjects); | 333 __ Assert(ne, kExpectedNonIdenticalObjects); |
334 } | 334 } |
335 | 335 |
336 // If either operand is a JS object or an oddball value, then they are not | 336 // If either operand is a JS object or an oddball value, then they are not |
337 // equal since their pointers are different. | 337 // equal since their pointers are different. |
338 // There is no test for undetectability in strict equality. | 338 // There is no test for undetectability in strict equality. |
339 STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE); | 339 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); |
340 Label right_non_object; | 340 Label right_non_object; |
341 | 341 |
342 __ Cmp(right_type, FIRST_SPEC_OBJECT_TYPE); | 342 __ Cmp(right_type, FIRST_JS_RECEIVER_TYPE); |
343 __ B(lt, &right_non_object); | 343 __ B(lt, &right_non_object); |
344 | 344 |
345 // Return non-zero - x0 already contains a non-zero pointer. | 345 // Return non-zero - x0 already contains a non-zero pointer. |
346 DCHECK(left.is(x0) || right.is(x0)); | 346 DCHECK(left.is(x0) || right.is(x0)); |
347 Label return_not_equal; | 347 Label return_not_equal; |
348 __ Bind(&return_not_equal); | 348 __ Bind(&return_not_equal); |
349 __ Ret(); | 349 __ Ret(); |
350 | 350 |
351 __ Bind(&right_non_object); | 351 __ Bind(&right_non_object); |
352 | 352 |
353 // Check for oddballs: true, false, null, undefined. | 353 // Check for oddballs: true, false, null, undefined. |
354 __ Cmp(right_type, ODDBALL_TYPE); | 354 __ Cmp(right_type, ODDBALL_TYPE); |
355 | 355 |
356 // If right is not ODDBALL, test left. Otherwise, set eq condition. | 356 // If right is not ODDBALL, test left. Otherwise, set eq condition. |
357 __ Ccmp(left_type, ODDBALL_TYPE, ZFlag, ne); | 357 __ Ccmp(left_type, ODDBALL_TYPE, ZFlag, ne); |
358 | 358 |
359 // If right or left is not ODDBALL, test left >= FIRST_SPEC_OBJECT_TYPE. | 359 // If right or left is not ODDBALL, test left >= FIRST_JS_RECEIVER_TYPE. |
360 // Otherwise, right or left is ODDBALL, so set a ge condition. | 360 // Otherwise, right or left is ODDBALL, so set a ge condition. |
361 __ Ccmp(left_type, FIRST_SPEC_OBJECT_TYPE, NVFlag, ne); | 361 __ Ccmp(left_type, FIRST_JS_RECEIVER_TYPE, NVFlag, ne); |
362 | 362 |
363 __ B(ge, &return_not_equal); | 363 __ B(ge, &return_not_equal); |
364 | 364 |
365 // Internalized strings are unique, so they can only be equal if they are the | 365 // Internalized strings are unique, so they can only be equal if they are the |
366 // same object. We have already tested that case, so if left and right are | 366 // same object. We have already tested that case, so if left and right are |
367 // both internalized strings, they cannot be equal. | 367 // both internalized strings, they cannot be equal. |
368 STATIC_ASSERT((kInternalizedTag == 0) && (kStringTag == 0)); | 368 STATIC_ASSERT((kInternalizedTag == 0) && (kStringTag == 0)); |
369 __ Orr(scratch, left_type, right_type); | 369 __ Orr(scratch, left_type, right_type); |
370 __ TestAndBranchIfAllClear( | 370 __ TestAndBranchIfAllClear( |
371 scratch, kIsNotStringMask | kIsNotInternalizedMask, &return_not_equal); | 371 scratch, kIsNotStringMask | kIsNotInternalizedMask, &return_not_equal); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
464 __ Tbnz(left_type, MaskToBit(kIsNotStringMask), not_both_strings); | 464 __ Tbnz(left_type, MaskToBit(kIsNotStringMask), not_both_strings); |
465 __ Tbnz(left_type, MaskToBit(kIsNotInternalizedMask), possible_strings); | 465 __ Tbnz(left_type, MaskToBit(kIsNotInternalizedMask), possible_strings); |
466 | 466 |
467 // Both are internalized. We already checked that they weren't the same | 467 // Both are internalized. We already checked that they weren't the same |
468 // pointer, so they are not equal. | 468 // pointer, so they are not equal. |
469 __ Mov(result, NOT_EQUAL); | 469 __ Mov(result, NOT_EQUAL); |
470 __ Ret(); | 470 __ Ret(); |
471 | 471 |
472 __ Bind(&object_test); | 472 __ Bind(&object_test); |
473 | 473 |
474 __ Cmp(right_type, FIRST_SPEC_OBJECT_TYPE); | 474 __ Cmp(right_type, FIRST_JS_RECEIVER_TYPE); |
475 | 475 |
476 // If right >= FIRST_SPEC_OBJECT_TYPE, test left. | 476 // If right >= FIRST_JS_RECEIVER_TYPE, test left. |
477 // Otherwise, right < FIRST_SPEC_OBJECT_TYPE, so set lt condition. | 477 // Otherwise, right < FIRST_JS_RECEIVER_TYPE, so set lt condition. |
478 __ Ccmp(left_type, FIRST_SPEC_OBJECT_TYPE, NFlag, ge); | 478 __ Ccmp(left_type, FIRST_JS_RECEIVER_TYPE, NFlag, ge); |
479 | 479 |
480 __ B(lt, not_both_strings); | 480 __ B(lt, not_both_strings); |
481 | 481 |
482 // If both objects are undetectable, they are equal. Otherwise, they are not | 482 // If both objects are undetectable, they are equal. Otherwise, they are not |
483 // equal, since they are different objects and an object is not equal to | 483 // equal, since they are different objects and an object is not equal to |
484 // undefined. | 484 // undefined. |
485 | 485 |
486 // Returning here, so we can corrupt right_type and left_type. | 486 // Returning here, so we can corrupt right_type and left_type. |
487 Register right_bitfield = right_type; | 487 Register right_bitfield = right_type; |
488 Register left_bitfield = left_type; | 488 Register left_bitfield = left_type; |
(...skipping 5304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5793 MemOperand(fp, 6 * kPointerSize), NULL); | 5793 MemOperand(fp, 6 * kPointerSize), NULL); |
5794 } | 5794 } |
5795 | 5795 |
5796 | 5796 |
5797 #undef __ | 5797 #undef __ |
5798 | 5798 |
5799 } // namespace internal | 5799 } // namespace internal |
5800 } // namespace v8 | 5800 } // namespace v8 |
5801 | 5801 |
5802 #endif // V8_TARGET_ARCH_ARM64 | 5802 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |