Commit 376813df authored by Divy Srivastava's avatar Divy Srivastava Committed by V8 LUCI CQ

[fastcall] Implement support for Uint8Array arguments

This CL adds Uint8Array as supported arguments for fast API calls.
It introduces a kUint8 variant to CTypeInfo for use with TypedArrays
only.

Bug: v8:13080
Change-Id: Ie65206078a18acabaafa9c95793f400b8e95373d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3767098
Commit-Queue: Maya Lekova <mslekova@chromium.org>
Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81886}
parent 20a97f8a
...@@ -99,6 +99,7 @@ David Sanders <dsanders11@ucsbalum.com> ...@@ -99,6 +99,7 @@ David Sanders <dsanders11@ucsbalum.com>
Deepak Mohan <hop2deep@gmail.com> Deepak Mohan <hop2deep@gmail.com>
Deon Dior <diaoyuanjie@gmail.com> Deon Dior <diaoyuanjie@gmail.com>
Derek Tu <derek.t@rioslab.org> Derek Tu <derek.t@rioslab.org>
Divy Srivastava <dj.srivastava23@gmail.com>
Dominic Chen <d.c.ddcc@gmail.com> Dominic Chen <d.c.ddcc@gmail.com>
Dominic Farolini <domfarolino@gmail.com> Dominic Farolini <domfarolino@gmail.com>
Douglas Crosher <dtc-v8@scieneer.com> Douglas Crosher <dtc-v8@scieneer.com>
......
...@@ -240,6 +240,7 @@ class CTypeInfo { ...@@ -240,6 +240,7 @@ class CTypeInfo {
enum class Type : uint8_t { enum class Type : uint8_t {
kVoid, kVoid,
kBool, kBool,
kUint8,
kInt32, kInt32,
kUint32, kUint32,
kInt64, kInt64,
...@@ -302,8 +303,9 @@ class CTypeInfo { ...@@ -302,8 +303,9 @@ class CTypeInfo {
constexpr Flags GetFlags() const { return flags_; } constexpr Flags GetFlags() const { return flags_; }
static constexpr bool IsIntegralType(Type type) { static constexpr bool IsIntegralType(Type type) {
return type == Type::kInt32 || type == Type::kUint32 || return type == Type::kUint8 || type == Type::kInt32 ||
type == Type::kInt64 || type == Type::kUint64; type == Type::kUint32 || type == Type::kInt64 ||
type == Type::kUint64;
} }
static constexpr bool IsFloatingPointType(Type type) { static constexpr bool IsFloatingPointType(Type type) {
...@@ -429,6 +431,7 @@ struct AnyCType { ...@@ -429,6 +431,7 @@ struct AnyCType {
double double_value; double double_value;
Local<Object> object_value; Local<Object> object_value;
Local<Array> sequence_value; Local<Array> sequence_value;
const FastApiTypedArray<uint8_t>* uint8_ta_value;
const FastApiTypedArray<int32_t>* int32_ta_value; const FastApiTypedArray<int32_t>* int32_ta_value;
const FastApiTypedArray<uint32_t>* uint32_ta_value; const FastApiTypedArray<uint32_t>* uint32_ta_value;
const FastApiTypedArray<int64_t>* int64_ta_value; const FastApiTypedArray<int64_t>* int64_ta_value;
...@@ -653,7 +656,8 @@ struct CTypeInfoTraits {}; ...@@ -653,7 +656,8 @@ struct CTypeInfoTraits {};
V(int64_t, kInt64) \ V(int64_t, kInt64) \
V(uint64_t, kUint64) \ V(uint64_t, kUint64) \
V(float, kFloat32) \ V(float, kFloat32) \
V(double, kFloat64) V(double, kFloat64) \
V(uint8_t, kUint8)
// Same as above, but includes deprecated types for compatibility. // Same as above, but includes deprecated types for compatibility.
#define ALL_C_TYPES(V) \ #define ALL_C_TYPES(V) \
...@@ -692,7 +696,8 @@ PRIMITIVE_C_TYPES(DEFINE_TYPE_INFO_TRAITS) ...@@ -692,7 +696,8 @@ PRIMITIVE_C_TYPES(DEFINE_TYPE_INFO_TRAITS)
V(int64_t, kInt64) \ V(int64_t, kInt64) \
V(uint64_t, kUint64) \ V(uint64_t, kUint64) \
V(float, kFloat32) \ V(float, kFloat32) \
V(double, kFloat64) V(double, kFloat64) \
V(uint8_t, kUint8)
TYPED_ARRAY_C_TYPES(SPECIALIZE_GET_TYPE_INFO_HELPER_FOR_TA) TYPED_ARRAY_C_TYPES(SPECIALIZE_GET_TYPE_INFO_HELPER_FOR_TA)
......
...@@ -289,6 +289,8 @@ class MachineType { ...@@ -289,6 +289,8 @@ class MachineType {
return MachineType::AnyTagged(); return MachineType::AnyTagged();
case CTypeInfo::Type::kBool: case CTypeInfo::Type::kBool:
return MachineType::Bool(); return MachineType::Bool();
case CTypeInfo::Type::kUint8:
return MachineType::Uint8();
case CTypeInfo::Type::kInt32: case CTypeInfo::Type::kInt32:
return MachineType::Int32(); return MachineType::Int32();
case CTypeInfo::Type::kUint32: case CTypeInfo::Type::kUint32:
......
...@@ -5195,6 +5195,7 @@ Node* EffectControlLinearizer::LowerFastApiCall(Node* node) { ...@@ -5195,6 +5195,7 @@ Node* EffectControlLinearizer::LowerFastApiCall(Node* node) {
c_call_result, CheckForMinusZeroMode::kCheckForMinusZero); c_call_result, CheckForMinusZeroMode::kCheckForMinusZero);
case CTypeInfo::Type::kV8Value: case CTypeInfo::Type::kV8Value:
case CTypeInfo::Type::kApiObject: case CTypeInfo::Type::kApiObject:
case CTypeInfo::Type::kUint8:
UNREACHABLE(); UNREACHABLE();
case CTypeInfo::Type::kAny: case CTypeInfo::Type::kAny:
return ChangeFloat64ToTagged( return ChangeFloat64ToTagged(
......
...@@ -13,6 +13,8 @@ namespace fast_api_call { ...@@ -13,6 +13,8 @@ namespace fast_api_call {
ElementsKind GetTypedArrayElementsKind(CTypeInfo::Type type) { ElementsKind GetTypedArrayElementsKind(CTypeInfo::Type type) {
switch (type) { switch (type) {
case CTypeInfo::Type::kUint8:
return UINT8_ELEMENTS;
case CTypeInfo::Type::kInt32: case CTypeInfo::Type::kInt32:
return INT32_ELEMENTS; return INT32_ELEMENTS;
case CTypeInfo::Type::kUint32: case CTypeInfo::Type::kUint32:
......
...@@ -1898,6 +1898,7 @@ class RepresentationSelector { ...@@ -1898,6 +1898,7 @@ class RepresentationSelector {
} }
switch (type.GetType()) { switch (type.GetType()) {
case CTypeInfo::Type::kVoid: case CTypeInfo::Type::kVoid:
case CTypeInfo::Type::kUint8:
UNREACHABLE(); UNREACHABLE();
case CTypeInfo::Type::kBool: case CTypeInfo::Type::kBool:
return UseInfo::Bool(); return UseInfo::Bool();
......
...@@ -278,6 +278,12 @@ class FastCApiObject { ...@@ -278,6 +278,12 @@ class FastCApiObject {
template <typename T> template <typename T>
static const FastApiTypedArray<T>* AnyCTypeToTypedArray(AnyCType arg); static const FastApiTypedArray<T>* AnyCTypeToTypedArray(AnyCType arg);
template <>
const FastApiTypedArray<uint8_t>* AnyCTypeToTypedArray<uint8_t>(
AnyCType arg) {
return arg.uint8_ta_value;
}
template <> template <>
const FastApiTypedArray<int32_t>* AnyCTypeToTypedArray<int32_t>( const FastApiTypedArray<int32_t>* AnyCTypeToTypedArray<int32_t>(
AnyCType arg) { AnyCType arg) {
...@@ -333,7 +339,6 @@ class FastCApiObject { ...@@ -333,7 +339,6 @@ class FastCApiObject {
FastCApiObject* self = UnwrapObject(receiver); FastCApiObject* self = UnwrapObject(receiver);
CHECK_SELF_OR_FALLBACK(0); CHECK_SELF_OR_FALLBACK(0);
self->fast_call_count_++; self->fast_call_count_++;
if (should_fallback) { if (should_fallback) {
options.fallback = true; options.fallback = true;
return 0; return 0;
...@@ -369,12 +374,15 @@ class FastCApiObject { ...@@ -369,12 +374,15 @@ class FastCApiObject {
size_t length = typed_array_arg->Length(); size_t length = typed_array_arg->Length();
void* data = typed_array_arg->Buffer()->GetBackingStore()->Data(); void* data = typed_array_arg->Buffer()->GetBackingStore()->Data();
if (typed_array_arg->IsInt32Array() || typed_array_arg->IsUint32Array() || if (typed_array_arg->IsUint8Array() || typed_array_arg->IsInt32Array() ||
typed_array_arg->IsUint32Array() ||
typed_array_arg->IsBigInt64Array() || typed_array_arg->IsBigInt64Array() ||
typed_array_arg->IsBigUint64Array()) { typed_array_arg->IsBigUint64Array()) {
int64_t sum = 0; int64_t sum = 0;
for (unsigned i = 0; i < length; ++i) { for (unsigned i = 0; i < length; ++i) {
if (typed_array_arg->IsInt32Array()) { if (typed_array_arg->IsUint8Array()) {
sum += static_cast<uint8_t*>(data)[i];
} else if (typed_array_arg->IsInt32Array()) {
sum += static_cast<int32_t*>(data)[i]; sum += static_cast<int32_t*>(data)[i];
} else if (typed_array_arg->IsUint32Array()) { } else if (typed_array_arg->IsUint32Array()) {
sum += static_cast<uint32_t*>(data)[i]; sum += static_cast<uint32_t*>(data)[i];
...@@ -893,6 +901,18 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) { ...@@ -893,6 +901,18 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
signature, 1, ConstructorBehavior::kThrow, signature, 1, ConstructorBehavior::kThrow,
SideEffectType::kHasSideEffect, &add_all_seq_c_func)); SideEffectType::kHasSideEffect, &add_all_seq_c_func));
CFunction add_all_uint8_typed_array_c_func = CFunction::Make(
FastCApiObject::AddAllTypedArrayFastCallback<uint8_t>
V8_IF_USE_SIMULATOR(
FastCApiObject::AddAllTypedArrayFastCallbackPatch<uint8_t>));
api_obj_ctor->PrototypeTemplate()->Set(
isolate, "add_all_uint8_typed_array",
FunctionTemplate::New(
isolate, FastCApiObject::AddAllTypedArraySlowCallback,
Local<Value>(), signature, 1, ConstructorBehavior::kThrow,
SideEffectType::kHasSideEffect, &add_all_uint8_typed_array_c_func));
CFunction add_all_int32_typed_array_c_func = CFunction::Make( CFunction add_all_int32_typed_array_c_func = CFunction::Make(
FastCApiObject::AddAllTypedArrayFastCallback<int32_t> FastCApiObject::AddAllTypedArrayFastCallback<int32_t>
V8_IF_USE_SIMULATOR( V8_IF_USE_SIMULATOR(
......
...@@ -129,6 +129,15 @@ for (let i = 0; i < 100; i++) { ...@@ -129,6 +129,15 @@ for (let i = 0; i < 100; i++) {
// `add_all_<TYPE>_typed_array` have the following signature: // `add_all_<TYPE>_typed_array` have the following signature:
// double add_all_<TYPE>_typed_array(bool /*should_fallback*/, FastApiTypedArray<TYPE>) // double add_all_<TYPE>_typed_array(bool /*should_fallback*/, FastApiTypedArray<TYPE>)
(function () {
function uint8_test() {
let typed_array = new Uint8Array([1, 2, 3]);
return fast_c_api.add_all_uint8_typed_array(false /* should_fallback */,
typed_array);
}
ExpectFastCall(uint8_test, 6);
})();
(function () { (function () {
function int32_test() { function int32_test() {
let typed_array = new Int32Array([-42, 1, 2, 3]); let typed_array = new Int32Array([-42, 1, 2, 3]);
...@@ -262,6 +271,25 @@ for (let i = 0; i < 100; i++) { ...@@ -262,6 +271,25 @@ for (let i = 0; i < 100; i++) {
ExpectFastCall(int32_test, 0); ExpectFastCall(int32_test, 0);
})(); })();
(function () {
function uint8_test() {
let typed_array = new Uint8Array(0);
return fast_c_api.add_all_uint8_typed_array(false /* should_fallback */,
typed_array);
}
ExpectFastCall(uint8_test, 0);
})();
// Values out of [0, 255] range are properly truncated.
(function() {
function uint8_test() {
let typed_array = new Uint8Array([0, 256, -1]);
return fast_c_api.add_all_uint8_typed_array(false /* should_fallback */,
typed_array);
}
ExpectFastCall(uint8_test, 255);
})();
// Invalid argument types instead of a TypedArray. // Invalid argument types instead of a TypedArray.
(function () { (function () {
function invalid_test(arg) { function invalid_test(arg) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment