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

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

Issue 2146293003: [builtins] implement Array.prototype.includes in TurboFan (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix IsComparisonOpcode Created 4 years, 5 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/code-stubs.h" 5 #include "src/code-stubs.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
11 #include "src/code-stub-assembler.h" 11 #include "src/code-stub-assembler.h"
12 #include "src/factory.h" 12 #include "src/factory.h"
13 #include "src/gdb-jit.h" 13 #include "src/gdb-jit.h"
14 #include "src/ic/handler-compiler.h" 14 #include "src/ic/handler-compiler.h"
15 #include "src/ic/ic.h" 15 #include "src/ic/ic.h"
16 #include "src/macro-assembler.h" 16 #include "src/macro-assembler.h"
17 #include "src/parsing/parser.h" 17 #include "src/parsing/parser.h"
18 18
19 namespace v8 { 19 namespace v8 {
20 namespace internal { 20 namespace internal {
21 21
22 enum class StrictEqualsFlags : unsigned char {
23 Normal = 0,
24 NanEqualsNan = 1 << 0,
25 };
26
27 static inline bool operator&(StrictEqualsFlags lhs, StrictEqualsFlags rhs) {
28 return (static_cast<unsigned char>(lhs) & static_cast<unsigned char>(rhs)) !=
29 0;
30 }
22 31
23 RUNTIME_FUNCTION(UnexpectedStubMiss) { 32 RUNTIME_FUNCTION(UnexpectedStubMiss) {
24 FATAL("Unexpected deopt of a stub"); 33 FATAL("Unexpected deopt of a stub");
25 return Smi::FromInt(0); 34 return Smi::FromInt(0);
26 } 35 }
27 36
28 37
29 CodeStubDescriptor::CodeStubDescriptor(CodeStub* stub) 38 CodeStubDescriptor::CodeStubDescriptor(CodeStub* stub)
30 : call_descriptor_(stub->GetCallInterfaceDescriptor()), 39 : call_descriptor_(stub->GetCallInterfaceDescriptor()),
31 stack_parameter_count_(no_reg), 40 stack_parameter_count_(no_reg),
(...skipping 2227 matching lines...) Expand 10 before | Expand all | Expand 10 after
2259 } 2268 }
2260 2269
2261 assembler->Bind(&end); 2270 assembler->Bind(&end);
2262 return result.value(); 2271 return result.value();
2263 } 2272 }
2264 2273
2265 enum ResultMode { kDontNegateResult, kNegateResult }; 2274 enum ResultMode { kDontNegateResult, kNegateResult };
2266 2275
2267 void GenerateEqual_Same(CodeStubAssembler* assembler, compiler::Node* value, 2276 void GenerateEqual_Same(CodeStubAssembler* assembler, compiler::Node* value,
2268 CodeStubAssembler::Label* if_equal, 2277 CodeStubAssembler::Label* if_equal,
2269 CodeStubAssembler::Label* if_notequal) { 2278 CodeStubAssembler::Label* if_notequal,
2279 StrictEqualsFlags flags) {
2270 // In case of abstract or strict equality checks, we need additional checks 2280 // In case of abstract or strict equality checks, we need additional checks
2271 // for NaN values because they are not considered equal, even if both the 2281 // for NaN values because they are not considered equal, even if both the
2272 // left and the right hand side reference exactly the same value. 2282 // left and the right hand side reference exactly the same value.
2273 // TODO(bmeurer): This seems to violate the SIMD.js specification, but it 2283 // TODO(bmeurer): This seems to violate the SIMD.js specification, but it
2274 // seems to be what is tested in the current SIMD.js testsuite. 2284 // seems to be what is tested in the current SIMD.js testsuite.
2275 2285
2276 typedef CodeStubAssembler::Label Label; 2286 typedef CodeStubAssembler::Label Label;
2277 typedef compiler::Node Node; 2287 typedef compiler::Node Node;
2278 2288
2279 // Check if {value} is a Smi or a HeapObject. 2289 // Check if {value} is a Smi or a HeapObject.
2280 Label if_valueissmi(assembler), if_valueisnotsmi(assembler); 2290 Label if_valueissmi(assembler), if_valueisnotsmi(assembler);
2281 assembler->Branch(assembler->WordIsSmi(value), &if_valueissmi, 2291 assembler->Branch(assembler->WordIsSmi(value), &if_valueissmi,
2282 &if_valueisnotsmi); 2292 &if_valueisnotsmi);
2283 2293
2284 assembler->Bind(&if_valueisnotsmi); 2294 assembler->Bind(&if_valueisnotsmi);
2285 { 2295 {
2286 // Load the map of {value}. 2296 // Load the map of {value}.
2287 Node* value_map = assembler->LoadMap(value); 2297 Node* value_map = assembler->LoadMap(value);
2288 2298
2289 // Check if {value} (and therefore {rhs}) is a HeapNumber. 2299 // Check if {value} (and therefore {rhs}) is a HeapNumber.
2290 Node* number_map = assembler->HeapNumberMapConstant(); 2300 Node* number_map = assembler->HeapNumberMapConstant();
2291 Label if_valueisnumber(assembler), if_valueisnotnumber(assembler); 2301 Label if_valueisnumber(assembler), if_valueisnotnumber(assembler);
2292 assembler->Branch(assembler->WordEqual(value_map, number_map), 2302 assembler->Branch(assembler->WordEqual(value_map, number_map),
2293 &if_valueisnumber, &if_valueisnotnumber); 2303 &if_valueisnumber, &if_valueisnotnumber);
2294 2304
2295 assembler->Bind(&if_valueisnumber); 2305 assembler->Bind(&if_valueisnumber);
2296 { 2306 {
2297 // Convert {value} (and therefore {rhs}) to floating point value. 2307 if (flags & StrictEqualsFlags::NanEqualsNan) {
2298 Node* value_value = assembler->LoadHeapNumberValue(value); 2308 // NaN === NaN --- No special treatment
2309 assembler->Goto(if_equal);
2310 } else {
2311 // Convert {value} (and therefore {rhs}) to floating point value.
2312 Node* value_value = assembler->LoadHeapNumberValue(value);
2299 2313
2300 // Check if the HeapNumber value is a NaN. 2314 // Check if the HeapNumber value is a NaN.
2301 assembler->BranchIfFloat64IsNaN(value_value, if_notequal, if_equal); 2315 assembler->BranchIfFloat64IsNaN(value_value, if_notequal, if_equal);
2316 }
2302 } 2317 }
2303 2318
2304 assembler->Bind(&if_valueisnotnumber); 2319 assembler->Bind(&if_valueisnotnumber);
2305 assembler->Goto(if_equal); 2320 assembler->Goto(if_equal);
2306 } 2321 }
2307 2322
2308 assembler->Bind(&if_valueissmi); 2323 assembler->Bind(&if_valueissmi);
2309 assembler->Goto(if_equal); 2324 assembler->Goto(if_equal);
2310 } 2325 }
2311 2326
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
2424 rhs = var_rhs.value(); 2439 rhs = var_rhs.value();
2425 2440
2426 // Check if {lhs} and {rhs} refer to the same object. 2441 // Check if {lhs} and {rhs} refer to the same object.
2427 Label if_same(assembler), if_notsame(assembler); 2442 Label if_same(assembler), if_notsame(assembler);
2428 assembler->Branch(assembler->WordEqual(lhs, rhs), &if_same, &if_notsame); 2443 assembler->Branch(assembler->WordEqual(lhs, rhs), &if_same, &if_notsame);
2429 2444
2430 assembler->Bind(&if_same); 2445 assembler->Bind(&if_same);
2431 { 2446 {
2432 // The {lhs} and {rhs} reference the exact same value, yet we need special 2447 // The {lhs} and {rhs} reference the exact same value, yet we need special
2433 // treatment for HeapNumber, as NaN is not equal to NaN. 2448 // treatment for HeapNumber, as NaN is not equal to NaN.
2434 GenerateEqual_Same(assembler, lhs, &if_equal, &if_notequal); 2449 GenerateEqual_Same(assembler, lhs, &if_equal, &if_notequal,
2450 StrictEqualsFlags::Normal);
2435 } 2451 }
2436 2452
2437 assembler->Bind(&if_notsame); 2453 assembler->Bind(&if_notsame);
2438 { 2454 {
2439 // Check if {lhs} is a Smi or a HeapObject. 2455 // Check if {lhs} is a Smi or a HeapObject.
2440 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler); 2456 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler);
2441 assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, 2457 assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi,
2442 &if_lhsisnotsmi); 2458 &if_lhsisnotsmi);
2443 2459
2444 assembler->Bind(&if_lhsissmi); 2460 assembler->Bind(&if_lhsissmi);
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
2924 assembler->Goto(&end); 2940 assembler->Goto(&end);
2925 } 2941 }
2926 2942
2927 assembler->Bind(&end); 2943 assembler->Bind(&end);
2928 return result.value(); 2944 return result.value();
2929 } 2945 }
2930 2946
2931 compiler::Node* GenerateStrictEqual(CodeStubAssembler* assembler, 2947 compiler::Node* GenerateStrictEqual(CodeStubAssembler* assembler,
2932 ResultMode mode, compiler::Node* lhs, 2948 ResultMode mode, compiler::Node* lhs,
2933 compiler::Node* rhs, 2949 compiler::Node* rhs,
2934 compiler::Node* context) { 2950 compiler::Node* context,
2951 StrictEqualsFlags flags) {
2935 // Here's pseudo-code for the algorithm below in case of kDontNegateResult 2952 // Here's pseudo-code for the algorithm below in case of kDontNegateResult
2936 // mode; for kNegateResult mode we properly negate the result. 2953 // mode; for kNegateResult mode we properly negate the result.
2937 // 2954 //
2938 // if (lhs == rhs) { 2955 // if (lhs == rhs) {
2939 // if (lhs->IsHeapNumber()) return HeapNumber::cast(lhs)->value() != NaN; 2956 // if (lhs->IsHeapNumber()) return HeapNumber::cast(lhs)->value() != NaN;
2940 // return true; 2957 // return true;
2941 // } 2958 // }
2942 // if (!lhs->IsSmi()) { 2959 // if (!lhs->IsSmi()) {
2943 // if (lhs->IsHeapNumber()) { 2960 // if (lhs->IsHeapNumber()) {
2944 // if (rhs->IsSmi()) { 2961 // if (rhs->IsSmi()) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2988 Variable result(assembler, MachineRepresentation::kTagged); 3005 Variable result(assembler, MachineRepresentation::kTagged);
2989 3006
2990 // Check if {lhs} and {rhs} refer to the same object. 3007 // Check if {lhs} and {rhs} refer to the same object.
2991 Label if_same(assembler), if_notsame(assembler); 3008 Label if_same(assembler), if_notsame(assembler);
2992 assembler->Branch(assembler->WordEqual(lhs, rhs), &if_same, &if_notsame); 3009 assembler->Branch(assembler->WordEqual(lhs, rhs), &if_same, &if_notsame);
2993 3010
2994 assembler->Bind(&if_same); 3011 assembler->Bind(&if_same);
2995 { 3012 {
2996 // The {lhs} and {rhs} reference the exact same value, yet we need special 3013 // The {lhs} and {rhs} reference the exact same value, yet we need special
2997 // treatment for HeapNumber, as NaN is not equal to NaN. 3014 // treatment for HeapNumber, as NaN is not equal to NaN.
2998 GenerateEqual_Same(assembler, lhs, &if_equal, &if_notequal); 3015 GenerateEqual_Same(assembler, lhs, &if_equal, &if_notequal, flags);
2999 } 3016 }
3000 3017
3001 assembler->Bind(&if_notsame); 3018 assembler->Bind(&if_notsame);
3002 { 3019 {
3003 // The {lhs} and {rhs} reference different objects, yet for Smi, HeapNumber, 3020 // The {lhs} and {rhs} reference different objects, yet for Smi, HeapNumber,
3004 // String and Simd128Value they can still be considered equal. 3021 // String and Simd128Value they can still be considered equal.
3005 Node* number_map = assembler->HeapNumberMapConstant(); 3022 Node* number_map = assembler->HeapNumberMapConstant();
3006 3023
3007 // Check if {lhs} is a Smi or a HeapObject. 3024 // Check if {lhs} is a Smi or a HeapObject.
3008 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler); 3025 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3045 Label if_rhsisnumber(assembler), if_rhsisnotnumber(assembler); 3062 Label if_rhsisnumber(assembler), if_rhsisnotnumber(assembler);
3046 assembler->Branch(assembler->WordEqual(rhs_map, number_map), 3063 assembler->Branch(assembler->WordEqual(rhs_map, number_map),
3047 &if_rhsisnumber, &if_rhsisnotnumber); 3064 &if_rhsisnumber, &if_rhsisnotnumber);
3048 3065
3049 assembler->Bind(&if_rhsisnumber); 3066 assembler->Bind(&if_rhsisnumber);
3050 { 3067 {
3051 // Convert {lhs} and {rhs} to floating point values. 3068 // Convert {lhs} and {rhs} to floating point values.
3052 Node* lhs_value = assembler->LoadHeapNumberValue(lhs); 3069 Node* lhs_value = assembler->LoadHeapNumberValue(lhs);
3053 Node* rhs_value = assembler->LoadHeapNumberValue(rhs); 3070 Node* rhs_value = assembler->LoadHeapNumberValue(rhs);
3054 3071
3072 if (flags & StrictEqualsFlags::NanEqualsNan) {
3073 Label isnan(assembler), isnotnan(assembler);
3074 assembler->BranchIfFloat64IsNaN(lhs_value, &isnan, &isnotnan);
3075
3076 assembler->Bind(&isnan);
3077 assembler->BranchIfFloat64IsNaN(rhs_value, &if_equal, &isnotnan);
3078
3079 assembler->Bind(&isnotnan);
3080 }
3081
3055 // Perform a floating point comparison of {lhs} and {rhs}. 3082 // Perform a floating point comparison of {lhs} and {rhs}.
3056 assembler->BranchIfFloat64Equal(lhs_value, rhs_value, &if_equal, 3083 assembler->BranchIfFloat64Equal(lhs_value, rhs_value, &if_equal,
3057 &if_notequal); 3084 &if_notequal);
3058 } 3085 }
3059 3086
3060 assembler->Bind(&if_rhsisnotnumber); 3087 assembler->Bind(&if_rhsisnotnumber);
3061 assembler->Goto(&if_notequal); 3088 assembler->Goto(&if_notequal);
3062 } 3089 }
3063 } 3090 }
3064 3091
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
3620 compiler::Node* lhs, compiler::Node* rhs, 3647 compiler::Node* lhs, compiler::Node* rhs,
3621 compiler::Node* context) { 3648 compiler::Node* context) {
3622 return GenerateEqual(assembler, kNegateResult, lhs, rhs, context); 3649 return GenerateEqual(assembler, kNegateResult, lhs, rhs, context);
3623 } 3650 }
3624 3651
3625 // static 3652 // static
3626 compiler::Node* StrictEqualStub::Generate(CodeStubAssembler* assembler, 3653 compiler::Node* StrictEqualStub::Generate(CodeStubAssembler* assembler,
3627 compiler::Node* lhs, 3654 compiler::Node* lhs,
3628 compiler::Node* rhs, 3655 compiler::Node* rhs,
3629 compiler::Node* context) { 3656 compiler::Node* context) {
3630 return GenerateStrictEqual(assembler, kDontNegateResult, lhs, rhs, context); 3657 return GenerateStrictEqual(assembler, kDontNegateResult, lhs, rhs, context,
3658 StrictEqualsFlags::Normal);
3631 } 3659 }
3632 3660
3633 // static 3661 // static
3634 compiler::Node* StrictNotEqualStub::Generate(CodeStubAssembler* assembler, 3662 compiler::Node* StrictNotEqualStub::Generate(CodeStubAssembler* assembler,
3635 compiler::Node* lhs, 3663 compiler::Node* lhs,
3636 compiler::Node* rhs, 3664 compiler::Node* rhs,
3637 compiler::Node* context) { 3665 compiler::Node* context) {
3638 return GenerateStrictEqual(assembler, kNegateResult, lhs, rhs, context); 3666 return GenerateStrictEqual(assembler, kNegateResult, lhs, rhs, context,
3667 StrictEqualsFlags::Normal);
3668 }
3669
3670 compiler::Node* SameValueZeroStub::Generate(CodeStubAssembler* assembler,
3671 compiler::Node* lhs,
3672 compiler::Node* rhs,
3673 compiler::Node* context) {
3674 return GenerateStrictEqual(assembler, kDontNegateResult, lhs, rhs, context,
3675 StrictEqualsFlags::NanEqualsNan);
3639 } 3676 }
3640 3677
3641 void StringEqualStub::GenerateAssembly(CodeStubAssembler* assembler) const { 3678 void StringEqualStub::GenerateAssembly(CodeStubAssembler* assembler) const {
3642 GenerateStringEqual(assembler, kDontNegateResult); 3679 GenerateStringEqual(assembler, kDontNegateResult);
3643 } 3680 }
3644 3681
3645 void StringNotEqualStub::GenerateAssembly(CodeStubAssembler* assembler) const { 3682 void StringNotEqualStub::GenerateAssembly(CodeStubAssembler* assembler) const {
3646 GenerateStringEqual(assembler, kNegateResult); 3683 GenerateStringEqual(assembler, kNegateResult);
3647 } 3684 }
3648 3685
(...skipping 1287 matching lines...) Expand 10 before | Expand all | Expand 10 after
4936 if (type->Is(Type::UntaggedPointer())) { 4973 if (type->Is(Type::UntaggedPointer())) {
4937 return Representation::External(); 4974 return Representation::External();
4938 } 4975 }
4939 4976
4940 DCHECK(!type->Is(Type::Untagged())); 4977 DCHECK(!type->Is(Type::Untagged()));
4941 return Representation::Tagged(); 4978 return Representation::Tagged();
4942 } 4979 }
4943 4980
4944 } // namespace internal 4981 } // namespace internal
4945 } // namespace v8 4982 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698