[fastcall] Add 8-byte element types support for TypedArrays
This CL adds back the 8-byte element types and extends the fast API by hiding the unaligned memory reads performed for them. Bug: chromium:1052746 Change-Id: Ide49ce6bd2c77b9d2d544ca2df47b5f95c93eaa9 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3056988 Commit-Queue: Maya Lekova <mslekova@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Cr-Commit-Position: refs/heads/master@{#76207}
This commit is contained in:
parent
12d112163b
commit
22f326b8af
@ -299,10 +299,42 @@ class CTypeInfo {
|
||||
Flags flags_;
|
||||
};
|
||||
|
||||
struct FastApiTypedArrayBase {
|
||||
public:
|
||||
// Returns the length in number of elements.
|
||||
size_t V8_EXPORT length() const { return length_; }
|
||||
// Checks whether the given index is within the bounds of the collection.
|
||||
void V8_EXPORT ValidateIndex(size_t index) const;
|
||||
|
||||
protected:
|
||||
size_t length_ = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct FastApiTypedArray {
|
||||
T* data; // should include the typed array offset applied
|
||||
size_t length; // length in number of elements
|
||||
struct FastApiTypedArray : public FastApiTypedArrayBase {
|
||||
public:
|
||||
V8_INLINE T get(size_t index) const {
|
||||
#ifdef DEBUG
|
||||
ValidateIndex(index);
|
||||
#endif // DEBUG
|
||||
static_assert(offsetof(FastApiTypedArray<T>, length_) <
|
||||
offsetof(FastApiTypedArray<T>, data_),
|
||||
"length_ should be "
|
||||
"stored in memory before data_, initializing the "
|
||||
"FastApiTypedArray struct will fail.");
|
||||
|
||||
T tmp;
|
||||
memcpy(&tmp, reinterpret_cast<T*>(data_) + index, sizeof(T));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
private:
|
||||
// This pointer should include the typed array offset applied.
|
||||
// It's not guaranteed that it's aligned to sizeof(T), it's only
|
||||
// guaranteed that it's 4-byte aligned, so for 8-byte types we need to
|
||||
// provide a special implementation for reading from it, which hides
|
||||
// the possibly unaligned read in the `get` method.
|
||||
void* data_;
|
||||
};
|
||||
|
||||
// Any TypedArray. It uses kTypedArrayBit with base type void
|
||||
|
@ -10045,6 +10045,10 @@ const CTypeInfo& CFunctionInfo::ArgumentInfo(unsigned int index) const {
|
||||
return arg_info_[index];
|
||||
}
|
||||
|
||||
void FastApiTypedArrayBase::ValidateIndex(size_t index) const {
|
||||
DCHECK_LT(index, length_);
|
||||
}
|
||||
|
||||
RegisterState::RegisterState()
|
||||
: pc(nullptr), sp(nullptr), fp(nullptr), lr(nullptr) {}
|
||||
RegisterState::~RegisterState() = default;
|
||||
@ -10332,18 +10336,6 @@ bool ConvertDouble(double d) {
|
||||
|
||||
} // namespace internal
|
||||
|
||||
bool CopyAndConvertArrayToCppBufferInt32(Local<Array> src, int32_t* dst,
|
||||
uint32_t max_length) {
|
||||
return CopyAndConvertArrayToCppBuffer<&v8::kTypeInfoInt32, int32_t>(
|
||||
src, dst, max_length);
|
||||
}
|
||||
|
||||
bool CopyAndConvertArrayToCppBufferFloat64(Local<Array> src, double* dst,
|
||||
uint32_t max_length) {
|
||||
return CopyAndConvertArrayToCppBuffer<&v8::kTypeInfoFloat64, double>(
|
||||
src, dst, max_length);
|
||||
}
|
||||
|
||||
} // namespace v8
|
||||
|
||||
#undef TRACE_BS
|
||||
|
@ -5083,10 +5083,10 @@ Node* EffectControlLinearizer::AdaptFastCallTypedArrayArgument(
|
||||
|
||||
__ Store(StoreRepresentation(MachineType::PointerRepresentation(),
|
||||
kNoWriteBarrier),
|
||||
stack_slot, 0, data_ptr);
|
||||
stack_slot, 0, length_in_bytes);
|
||||
__ Store(StoreRepresentation(MachineType::PointerRepresentation(),
|
||||
kNoWriteBarrier),
|
||||
stack_slot, sizeof(uintptr_t), length_in_bytes);
|
||||
stack_slot, sizeof(size_t), data_ptr);
|
||||
static_assert(sizeof(uintptr_t) == sizeof(size_t),
|
||||
"The buffer length can't "
|
||||
"fit the PointerRepresentation used to store it.");
|
||||
|
@ -3549,23 +3549,6 @@ bool Has64BitIntegerParamsInSignature(const CFunctionInfo* c_signature) {
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
bool Has64BitTypedArraysInSignature(const CFunctionInfo* c_signature) {
|
||||
for (unsigned int i = 0; i < c_signature->ArgumentCount(); ++i) {
|
||||
if (c_signature->ArgumentInfo(i).GetSequenceType() !=
|
||||
CTypeInfo::SequenceType::kIsTypedArray) {
|
||||
continue;
|
||||
}
|
||||
if (c_signature->ArgumentInfo(i).GetType() == CTypeInfo::Type::kInt64 ||
|
||||
c_signature->ArgumentInfo(i).GetType() == CTypeInfo::Type::kUint64 ||
|
||||
c_signature->ArgumentInfo(i).GetType() == CTypeInfo::Type::kFloat64) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// Given a FunctionTemplateInfo, checks whether the fast API call can be
|
||||
// optimized, applying the initial step of the overload resolution algorithm:
|
||||
// Given an overload set function_template_info.c_signatures, and a list of
|
||||
@ -3620,10 +3603,6 @@ FastApiCallFunctionVector CanOptimizeFastCall(
|
||||
optimize_to_fast_call =
|
||||
optimize_to_fast_call && !Has64BitIntegerParamsInSignature(c_signature);
|
||||
#endif
|
||||
// TODO(mslekova): Add back support for 64-bit TA params when the API is
|
||||
// changed to disallow raw access to unaligned data.
|
||||
optimize_to_fast_call =
|
||||
optimize_to_fast_call && !Has64BitTypedArraysInSignature(c_signature);
|
||||
|
||||
if (optimize_to_fast_call) {
|
||||
result.push_back({functions[i], c_signature});
|
||||
|
@ -206,14 +206,9 @@ class FastCApiObject {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!typed_array_arg.data) {
|
||||
options.fallback = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
T sum = 0;
|
||||
for (unsigned i = 0; i < typed_array_arg.length; ++i) {
|
||||
sum += typed_array_arg.data[i];
|
||||
for (unsigned i = 0; i < typed_array_arg.length(); ++i) {
|
||||
sum += typed_array_arg.get(i);
|
||||
}
|
||||
return static_cast<Type>(sum);
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ const max_safe_as_bigint = BigInt(Number.MAX_SAFE_INTEGER);
|
||||
typed_array);
|
||||
}
|
||||
const expected = Number(BigInt.asIntN(64, -42n + 1n + max_safe_as_bigint));
|
||||
ExpectSlowCall(int64_test, expected);
|
||||
ExpectFastCall(int64_test, expected);
|
||||
})();
|
||||
|
||||
(function () {
|
||||
@ -51,5 +51,5 @@ const max_safe_as_bigint = BigInt(Number.MAX_SAFE_INTEGER);
|
||||
typed_array);
|
||||
}
|
||||
const expected = Number(BigInt.asUintN(64, max_safe_as_bigint + 1n + 2n));
|
||||
ExpectSlowCall(uint64_test, expected);
|
||||
ExpectFastCall(uint64_test, expected);
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user