[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: Maya Lekova <mslekova@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81886}
This commit is contained in:
Divy Srivastava 2022-07-20 20:11:08 +05:30 committed by V8 LUCI CQ
parent 20a97f8ac2
commit 376813dfeb
8 changed files with 67 additions and 7 deletions

View File

@ -99,6 +99,7 @@ David Sanders <dsanders11@ucsbalum.com>
Deepak Mohan <hop2deep@gmail.com>
Deon Dior <diaoyuanjie@gmail.com>
Derek Tu <derek.t@rioslab.org>
Divy Srivastava <dj.srivastava23@gmail.com>
Dominic Chen <d.c.ddcc@gmail.com>
Dominic Farolini <domfarolino@gmail.com>
Douglas Crosher <dtc-v8@scieneer.com>

View File

@ -240,6 +240,7 @@ class CTypeInfo {
enum class Type : uint8_t {
kVoid,
kBool,
kUint8,
kInt32,
kUint32,
kInt64,
@ -302,8 +303,9 @@ class CTypeInfo {
constexpr Flags GetFlags() const { return flags_; }
static constexpr bool IsIntegralType(Type type) {
return type == Type::kInt32 || type == Type::kUint32 ||
type == Type::kInt64 || type == Type::kUint64;
return type == Type::kUint8 || type == Type::kInt32 ||
type == Type::kUint32 || type == Type::kInt64 ||
type == Type::kUint64;
}
static constexpr bool IsFloatingPointType(Type type) {
@ -429,6 +431,7 @@ struct AnyCType {
double double_value;
Local<Object> object_value;
Local<Array> sequence_value;
const FastApiTypedArray<uint8_t>* uint8_ta_value;
const FastApiTypedArray<int32_t>* int32_ta_value;
const FastApiTypedArray<uint32_t>* uint32_ta_value;
const FastApiTypedArray<int64_t>* int64_ta_value;
@ -653,7 +656,8 @@ struct CTypeInfoTraits {};
V(int64_t, kInt64) \
V(uint64_t, kUint64) \
V(float, kFloat32) \
V(double, kFloat64)
V(double, kFloat64) \
V(uint8_t, kUint8)
// Same as above, but includes deprecated types for compatibility.
#define ALL_C_TYPES(V) \
@ -692,7 +696,8 @@ PRIMITIVE_C_TYPES(DEFINE_TYPE_INFO_TRAITS)
V(int64_t, kInt64) \
V(uint64_t, kUint64) \
V(float, kFloat32) \
V(double, kFloat64)
V(double, kFloat64) \
V(uint8_t, kUint8)
TYPED_ARRAY_C_TYPES(SPECIALIZE_GET_TYPE_INFO_HELPER_FOR_TA)

View File

@ -289,6 +289,8 @@ class MachineType {
return MachineType::AnyTagged();
case CTypeInfo::Type::kBool:
return MachineType::Bool();
case CTypeInfo::Type::kUint8:
return MachineType::Uint8();
case CTypeInfo::Type::kInt32:
return MachineType::Int32();
case CTypeInfo::Type::kUint32:

View File

@ -5195,6 +5195,7 @@ Node* EffectControlLinearizer::LowerFastApiCall(Node* node) {
c_call_result, CheckForMinusZeroMode::kCheckForMinusZero);
case CTypeInfo::Type::kV8Value:
case CTypeInfo::Type::kApiObject:
case CTypeInfo::Type::kUint8:
UNREACHABLE();
case CTypeInfo::Type::kAny:
return ChangeFloat64ToTagged(

View File

@ -13,6 +13,8 @@ namespace fast_api_call {
ElementsKind GetTypedArrayElementsKind(CTypeInfo::Type type) {
switch (type) {
case CTypeInfo::Type::kUint8:
return UINT8_ELEMENTS;
case CTypeInfo::Type::kInt32:
return INT32_ELEMENTS;
case CTypeInfo::Type::kUint32:

View File

@ -1898,6 +1898,7 @@ class RepresentationSelector {
}
switch (type.GetType()) {
case CTypeInfo::Type::kVoid:
case CTypeInfo::Type::kUint8:
UNREACHABLE();
case CTypeInfo::Type::kBool:
return UseInfo::Bool();

View File

@ -278,6 +278,12 @@ class FastCApiObject {
template <typename T>
static const FastApiTypedArray<T>* AnyCTypeToTypedArray(AnyCType arg);
template <>
const FastApiTypedArray<uint8_t>* AnyCTypeToTypedArray<uint8_t>(
AnyCType arg) {
return arg.uint8_ta_value;
}
template <>
const FastApiTypedArray<int32_t>* AnyCTypeToTypedArray<int32_t>(
AnyCType arg) {
@ -333,7 +339,6 @@ class FastCApiObject {
FastCApiObject* self = UnwrapObject(receiver);
CHECK_SELF_OR_FALLBACK(0);
self->fast_call_count_++;
if (should_fallback) {
options.fallback = true;
return 0;
@ -369,12 +374,15 @@ class FastCApiObject {
size_t length = typed_array_arg->Length();
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->IsBigUint64Array()) {
int64_t sum = 0;
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];
} else if (typed_array_arg->IsUint32Array()) {
sum += static_cast<uint32_t*>(data)[i];
@ -893,6 +901,18 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
signature, 1, ConstructorBehavior::kThrow,
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(
FastCApiObject::AddAllTypedArrayFastCallback<int32_t>
V8_IF_USE_SIMULATOR(

View File

@ -129,6 +129,15 @@ for (let i = 0; i < 100; i++) {
// `add_all_<TYPE>_typed_array` have the following signature:
// 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 int32_test() {
let typed_array = new Int32Array([-42, 1, 2, 3]);
@ -262,6 +271,25 @@ for (let i = 0; i < 100; i++) {
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.
(function () {
function invalid_test(arg) {