| 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 |