1 // Copyright 2021 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/compiler/fast-api-calls.h"
6
7 #include "src/compiler/globals.h"
8
9 namespace v8 {
10 namespace internal {
11 namespace compiler {
12 namespace fast_api_call {
13
GetTypedArrayElementsKind(CTypeInfo::Type type)14 ElementsKind GetTypedArrayElementsKind(CTypeInfo::Type type) {
15 switch (type) {
16 case CTypeInfo::Type::kInt32:
17 return INT32_ELEMENTS;
18 case CTypeInfo::Type::kUint32:
19 return UINT32_ELEMENTS;
20 case CTypeInfo::Type::kInt64:
21 return BIGINT64_ELEMENTS;
22 case CTypeInfo::Type::kUint64:
23 return BIGUINT64_ELEMENTS;
24 case CTypeInfo::Type::kFloat32:
25 return FLOAT32_ELEMENTS;
26 case CTypeInfo::Type::kFloat64:
27 return FLOAT64_ELEMENTS;
28 case CTypeInfo::Type::kVoid:
29 case CTypeInfo::Type::kBool:
30 case CTypeInfo::Type::kV8Value:
31 case CTypeInfo::Type::kApiObject:
32 case CTypeInfo::Type::kAny:
33 UNREACHABLE();
34 }
35 }
36
ResolveOverloads(Zone * zone,const FastApiCallFunctionVector & candidates,unsigned int arg_count)37 OverloadsResolutionResult ResolveOverloads(
38 Zone* zone, const FastApiCallFunctionVector& candidates,
39 unsigned int arg_count) {
40 DCHECK_GT(arg_count, 0);
41
42 static constexpr int kReceiver = 1;
43
44 // Only the case of the overload resolution of two functions, one with a
45 // JSArray param and the other with a typed array param is currently
46 // supported.
47 DCHECK_EQ(candidates.size(), 2);
48
49 for (unsigned int arg_index = 0; arg_index < arg_count - kReceiver;
50 arg_index++) {
51 int index_of_func_with_js_array_arg = -1;
52 int index_of_func_with_typed_array_arg = -1;
53 CTypeInfo::Type element_type = CTypeInfo::Type::kVoid;
54
55 for (size_t i = 0; i < candidates.size(); i++) {
56 const CTypeInfo& type_info =
57 candidates[i].signature->ArgumentInfo(arg_index + kReceiver);
58 CTypeInfo::SequenceType sequence_type = type_info.GetSequenceType();
59
60 if (sequence_type == CTypeInfo::SequenceType::kIsSequence) {
61 DCHECK_LT(index_of_func_with_js_array_arg, 0);
62 index_of_func_with_js_array_arg = static_cast<int>(i);
63 } else if (sequence_type == CTypeInfo::SequenceType::kIsTypedArray) {
64 DCHECK_LT(index_of_func_with_typed_array_arg, 0);
65 index_of_func_with_typed_array_arg = static_cast<int>(i);
66 element_type = type_info.GetType();
67 } else {
68 DCHECK_LT(index_of_func_with_js_array_arg, 0);
69 DCHECK_LT(index_of_func_with_typed_array_arg, 0);
70 }
71 }
72
73 if (index_of_func_with_js_array_arg >= 0 &&
74 index_of_func_with_typed_array_arg >= 0) {
75 return {static_cast<int>(arg_index), element_type};
76 }
77 }
78
79 // No overload found with a JSArray and a typed array as i-th argument.
80 return OverloadsResolutionResult::Invalid();
81 }
82
CanOptimizeFastSignature(const CFunctionInfo * c_signature)83 bool CanOptimizeFastSignature(const CFunctionInfo* c_signature) {
84 USE(c_signature);
85
86 #if defined(V8_OS_MACOS) && defined(V8_TARGET_ARCH_ARM64)
87 // On MacArm64 hardware we don't support passing of arguments on the stack.
88 if (c_signature->ArgumentCount() > 8) {
89 return false;
90 }
91 #endif // defined(V8_OS_MACOS) && defined(V8_TARGET_ARCH_ARM64)
92
93 #ifndef V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
94 if (c_signature->ReturnInfo().GetType() == CTypeInfo::Type::kFloat32 ||
95 c_signature->ReturnInfo().GetType() == CTypeInfo::Type::kFloat64) {
96 return false;
97 }
98 #endif
99
100 #ifndef V8_TARGET_ARCH_64_BIT
101 if (c_signature->ReturnInfo().GetType() == CTypeInfo::Type::kInt64 ||
102 c_signature->ReturnInfo().GetType() == CTypeInfo::Type::kUint64) {
103 return false;
104 }
105 #endif
106
107 for (unsigned int i = 0; i < c_signature->ArgumentCount(); ++i) {
108 USE(i);
109
110 #ifndef V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
111 if (c_signature->ArgumentInfo(i).GetType() == CTypeInfo::Type::kFloat32 ||
112 c_signature->ArgumentInfo(i).GetType() == CTypeInfo::Type::kFloat64) {
113 return false;
114 }
115 #endif
116
117 #ifndef V8_TARGET_ARCH_64_BIT
118 if (c_signature->ArgumentInfo(i).GetType() == CTypeInfo::Type::kInt64 ||
119 c_signature->ArgumentInfo(i).GetType() == CTypeInfo::Type::kUint64) {
120 return false;
121 }
122 #endif
123 }
124
125 return true;
126 }
127
128 } // namespace fast_api_call
129 } // namespace compiler
130 } // namespace internal
131 } // namespace v8
132