diff --git a/js/public/MemoryCallbacks.h b/js/public/MemoryCallbacks.h new file mode 100644 index 000000000000..dad63915d45a --- /dev/null +++ b/js/public/MemoryCallbacks.h @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef js_MemoryCallbacks_h +#define js_MemoryCallbacks_h + +#include "jstypes.h" + +struct JS_PUBLIC_API JSContext; + +namespace JS { + +/** + * If a large allocation fails when calling pod_{calloc,realloc}CanGC, the JS + * engine may call the large-allocation-failure callback, if set, to allow the + * embedding to flush caches, possibly perform shrinking GCs, etc. to make some + * room. The allocation will then be retried (and may still fail.) This callback + * can be called on any thread and must be set at most once in a process. + */ + +using LargeAllocationFailureCallback = void (*)(); + +extern JS_PUBLIC_API void SetProcessLargeAllocationFailureCallback( + LargeAllocationFailureCallback afc); + +/** + * Unlike the error reporter, which is only called if the exception for an OOM + * bubbles up and is not caught, the OutOfMemoryCallback is called immediately + * at the OOM site to allow the embedding to capture the current state of heap + * allocation before anything is freed. If the large-allocation-failure callback + * is called at all (not all allocation sites call the large-allocation-failure + * callback on failure), it is called before the out-of-memory callback; the + * out-of-memory callback is only called if the allocation still fails after the + * large-allocation-failure callback has returned. + */ + +using OutOfMemoryCallback = void (*)(JSContext*, void*); + +extern JS_PUBLIC_API void SetOutOfMemoryCallback(JSContext* cx, + OutOfMemoryCallback cb, + void* data); + +} // namespace JS + +#endif // js_MemoryCallbacks_h diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 3818065fb973..4fb7a51f1151 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -51,6 +51,7 @@ #include "js/Initialization.h" #include "js/JSON.h" #include "js/LocaleSensitive.h" +#include "js/MemoryCallbacks.h" #include "js/MemoryFunctions.h" #include "js/OffThreadScriptCompilation.h" // js::UseOffThreadParseGlobal #include "js/PropertySpec.h" diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 2af17a8c0271..e4de5fc7a6a3 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -41,6 +41,7 @@ #include "js/HashTable.h" #include "js/Id.h" #include "js/MapAndSet.h" +#include "js/MemoryCallbacks.h" #include "js/MemoryFunctions.h" #include "js/OffThreadScriptCompilation.h" #include "js/Principals.h" @@ -1102,36 +1103,6 @@ class MOZ_RAII AutoHideScriptedCaller { */ [[nodiscard]] extern JS_PUBLIC_API bool DisableWasmHugeMemory(); -/** - * If a large allocation fails when calling pod_{calloc,realloc}CanGC, the JS - * engine may call the large-allocation-failure callback, if set, to allow the - * embedding to flush caches, possibly perform shrinking GCs, etc. to make some - * room. The allocation will then be retried (and may still fail.) This callback - * can be called on any thread and must be set at most once in a process. - */ - -using LargeAllocationFailureCallback = void (*)(); - -extern JS_PUBLIC_API void SetProcessLargeAllocationFailureCallback( - LargeAllocationFailureCallback afc); - -/** - * Unlike the error reporter, which is only called if the exception for an OOM - * bubbles up and is not caught, the OutOfMemoryCallback is called immediately - * at the OOM site to allow the embedding to capture the current state of heap - * allocation before anything is freed. If the large-allocation-failure callback - * is called at all (not all allocation sites call the large-allocation-failure - * callback on failure), it is called before the out-of-memory callback; the - * out-of-memory callback is only called if the allocation still fails after the - * large-allocation-failure callback has returned. - */ - -using OutOfMemoryCallback = void (*)(JSContext*, void*); - -extern JS_PUBLIC_API void SetOutOfMemoryCallback(JSContext* cx, - OutOfMemoryCallback cb, - void* data); - /** * When the JSRuntime is about to block in an Atomics.wait() JS call or in a * `wait` instruction in WebAssembly, it can notify the host by means of a call diff --git a/js/src/moz.build b/js/src/moz.build index c2d3a1a5ddfc..67f43af01087 100755 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -166,6 +166,7 @@ EXPORTS.js += [ "../public/JSON.h", "../public/LocaleSensitive.h", "../public/MapAndSet.h", + "../public/MemoryCallbacks.h", "../public/MemoryFunctions.h", "../public/MemoryMetrics.h", "../public/Modules.h", diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index ccd1b517ad8d..4bb66ee58d9f 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -131,6 +131,7 @@ #include "js/GCVector.h" #include "js/Initialization.h" #include "js/JSON.h" +#include "js/MemoryCallbacks.h" #include "js/MemoryFunctions.h" #include "js/Modules.h" // JS::GetModulePrivate, JS::SetModule{DynamicImport,Metadata,Resolve}Hook, JS::SetModulePrivate #include "js/Object.h" // JS::GetClass, JS::GetCompartment, JS::GetReservedSlot, JS::SetReservedSlot diff --git a/js/src/vm/JSContext.cpp b/js/src/vm/JSContext.cpp index f52e38f3d05d..4903d3fbf113 100644 --- a/js/src/vm/JSContext.cpp +++ b/js/src/vm/JSContext.cpp @@ -45,6 +45,7 @@ #include "js/ErrorInterceptor.h" // JSErrorInterceptor #include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_* #include "js/friend/StackLimits.h" // js::ReportOverRecursed +#include "js/MemoryCallbacks.h" #include "js/Printf.h" #include "js/PropertyAndElement.h" // JS_GetProperty #include "js/Stack.h" diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index 91752b418a84..c0328d853065 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -44,6 +44,7 @@ #include "js/GCVector.h" #include "js/HashTable.h" #include "js/Initialization.h" +#include "js/MemoryCallbacks.h" #include "js/Modules.h" // JS::Module{DynamicImport,Metadata,Resolve}Hook #ifdef DEBUG # include "js/Proxy.h" // For AutoEnterPolicy @@ -1013,7 +1014,7 @@ struct JSRuntime { autoWritableJitCodeActive_ = b; } - /* See comment for JS::SetOutOfMemoryCallback in jsapi.h. */ + /* See comment for JS::SetOutOfMemoryCallback in js/MemoryCallbacks.h. */ js::MainThreadData oomCallback; js::MainThreadData oomCallbackData;