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

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

Issue 1693833002: Remove strong mode support from binary operations. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comments. Created 4 years, 10 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
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 #if V8_TARGET_ARCH_X64 5 #if V8_TARGET_ARCH_X64
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 1093 matching lines...) Expand 10 before | Expand all | Expand 10 after
1104 // Two identical objects are equal unless they are both NaN or undefined. 1104 // Two identical objects are equal unless they are both NaN or undefined.
1105 { 1105 {
1106 Label not_identical; 1106 Label not_identical;
1107 __ cmpp(rax, rdx); 1107 __ cmpp(rax, rdx);
1108 __ j(not_equal, &not_identical, Label::kNear); 1108 __ j(not_equal, &not_identical, Label::kNear);
1109 1109
1110 if (cc != equal) { 1110 if (cc != equal) {
1111 // Check for undefined. undefined OP undefined is false even though 1111 // Check for undefined. undefined OP undefined is false even though
1112 // undefined == undefined. 1112 // undefined == undefined.
1113 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex); 1113 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex);
1114 if (is_strong(strength())) { 1114 Label check_for_nan;
1115 // In strong mode, this comparison must throw, so call the runtime. 1115 __ j(not_equal, &check_for_nan, Label::kNear);
1116 __ j(equal, &runtime_call, Label::kFar); 1116 __ Set(rax, NegativeComparisonResult(cc));
1117 } else { 1117 __ ret(0);
1118 Label check_for_nan; 1118 __ bind(&check_for_nan);
1119 __ j(not_equal, &check_for_nan, Label::kNear);
1120 __ Set(rax, NegativeComparisonResult(cc));
1121 __ ret(0);
1122 __ bind(&check_for_nan);
1123 }
1124 } 1119 }
1125 1120
1126 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(), 1121 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
1127 // so we do the second best thing - test it ourselves. 1122 // so we do the second best thing - test it ourselves.
1128 Label heap_number; 1123 Label heap_number;
1129 // If it's not a heap number, then return equal for (in)equality operator. 1124 // If it's not a heap number, then return equal for (in)equality operator.
1130 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), 1125 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset),
1131 factory->heap_number_map()); 1126 factory->heap_number_map());
1132 __ j(equal, &heap_number, Label::kNear); 1127 __ j(equal, &heap_number, Label::kNear);
1133 if (cc != equal) { 1128 if (cc != equal) {
1134 __ movp(rcx, FieldOperand(rax, HeapObject::kMapOffset)); 1129 __ movp(rcx, FieldOperand(rax, HeapObject::kMapOffset));
1135 __ movzxbl(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset)); 1130 __ movzxbl(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset));
1136 // Call runtime on identical objects. Otherwise return equal. 1131 // Call runtime on identical objects. Otherwise return equal.
1137 __ cmpb(rcx, Immediate(static_cast<uint8_t>(FIRST_JS_RECEIVER_TYPE))); 1132 __ cmpb(rcx, Immediate(static_cast<uint8_t>(FIRST_JS_RECEIVER_TYPE)));
1138 __ j(above_equal, &runtime_call, Label::kFar); 1133 __ j(above_equal, &runtime_call, Label::kFar);
1139 // Call runtime on identical symbols since we need to throw a TypeError. 1134 // Call runtime on identical symbols since we need to throw a TypeError.
1140 __ cmpb(rcx, Immediate(static_cast<uint8_t>(SYMBOL_TYPE))); 1135 __ cmpb(rcx, Immediate(static_cast<uint8_t>(SYMBOL_TYPE)));
1141 __ j(equal, &runtime_call, Label::kFar); 1136 __ j(equal, &runtime_call, Label::kFar);
1142 // Call runtime on identical SIMD values since we must throw a TypeError. 1137 // Call runtime on identical SIMD values since we must throw a TypeError.
1143 __ cmpb(rcx, Immediate(static_cast<uint8_t>(SIMD128_VALUE_TYPE))); 1138 __ cmpb(rcx, Immediate(static_cast<uint8_t>(SIMD128_VALUE_TYPE)));
1144 __ j(equal, &runtime_call, Label::kFar); 1139 __ j(equal, &runtime_call, Label::kFar);
1145 if (is_strong(strength())) {
1146 // We have already tested for smis and heap numbers, so if both
1147 // arguments are not strings we must proceed to the slow case.
1148 __ testb(rcx, Immediate(kIsNotStringMask));
1149 __ j(not_zero, &runtime_call, Label::kFar);
1150 }
1151 } 1140 }
1152 __ Set(rax, EQUAL); 1141 __ Set(rax, EQUAL);
1153 __ ret(0); 1142 __ ret(0);
1154 1143
1155 __ bind(&heap_number); 1144 __ bind(&heap_number);
1156 // It is a heap number, so return equal if it's not NaN. 1145 // It is a heap number, so return equal if it's not NaN.
1157 // For NaN, return 1 for every condition except greater and 1146 // For NaN, return 1 for every condition except greater and
1158 // greater-equal. Return -1 for them, so the comparison yields 1147 // greater-equal. Return -1 for them, so the comparison yields
1159 // false for all conditions except not-equal. 1148 // false for all conditions except not-equal.
1160 __ Set(rax, EQUAL); 1149 __ Set(rax, EQUAL);
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1336 __ Push(rdx); 1325 __ Push(rdx);
1337 __ Push(rax); 1326 __ Push(rax);
1338 1327
1339 // Figure out which native to call and setup the arguments. 1328 // Figure out which native to call and setup the arguments.
1340 if (cc == equal) { 1329 if (cc == equal) {
1341 __ PushReturnAddressFrom(rcx); 1330 __ PushReturnAddressFrom(rcx);
1342 __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals); 1331 __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals);
1343 } else { 1332 } else {
1344 __ Push(Smi::FromInt(NegativeComparisonResult(cc))); 1333 __ Push(Smi::FromInt(NegativeComparisonResult(cc)));
1345 __ PushReturnAddressFrom(rcx); 1334 __ PushReturnAddressFrom(rcx);
1346 __ TailCallRuntime(is_strong(strength()) ? Runtime::kCompare_Strong 1335 __ TailCallRuntime(Runtime::kCompare);
1347 : Runtime::kCompare);
1348 } 1336 }
1349 1337
1350 __ bind(&miss); 1338 __ bind(&miss);
1351 GenerateMiss(masm); 1339 GenerateMiss(masm);
1352 } 1340 }
1353 1341
1354 1342
1355 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { 1343 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) {
1356 // rax : number of arguments to the construct function 1344 // rax : number of arguments to the construct function
1357 // rbx : feedback vector 1345 // rbx : feedback vector
(...skipping 1536 matching lines...) Expand 10 before | Expand all | Expand 10 after
2894 Label miss; 2882 Label miss;
2895 Label::Distance const miss_distance = 2883 Label::Distance const miss_distance =
2896 masm->emit_debug_code() ? Label::kFar : Label::kNear; 2884 masm->emit_debug_code() ? Label::kFar : Label::kNear;
2897 2885
2898 __ JumpIfSmi(rdx, &miss, miss_distance); 2886 __ JumpIfSmi(rdx, &miss, miss_distance);
2899 __ movp(rcx, FieldOperand(rdx, HeapObject::kMapOffset)); 2887 __ movp(rcx, FieldOperand(rdx, HeapObject::kMapOffset));
2900 __ JumpIfSmi(rax, &miss, miss_distance); 2888 __ JumpIfSmi(rax, &miss, miss_distance);
2901 __ movp(rbx, FieldOperand(rax, HeapObject::kMapOffset)); 2889 __ movp(rbx, FieldOperand(rax, HeapObject::kMapOffset));
2902 __ JumpIfNotRoot(rcx, Heap::kBooleanMapRootIndex, &miss, miss_distance); 2890 __ JumpIfNotRoot(rcx, Heap::kBooleanMapRootIndex, &miss, miss_distance);
2903 __ JumpIfNotRoot(rbx, Heap::kBooleanMapRootIndex, &miss, miss_distance); 2891 __ JumpIfNotRoot(rbx, Heap::kBooleanMapRootIndex, &miss, miss_distance);
2904 if (op() != Token::EQ_STRICT && is_strong(strength())) { 2892 if (!Token::IsEqualityOp(op())) {
2905 __ TailCallRuntime(Runtime::kThrowStrongModeImplicitConversion); 2893 __ movp(rax, FieldOperand(rax, Oddball::kToNumberOffset));
2906 } else { 2894 __ AssertSmi(rax);
2907 if (!Token::IsEqualityOp(op())) { 2895 __ movp(rdx, FieldOperand(rdx, Oddball::kToNumberOffset));
2908 __ movp(rax, FieldOperand(rax, Oddball::kToNumberOffset)); 2896 __ AssertSmi(rdx);
2909 __ AssertSmi(rax); 2897 __ pushq(rax);
2910 __ movp(rdx, FieldOperand(rdx, Oddball::kToNumberOffset)); 2898 __ movq(rax, rdx);
2911 __ AssertSmi(rdx); 2899 __ popq(rdx);
2912 __ pushq(rax);
2913 __ movq(rax, rdx);
2914 __ popq(rdx);
2915 }
2916 __ subp(rax, rdx);
2917 __ Ret();
2918 } 2900 }
2901 __ subp(rax, rdx);
2902 __ Ret();
2919 2903
2920 __ bind(&miss); 2904 __ bind(&miss);
2921 GenerateMiss(masm); 2905 GenerateMiss(masm);
2922 } 2906 }
2923 2907
2924 2908
2925 void CompareICStub::GenerateSmis(MacroAssembler* masm) { 2909 void CompareICStub::GenerateSmis(MacroAssembler* masm) {
2926 DCHECK(state() == CompareICState::SMI); 2910 DCHECK(state() == CompareICState::SMI);
2927 Label miss; 2911 Label miss;
2928 __ JumpIfNotBothSmi(rdx, rax, &miss, Label::kNear); 2912 __ JumpIfNotBothSmi(rdx, rax, &miss, Label::kNear);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2991 // Return a result of -1, 0, or 1, based on EFLAGS. 2975 // Return a result of -1, 0, or 1, based on EFLAGS.
2992 // Performing mov, because xor would destroy the flag register. 2976 // Performing mov, because xor would destroy the flag register.
2993 __ movl(rax, Immediate(0)); 2977 __ movl(rax, Immediate(0));
2994 __ movl(rcx, Immediate(0)); 2978 __ movl(rcx, Immediate(0));
2995 __ setcc(above, rax); // Add one to zero if carry clear and not equal. 2979 __ setcc(above, rax); // Add one to zero if carry clear and not equal.
2996 __ sbbp(rax, rcx); // Subtract one if below (aka. carry set). 2980 __ sbbp(rax, rcx); // Subtract one if below (aka. carry set).
2997 __ ret(0); 2981 __ ret(0);
2998 2982
2999 __ bind(&unordered); 2983 __ bind(&unordered);
3000 __ bind(&generic_stub); 2984 __ bind(&generic_stub);
3001 CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC, 2985 CompareICStub stub(isolate(), op(), CompareICState::GENERIC,
3002 CompareICState::GENERIC, CompareICState::GENERIC); 2986 CompareICState::GENERIC, CompareICState::GENERIC);
3003 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); 2987 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
3004 2988
3005 __ bind(&maybe_undefined1); 2989 __ bind(&maybe_undefined1);
3006 if (Token::IsOrderedRelationalCompareOp(op())) { 2990 if (Token::IsOrderedRelationalCompareOp(op())) {
3007 __ Cmp(rax, isolate()->factory()->undefined_value()); 2991 __ Cmp(rax, isolate()->factory()->undefined_value());
3008 __ j(not_equal, &miss); 2992 __ j(not_equal, &miss);
3009 __ JumpIfSmi(rdx, &unordered); 2993 __ JumpIfSmi(rdx, &unordered);
3010 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rcx); 2994 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rcx);
3011 __ j(not_equal, &maybe_undefined2, Label::kNear); 2995 __ j(not_equal, &maybe_undefined2, Label::kNear);
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
3225 3209
3226 __ GetWeakValue(rdi, cell); 3210 __ GetWeakValue(rdi, cell);
3227 __ cmpp(FieldOperand(rdx, HeapObject::kMapOffset), rdi); 3211 __ cmpp(FieldOperand(rdx, HeapObject::kMapOffset), rdi);
3228 __ j(not_equal, &miss, Label::kNear); 3212 __ j(not_equal, &miss, Label::kNear);
3229 __ cmpp(FieldOperand(rax, HeapObject::kMapOffset), rdi); 3213 __ cmpp(FieldOperand(rax, HeapObject::kMapOffset), rdi);
3230 __ j(not_equal, &miss, Label::kNear); 3214 __ j(not_equal, &miss, Label::kNear);
3231 3215
3232 if (Token::IsEqualityOp(op())) { 3216 if (Token::IsEqualityOp(op())) {
3233 __ subp(rax, rdx); 3217 __ subp(rax, rdx);
3234 __ ret(0); 3218 __ ret(0);
3235 } else if (is_strong(strength())) {
3236 __ TailCallRuntime(Runtime::kThrowStrongModeImplicitConversion);
3237 } else { 3219 } else {
3238 __ PopReturnAddressTo(rcx); 3220 __ PopReturnAddressTo(rcx);
3239 __ Push(rdx); 3221 __ Push(rdx);
3240 __ Push(rax); 3222 __ Push(rax);
3241 __ Push(Smi::FromInt(NegativeComparisonResult(GetCondition()))); 3223 __ Push(Smi::FromInt(NegativeComparisonResult(GetCondition())));
3242 __ PushReturnAddressFrom(rcx); 3224 __ PushReturnAddressFrom(rcx);
3243 __ TailCallRuntime(Runtime::kCompare); 3225 __ TailCallRuntime(Runtime::kCompare);
3244 } 3226 }
3245 3227
3246 __ bind(&miss); 3228 __ bind(&miss);
(...skipping 2274 matching lines...) Expand 10 before | Expand all | Expand 10 after
5521 NULL); 5503 NULL);
5522 } 5504 }
5523 5505
5524 5506
5525 #undef __ 5507 #undef __
5526 5508
5527 } // namespace internal 5509 } // namespace internal
5528 } // namespace v8 5510 } // namespace v8
5529 5511
5530 #endif // V8_TARGET_ARCH_X64 5512 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698