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 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 // Fast negative check for internalized-to-internalized equality. | 428 // Fast negative check for internalized-to-internalized equality. |
429 // See call site for description. | 429 // See call site for description. |
430 static void EmitCheckForInternalizedStringsOrObjects( | 430 static void EmitCheckForInternalizedStringsOrObjects( |
431 MacroAssembler* masm, Register left, Register right, Register left_map, | 431 MacroAssembler* masm, Register left, Register right, Register left_map, |
432 Register right_map, Register left_type, Register right_type, | 432 Register right_map, Register left_type, Register right_type, |
433 Label* possible_strings, Label* runtime_call) { | 433 Label* possible_strings, Label* runtime_call) { |
434 DCHECK(!AreAliased(left, right, left_map, right_map, left_type, right_type)); | 434 DCHECK(!AreAliased(left, right, left_map, right_map, left_type, right_type)); |
435 Register result = x0; | 435 Register result = x0; |
436 DCHECK(left.is(x0) || right.is(x0)); | 436 DCHECK(left.is(x0) || right.is(x0)); |
437 | 437 |
438 Label object_test, return_unequal, undetectable; | 438 Label object_test, return_equal, return_unequal, undetectable; |
439 STATIC_ASSERT((kInternalizedTag == 0) && (kStringTag == 0)); | 439 STATIC_ASSERT((kInternalizedTag == 0) && (kStringTag == 0)); |
440 // TODO(all): reexamine this branch sequence for optimisation wrt branch | 440 // TODO(all): reexamine this branch sequence for optimisation wrt branch |
441 // prediction. | 441 // prediction. |
442 __ Tbnz(right_type, MaskToBit(kIsNotStringMask), &object_test); | 442 __ Tbnz(right_type, MaskToBit(kIsNotStringMask), &object_test); |
443 __ Tbnz(right_type, MaskToBit(kIsNotInternalizedMask), possible_strings); | 443 __ Tbnz(right_type, MaskToBit(kIsNotInternalizedMask), possible_strings); |
444 __ Tbnz(left_type, MaskToBit(kIsNotStringMask), runtime_call); | 444 __ Tbnz(left_type, MaskToBit(kIsNotStringMask), runtime_call); |
445 __ Tbnz(left_type, MaskToBit(kIsNotInternalizedMask), possible_strings); | 445 __ Tbnz(left_type, MaskToBit(kIsNotInternalizedMask), possible_strings); |
446 | 446 |
447 // Both are internalized. We already checked they weren't the same pointer so | 447 // Both are internalized. We already checked they weren't the same pointer so |
448 // they are not equal. Return non-equal by returning the non-zero object | 448 // they are not equal. Return non-equal by returning the non-zero object |
449 // pointer in x0. | 449 // pointer in x0. |
450 __ Ret(); | 450 __ Ret(); |
451 | 451 |
452 __ Bind(&object_test); | 452 __ Bind(&object_test); |
453 | 453 |
454 Register left_bitfield = left_type; | 454 Register left_bitfield = left_type; |
455 Register right_bitfield = right_type; | 455 Register right_bitfield = right_type; |
456 __ Ldrb(right_bitfield, FieldMemOperand(right_map, Map::kBitFieldOffset)); | 456 __ Ldrb(right_bitfield, FieldMemOperand(right_map, Map::kBitFieldOffset)); |
457 __ Ldrb(left_bitfield, FieldMemOperand(left_map, Map::kBitFieldOffset)); | 457 __ Ldrb(left_bitfield, FieldMemOperand(left_map, Map::kBitFieldOffset)); |
458 __ Tbnz(right_bitfield, MaskToBit(1 << Map::kIsUndetectable), &undetectable); | 458 __ Tbnz(right_bitfield, MaskToBit(1 << Map::kIsUndetectable), &undetectable); |
459 __ Tbnz(left_bitfield, MaskToBit(1 << Map::kIsUndetectable), &return_unequal); | 459 __ Tbnz(left_bitfield, MaskToBit(1 << Map::kIsUndetectable), &return_unequal); |
460 | 460 |
461 __ CompareInstanceType(right_map, right_type, FIRST_JS_RECEIVER_TYPE); | 461 __ CompareInstanceType(right_map, right_type, FIRST_JS_RECEIVER_TYPE); |
462 __ B(lt, runtime_call); | 462 __ B(lt, runtime_call); |
463 __ CompareInstanceType(left_map, left_type, FIRST_JS_RECEIVER_TYPE); | 463 __ CompareInstanceType(left_map, left_type, FIRST_JS_RECEIVER_TYPE); |
464 __ B(lt, runtime_call); | 464 __ B(lt, runtime_call); |
465 | 465 |
466 __ bind(&return_unequal); | 466 __ Bind(&return_unequal); |
467 // Return non-equal by returning the non-zero object pointer in x0. | 467 // Return non-equal by returning the non-zero object pointer in x0. |
468 __ Ret(); | 468 __ Ret(); |
469 | 469 |
470 __ bind(&undetectable); | 470 __ Bind(&undetectable); |
471 __ Tbz(left_bitfield, MaskToBit(1 << Map::kIsUndetectable), &return_unequal); | 471 __ Tbz(left_bitfield, MaskToBit(1 << Map::kIsUndetectable), &return_unequal); |
| 472 |
| 473 // If both sides are JSReceivers, then the result is false according to |
| 474 // the HTML specification, which says that only comparisons with null or |
| 475 // undefined are affected by special casing for document.all. |
| 476 __ CompareInstanceType(right_map, right_type, ODDBALL_TYPE); |
| 477 __ B(eq, &return_equal); |
| 478 __ CompareInstanceType(left_map, left_type, ODDBALL_TYPE); |
| 479 __ B(ne, &return_unequal); |
| 480 |
| 481 __ Bind(&return_equal); |
472 __ Mov(result, EQUAL); | 482 __ Mov(result, EQUAL); |
473 __ Ret(); | 483 __ Ret(); |
474 } | 484 } |
475 | 485 |
476 | 486 |
477 static void CompareICStub_CheckInputType(MacroAssembler* masm, Register input, | 487 static void CompareICStub_CheckInputType(MacroAssembler* masm, Register input, |
478 CompareICState::State expected, | 488 CompareICState::State expected, |
479 Label* fail) { | 489 Label* fail) { |
480 Label ok; | 490 Label ok; |
481 if (expected == CompareICState::SMI) { | 491 if (expected == CompareICState::SMI) { |
(...skipping 5492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5974 return_value_operand, NULL); | 5984 return_value_operand, NULL); |
5975 } | 5985 } |
5976 | 5986 |
5977 | 5987 |
5978 #undef __ | 5988 #undef __ |
5979 | 5989 |
5980 } // namespace internal | 5990 } // namespace internal |
5981 } // namespace v8 | 5991 } // namespace v8 |
5982 | 5992 |
5983 #endif // V8_TARGET_ARCH_ARM64 | 5993 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |