zlib: implement fast path for crc32 · nodejs/node@9782ca2
@@ -30,6 +30,8 @@
3030#include "threadpoolwork-inl.h"
3131#include "util-inl.h"
323233+#include "node_debug.h"
34+#include "v8-fast-api-calls.h"
3335#include "v8.h"
34363537#include "brotli/decode.h"
@@ -48,6 +50,7 @@
4850namespace node {
49515052using v8::ArrayBuffer;
53+using v8::CFunction;
5154using v8::Context;
5255using v8::Function;
5356using v8::FunctionCallbackInfo;
@@ -1657,22 +1660,35 @@ T CallOnSequence(v8::Isolate* isolate, Local<Value> value, F callback) {
16571660 }
16581661}
165916621660-// TODO(joyeecheung): use fast API
1663+static inline uint32_t CRC32Impl(Isolate* isolate,
1664+ Local<Value> data,
1665+uint32_t value) {
1666+return CallOnSequence<uint32_t>(
1667+ isolate, data, [&](const char* ptr, size_t size) -> uint32_t {
1668+return static_cast<uint32_t>(
1669+crc32(value, reinterpret_cast<const Bytef*>(ptr), size));
1670+ });
1671+}
1672+16611673static void CRC32(const FunctionCallbackInfo<Value>& args) {
16621674CHECK(args[0]->IsArrayBufferView() || args[0]->IsString());
16631675CHECK(args[1]->IsUint32());
16641676uint32_t value = args[1].As<v8::Uint32>()->Value();
1677+ args.GetReturnValue().Set(CRC32Impl(args.GetIsolate(), args[0], value));
1678+}
166516791666- uint32_t result = CallOnSequence<uint32_t>(
1667-args.GetIsolate(),
1668-args[0],
1669-[&](const char* data, size_t size) -> uint32_t {
1670-return crc32(value, reinterpret_cast<const Bytef*>(data), size);
1671- });
1672-1673-args.GetReturnValue().Set(result);
1680+static uint32_t FastCRC32(v8::Local<v8::Value> receiver,
1681+ v8::Local<v8::Value> data,
1682+ uint32_t value,
1683+ // NOLINTNEXTLINE(runtime/references)
1684+ v8::FastApiCallbackOptions& options) {
1685+TRACK_V8_FAST_API_CALL("zlib.crc32");
1686+ v8::HandleScope handle_scope(options.isolate);
1687+return CRC32Impl(options.isolate, data, value);
16741688}
167516891690+static CFunction fast_crc32_(CFunction::Make(FastCRC32));
1691+16761692void Initialize(Local<Object> target,
16771693 Local<Value> unused,
16781694 Local<Context> context,
@@ -1685,7 +1701,7 @@ void Initialize(Local<Object> target,
16851701 MakeClass<ZstdCompressStream>::Make(env, target, "ZstdCompress");
16861702 MakeClass<ZstdDecompressStream>::Make(env, target, "ZstdDecompress");
168717031688-SetMethod(context, target, "crc32", CRC32);
1704+SetFastMethodNoSideEffect(context, target, "crc32", CRC32, &fast_crc32_);
16891705 target->Set(env->context(),
16901706FIXED_ONE_BYTE_STRING(env->isolate(), "ZLIB_VERSION"),
16911707FIXED_ONE_BYTE_STRING(env->isolate(), ZLIB_VERSION)).Check();
@@ -1698,6 +1714,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
16981714 MakeClass<ZstdCompressStream>::Make(registry);
16991715 MakeClass<ZstdDecompressStream>::Make(registry);
17001716 registry->Register(CRC32);
1717+ registry->Register(fast_crc32_);
17011718}
1702171917031720} // anonymous namespace