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 @@

4850

namespace node {

49515052

using v8::ArrayBuffer;

53+

using v8::CFunction;

5154

using v8::Context;

5255

using v8::Function;

5356

using 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+16611673

static void CRC32(const FunctionCallbackInfo<Value>& args) {

16621674

CHECK(args[0]->IsArrayBufferView() || args[0]->IsString());

16631675

CHECK(args[1]->IsUint32());

16641676

uint32_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+16761692

void 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(),

16901706

FIXED_ONE_BYTE_STRING(env->isolate(), "ZLIB_VERSION"),

16911707

FIXED_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