Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Side by Side Diff: src/arm64/code-stubs-arm64.cc

Issue 1130283002: [strong] Disallow implicit conversions for comparison (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: cl feedback Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/arm/lithium-codegen-arm.cc ('k') | src/arm64/full-codegen-arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_ARM64 7 #if V8_TARGET_ARCH_ARM64
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 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 __ Bind(&done); 196 __ Bind(&done);
197 if (!skip_fastpath()) { 197 if (!skip_fastpath()) {
198 __ Pop(double_scratch); 198 __ Pop(double_scratch);
199 } 199 }
200 __ Pop(scratch2, scratch1); 200 __ Pop(scratch2, scratch1);
201 __ Ret(); 201 __ Ret();
202 } 202 }
203 203
204 204
205 // See call site for description. 205 // See call site for description.
206 static void EmitIdenticalObjectComparison(MacroAssembler* masm, 206 static void EmitIdenticalObjectComparison(MacroAssembler* masm, Register left,
207 Register left, 207 Register right, Register scratch,
208 Register right,
209 Register scratch,
210 FPRegister double_scratch, 208 FPRegister double_scratch,
211 Label* slow, 209 Label* slow, Condition cond,
212 Condition cond) { 210 bool strong) {
213 DCHECK(!AreAliased(left, right, scratch)); 211 DCHECK(!AreAliased(left, right, scratch));
214 Label not_identical, return_equal, heap_number; 212 Label not_identical, return_equal, heap_number;
215 Register result = x0; 213 Register result = x0;
216 214
217 __ Cmp(right, left); 215 __ Cmp(right, left);
218 __ B(ne, &not_identical); 216 __ B(ne, &not_identical);
219 217
220 // Test for NaN. Sadly, we can't just compare to factory::nan_value(), 218 // Test for NaN. Sadly, we can't just compare to factory::nan_value(),
221 // so we do the second best thing - test it ourselves. 219 // so we do the second best thing - test it ourselves.
222 // They are both equal and they are not both Smis so both of them are not 220 // They are both equal and they are not both Smis so both of them are not
223 // Smis. If it's not a heap number, then return equal. 221 // Smis. If it's not a heap number, then return equal.
224 Register right_type = scratch; 222 Register right_type = scratch;
225 if ((cond == lt) || (cond == gt)) { 223 if ((cond == lt) || (cond == gt)) {
224 // Call runtime on identical JSObjects. Otherwise return equal.
226 __ JumpIfObjectType(right, right_type, right_type, FIRST_SPEC_OBJECT_TYPE, 225 __ JumpIfObjectType(right, right_type, right_type, FIRST_SPEC_OBJECT_TYPE,
227 slow, ge); 226 slow, ge);
227 // Call runtime on identical symbols since we need to throw a TypeError.
228 __ Cmp(right_type, SYMBOL_TYPE); 228 __ Cmp(right_type, SYMBOL_TYPE);
229 __ B(eq, slow); 229 __ B(eq, slow);
230 if (strong) {
231 // Call the runtime on anything that is converted in the semantics, since
232 // we need to throw a TypeError. Smis have already been ruled out.
233 __ Cmp(right_type, Operand(HEAP_NUMBER_TYPE));
234 __ B(eq, &return_equal);
235 __ Tst(right_type, Operand(kIsNotStringMask));
236 __ B(ne, slow);
237 }
230 } else if (cond == eq) { 238 } else if (cond == eq) {
231 __ JumpIfHeapNumber(right, &heap_number); 239 __ JumpIfHeapNumber(right, &heap_number);
232 } else { 240 } else {
233 __ JumpIfObjectType(right, right_type, right_type, HEAP_NUMBER_TYPE, 241 __ JumpIfObjectType(right, right_type, right_type, HEAP_NUMBER_TYPE,
234 &heap_number); 242 &heap_number);
235 // Comparing JS objects with <=, >= is complicated. 243 // Comparing JS objects with <=, >= is complicated.
236 __ Cmp(right_type, FIRST_SPEC_OBJECT_TYPE); 244 __ Cmp(right_type, FIRST_SPEC_OBJECT_TYPE);
237 __ B(ge, slow); 245 __ B(ge, slow);
246 // Call runtime on identical symbols since we need to throw a TypeError.
238 __ Cmp(right_type, SYMBOL_TYPE); 247 __ Cmp(right_type, SYMBOL_TYPE);
239 __ B(eq, slow); 248 __ B(eq, slow);
249 if (strong) {
250 // Call the runtime on anything that is converted in the semantics,
251 // since we need to throw a TypeError. Smis and heap numbers have
252 // already been ruled out.
253 __ Tst(right_type, Operand(kIsNotStringMask));
254 __ B(ne, slow);
255 }
240 // Normally here we fall through to return_equal, but undefined is 256 // Normally here we fall through to return_equal, but undefined is
241 // special: (undefined == undefined) == true, but 257 // special: (undefined == undefined) == true, but
242 // (undefined <= undefined) == false! See ECMAScript 11.8.5. 258 // (undefined <= undefined) == false! See ECMAScript 11.8.5.
243 if ((cond == le) || (cond == ge)) { 259 if ((cond == le) || (cond == ge)) {
244 __ Cmp(right_type, ODDBALL_TYPE); 260 __ Cmp(right_type, ODDBALL_TYPE);
245 __ B(ne, &return_equal); 261 __ B(ne, &return_equal);
246 __ JumpIfNotRoot(right, Heap::kUndefinedValueRootIndex, &return_equal); 262 __ JumpIfNotRoot(right, Heap::kUndefinedValueRootIndex, &return_equal);
247 if (cond == le) { 263 if (cond == le) {
248 // undefined <= undefined should fail. 264 // undefined <= undefined should fail.
249 __ Mov(result, GREATER); 265 __ Mov(result, GREATER);
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 __ Sub(result, lhs, Operand::UntagSmi(rhs)); 522 __ Sub(result, lhs, Operand::UntagSmi(rhs));
507 __ Ret(); 523 __ Ret();
508 524
509 __ Bind(&not_two_smis); 525 __ Bind(&not_two_smis);
510 526
511 // NOTICE! This code is only reached after a smi-fast-case check, so it is 527 // NOTICE! This code is only reached after a smi-fast-case check, so it is
512 // certain that at least one operand isn't a smi. 528 // certain that at least one operand isn't a smi.
513 529
514 // Handle the case where the objects are identical. Either returns the answer 530 // Handle the case where the objects are identical. Either returns the answer
515 // or goes to slow. Only falls through if the objects were not identical. 531 // or goes to slow. Only falls through if the objects were not identical.
516 EmitIdenticalObjectComparison(masm, lhs, rhs, x10, d0, &slow, cond); 532 EmitIdenticalObjectComparison(masm, lhs, rhs, x10, d0, &slow, cond, strong());
517 533
518 // If either is a smi (we know that at least one is not a smi), then they can 534 // If either is a smi (we know that at least one is not a smi), then they can
519 // only be strictly equal if the other is a HeapNumber. 535 // only be strictly equal if the other is a HeapNumber.
520 __ JumpIfBothNotSmi(lhs, rhs, &not_smis); 536 __ JumpIfBothNotSmi(lhs, rhs, &not_smis);
521 537
522 // Exactly one operand is a smi. EmitSmiNonsmiComparison generates code that 538 // Exactly one operand is a smi. EmitSmiNonsmiComparison generates code that
523 // can: 539 // can:
524 // 1) Return the answer. 540 // 1) Return the answer.
525 // 2) Branch to the slow case. 541 // 2) Branch to the slow case.
526 // 3) Fall through to both_loaded_as_doubles. 542 // 3) Fall through to both_loaded_as_doubles.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 } 641 }
626 642
627 __ Bind(&slow); 643 __ Bind(&slow);
628 644
629 __ Push(lhs, rhs); 645 __ Push(lhs, rhs);
630 // Figure out which native to call and setup the arguments. 646 // Figure out which native to call and setup the arguments.
631 Builtins::JavaScript native; 647 Builtins::JavaScript native;
632 if (cond == eq) { 648 if (cond == eq) {
633 native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS; 649 native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
634 } else { 650 } else {
635 native = Builtins::COMPARE; 651 native = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
636 int ncr; // NaN compare result 652 int ncr; // NaN compare result
637 if ((cond == lt) || (cond == le)) { 653 if ((cond == lt) || (cond == le)) {
638 ncr = GREATER; 654 ncr = GREATER;
639 } else { 655 } else {
640 DCHECK((cond == gt) || (cond == ge)); // remaining cases 656 DCHECK((cond == gt) || (cond == ge)); // remaining cases
641 ncr = LESS; 657 ncr = LESS;
642 } 658 }
643 __ Mov(x10, Smi::FromInt(ncr)); 659 __ Mov(x10, Smi::FromInt(ncr));
644 __ Push(x10); 660 __ Push(x10);
645 } 661 }
(...skipping 2832 matching lines...) Expand 10 before | Expand all | Expand 10 after
3478 3494
3479 __ Bind(&values_in_d_regs); 3495 __ Bind(&values_in_d_regs);
3480 __ Fcmp(lhs_d, rhs_d); 3496 __ Fcmp(lhs_d, rhs_d);
3481 __ B(vs, &unordered); // Overflow flag set if either is NaN. 3497 __ B(vs, &unordered); // Overflow flag set if either is NaN.
3482 STATIC_ASSERT((LESS == -1) && (EQUAL == 0) && (GREATER == 1)); 3498 STATIC_ASSERT((LESS == -1) && (EQUAL == 0) && (GREATER == 1));
3483 __ Cset(result, gt); // gt => 1, otherwise (lt, eq) => 0 (EQUAL). 3499 __ Cset(result, gt); // gt => 1, otherwise (lt, eq) => 0 (EQUAL).
3484 __ Csinv(result, result, xzr, ge); // lt => -1, gt => 1, eq => 0. 3500 __ Csinv(result, result, xzr, ge); // lt => -1, gt => 1, eq => 0.
3485 __ Ret(); 3501 __ Ret();
3486 3502
3487 __ Bind(&unordered); 3503 __ Bind(&unordered);
3488 CompareICStub stub(isolate(), op(), CompareICState::GENERIC, 3504 CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC,
3489 CompareICState::GENERIC, CompareICState::GENERIC); 3505 CompareICState::GENERIC, CompareICState::GENERIC);
3490 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); 3506 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
3491 3507
3492 __ Bind(&maybe_undefined1); 3508 __ Bind(&maybe_undefined1);
3493 if (Token::IsOrderedRelationalCompareOp(op())) { 3509 if (Token::IsOrderedRelationalCompareOp(op())) {
3494 __ JumpIfNotRoot(rhs, Heap::kUndefinedValueRootIndex, &miss); 3510 __ JumpIfNotRoot(rhs, Heap::kUndefinedValueRootIndex, &miss);
3495 __ JumpIfSmi(lhs, &unordered); 3511 __ JumpIfSmi(lhs, &unordered);
3496 __ JumpIfNotHeapNumber(lhs, &maybe_undefined2); 3512 __ JumpIfNotHeapNumber(lhs, &maybe_undefined2);
3497 __ B(&unordered); 3513 __ B(&unordered);
3498 } 3514 }
(...skipping 2262 matching lines...) Expand 10 before | Expand all | Expand 10 after
5761 kStackUnwindSpace, NULL, spill_offset, 5777 kStackUnwindSpace, NULL, spill_offset,
5762 MemOperand(fp, 6 * kPointerSize), NULL); 5778 MemOperand(fp, 6 * kPointerSize), NULL);
5763 } 5779 }
5764 5780
5765 5781
5766 #undef __ 5782 #undef __
5767 5783
5768 } } // namespace v8::internal 5784 } } // namespace v8::internal
5769 5785
5770 #endif // V8_TARGET_ARCH_ARM64 5786 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.cc ('k') | src/arm64/full-codegen-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698