mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
Add runtime detection of V8 memory cage #3384
When using the V8 memory cage, Buffers cannot be wrapped and then later freed via a callback. When the cage is detected via a throw, instead fall back to copying Buffer contents to V8 memory. This approach will be used by Electron 21+ and you should expect reduced performance and increased memory consumption/fragmentation.
This commit is contained in:
parent
a7fa7014ef
commit
584807b4f5
@ -9,6 +9,9 @@ Requires libvips v8.13.3
|
|||||||
* Add experimental support for JPEG-XL images. Requires libvips compiled with libjxl.
|
* Add experimental support for JPEG-XL images. Requires libvips compiled with libjxl.
|
||||||
[#2731](https://github.com/lovell/sharp/issues/2731)
|
[#2731](https://github.com/lovell/sharp/issues/2731)
|
||||||
|
|
||||||
|
* Add runtime detection of V8 memory cage, ensures compatibility with Electron 21 onwards.
|
||||||
|
[#3384](https://github.com/lovell/sharp/issues/3384)
|
||||||
|
|
||||||
* Expose `interFrameMaxError` and `interPaletteMaxError` GIF optimisation properties.
|
* Expose `interFrameMaxError` and `interPaletteMaxError` GIF optimisation properties.
|
||||||
[#3401](https://github.com/lovell/sharp/issues/3401)
|
[#3401](https://github.com/lovell/sharp/issues/3401)
|
||||||
|
|
||||||
|
@ -76,6 +76,14 @@ namespace sharp {
|
|||||||
}
|
}
|
||||||
return vector;
|
return vector;
|
||||||
}
|
}
|
||||||
|
Napi::Buffer<char> NewOrCopyBuffer(Napi::Env env, char* data, size_t len) {
|
||||||
|
try {
|
||||||
|
return Napi::Buffer<char>::New(env, data, len, FreeCallback);
|
||||||
|
} catch (Napi::Error const &err) {}
|
||||||
|
Napi::Buffer<char> buf = Napi::Buffer<char>::Copy(env, data, len);
|
||||||
|
FreeCallback(nullptr, data);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
// Create an InputDescriptor instance from a Napi::Object describing an input image
|
// Create an InputDescriptor instance from a Napi::Object describing an input image
|
||||||
InputDescriptor* CreateInputDescriptor(Napi::Object input) {
|
InputDescriptor* CreateInputDescriptor(Napi::Object input) {
|
||||||
|
@ -133,6 +133,7 @@ namespace sharp {
|
|||||||
return static_cast<T>(
|
return static_cast<T>(
|
||||||
vips_enum_from_nick(nullptr, type, AttrAsStr(obj, attr).data()));
|
vips_enum_from_nick(nullptr, type, AttrAsStr(obj, attr).data()));
|
||||||
}
|
}
|
||||||
|
Napi::Buffer<char> NewOrCopyBuffer(Napi::Env env, char* data, size_t len);
|
||||||
|
|
||||||
// Create an InputDescriptor instance from a Napi::Object describing an input image
|
// Create an InputDescriptor instance from a Napi::Object describing an input image
|
||||||
InputDescriptor* CreateInputDescriptor(Napi::Object input);
|
InputDescriptor* CreateInputDescriptor(Napi::Object input);
|
||||||
|
@ -235,20 +235,20 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|||||||
info.Set("orientation", baton->orientation);
|
info.Set("orientation", baton->orientation);
|
||||||
}
|
}
|
||||||
if (baton->exifLength > 0) {
|
if (baton->exifLength > 0) {
|
||||||
info.Set("exif", Napi::Buffer<char>::New(env, baton->exif, baton->exifLength, sharp::FreeCallback));
|
info.Set("exif", sharp::NewOrCopyBuffer(env, baton->exif, baton->exifLength));
|
||||||
}
|
}
|
||||||
if (baton->iccLength > 0) {
|
if (baton->iccLength > 0) {
|
||||||
info.Set("icc", Napi::Buffer<char>::New(env, baton->icc, baton->iccLength, sharp::FreeCallback));
|
info.Set("icc", sharp::NewOrCopyBuffer(env, baton->icc, baton->iccLength));
|
||||||
}
|
}
|
||||||
if (baton->iptcLength > 0) {
|
if (baton->iptcLength > 0) {
|
||||||
info.Set("iptc", Napi::Buffer<char>::New(env, baton->iptc, baton->iptcLength, sharp::FreeCallback));
|
info.Set("iptc", sharp::NewOrCopyBuffer(env, baton->iptc, baton->iptcLength));
|
||||||
}
|
}
|
||||||
if (baton->xmpLength > 0) {
|
if (baton->xmpLength > 0) {
|
||||||
info.Set("xmp", Napi::Buffer<char>::New(env, baton->xmp, baton->xmpLength, sharp::FreeCallback));
|
info.Set("xmp", sharp::NewOrCopyBuffer(env, baton->xmp, baton->xmpLength));
|
||||||
}
|
}
|
||||||
if (baton->tifftagPhotoshopLength > 0) {
|
if (baton->tifftagPhotoshopLength > 0) {
|
||||||
info.Set("tifftagPhotoshop",
|
info.Set("tifftagPhotoshop",
|
||||||
Napi::Buffer<char>::New(env, baton->tifftagPhotoshop, baton->tifftagPhotoshopLength, sharp::FreeCallback));
|
sharp::NewOrCopyBuffer(env, baton->tifftagPhotoshop, baton->tifftagPhotoshopLength));
|
||||||
}
|
}
|
||||||
Callback().MakeCallback(Receiver().Value(), { env.Null(), info });
|
Callback().MakeCallback(Receiver().Value(), { env.Null(), info });
|
||||||
} else {
|
} else {
|
||||||
|
@ -1206,8 +1206,8 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
// Add buffer size to info
|
// Add buffer size to info
|
||||||
info.Set("size", static_cast<uint32_t>(baton->bufferOutLength));
|
info.Set("size", static_cast<uint32_t>(baton->bufferOutLength));
|
||||||
// Pass ownership of output data to Buffer instance
|
// Pass ownership of output data to Buffer instance
|
||||||
Napi::Buffer<char> data = Napi::Buffer<char>::New(env, static_cast<char*>(baton->bufferOut),
|
Napi::Buffer<char> data = sharp::NewOrCopyBuffer(env, static_cast<char*>(baton->bufferOut),
|
||||||
baton->bufferOutLength, sharp::FreeCallback);
|
baton->bufferOutLength);
|
||||||
Callback().MakeCallback(Receiver().Value(), { env.Null(), data, info });
|
Callback().MakeCallback(Receiver().Value(), { env.Null(), data, info });
|
||||||
} else {
|
} else {
|
||||||
// Add file size to info
|
// Add file size to info
|
||||||
|
Loading…
x
Reference in New Issue
Block a user