From 3d8acd4688bc1f923488ee8f6d159a22a8ab735e Mon Sep 17 00:00:00 2001 From: Santiago Roche <69868136+sroches@users.noreply.github.com> Date: Thu, 11 Jul 2024 22:15:56 -0400 Subject: [PATCH] SERVER-91111: Enable spider-monkey-dbg build. (#22906) GitOrigin-RevId: 8d4990e21d30aa8e36bf4d60e9acde80a4c2c12c --- .eslintrc.yml | 1 + .../variants/rhel/test_dev.yml | 3 + .../test_dev_master_and_lts_branches_only.yml | 2 + .../rhel/test_dev_master_branch_only.yml | 3 + .../variants/sanitizer/test_dev.yml | 85 +++++++++++++++++++ .../sanitizer/test_dev_master_branch_only.yml | 3 + evergreen/resmoke_tests_execute.sh | 2 +- jstests/aggregation/query_limits_test.js | 2 +- src/mongo/scripting/mozjs/base.h | 1 + src/mongo/scripting/mozjs/bindata.h | 3 +- src/mongo/scripting/mozjs/bson.h | 3 +- src/mongo/scripting/mozjs/cursor.h | 3 +- src/mongo/scripting/mozjs/cursor_handle.h | 3 +- src/mongo/scripting/mozjs/dbref.h | 3 +- src/mongo/scripting/mozjs/implscope.cpp | 18 ++-- src/mongo/scripting/mozjs/implscope.h | 7 +- src/mongo/scripting/mozjs/jsthread.h | 3 +- src/mongo/scripting/mozjs/module_loader.cpp | 4 +- src/mongo/scripting/mozjs/mongo.h | 3 +- src/mongo/scripting/mozjs/nativefunction.h | 3 +- src/mongo/scripting/mozjs/numberdecimal.h | 4 +- src/mongo/scripting/mozjs/numberint.h | 3 +- src/mongo/scripting/mozjs/numberlong.h | 3 +- src/mongo/scripting/mozjs/oid.h | 4 +- src/mongo/scripting/mozjs/session.h | 3 +- src/mongo/scripting/mozjs/status.h | 3 +- src/mongo/shell/utils.js | 15 ++++ src/third_party/SConscript | 1 + src/third_party/mozjs/SConscript | 3 + .../mozjs/extract/js/src/util/Utility.cpp | 4 + .../mozjs/extract/js/src/vm/JSObject.cpp | 3 + src/third_party/mozjs/get-sources.sh | 2 +- 32 files changed, 174 insertions(+), 29 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index 8ae3e533366..6edbd4129fd 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -108,6 +108,7 @@ globals: _isLeakSanitizerActive: true _isThreadSanitizerActive: true _isUndefinedBehaviorSanitizerActive: true + _isSpiderMonkeyDebugEnabled: true _optimizationsEnabled: true allocatePort: true allocatePorts: true diff --git a/etc/evergreen_yml_components/variants/rhel/test_dev.yml b/etc/evergreen_yml_components/variants/rhel/test_dev.yml index 5798e1816b2..c4d74969f05 100644 --- a/etc/evergreen_yml_components/variants/rhel/test_dev.yml +++ b/etc/evergreen_yml_components/variants/rhel/test_dev.yml @@ -36,6 +36,7 @@ variables: # - etc/evergreen_yml_components/variants/rhel/test_dev_master_and_lts_branches_only.yml # - etc/evergreen_yml_components/variants/rhel/test_dev.yml # - etc/evergreen_yml_components/variants/sanitizer/test_dev_master_branch_only.yml + # - etc/evergreen_yml_components/variants/sanitizer/test_dev.yml # ANY MODIFICATIONS HERE SHOULD ALSO BE MADE IN THOSE FILES - &linux_x86_dynamic_compile_variant_dependency depends_on: @@ -54,6 +55,7 @@ variables: # - etc/evergreen_yml_components/variants/rhel/test_dev_master_and_lts_branches_only.yml # - etc/evergreen_yml_components/variants/rhel/test_dev.yml # - etc/evergreen_yml_components/variants/sanitizer/test_dev_master_branch_only.yml + # - etc/evergreen_yml_components/variants/sanitizer/test_dev.yml # ANY MODIFICATIONS HERE SHOULD ALSO BE MADE IN THOSE FILES - &linux_x86_generic_expansions multiversion_platform: rhel80 @@ -68,6 +70,7 @@ variables: # - etc/evergreen_yml_components/variants/rhel/test_dev_master_branch_only.yml # - etc/evergreen_yml_components/variants/rhel/test_dev.yml # - etc/evergreen_yml_components/variants/sanitizer/test_dev_master_branch_only.yml + # - etc/evergreen_yml_components/variants/sanitizer/test_dev.yml # ANY MODIFICATIONS HERE SHOULD ALSO BE MADE IN THOSE FILES - &enterprise-rhel-88-64-bit-dynamic-expansions <<: *linux_x86_generic_expansions diff --git a/etc/evergreen_yml_components/variants/rhel/test_dev_master_and_lts_branches_only.yml b/etc/evergreen_yml_components/variants/rhel/test_dev_master_and_lts_branches_only.yml index 16ceff1e620..aab402d3af7 100644 --- a/etc/evergreen_yml_components/variants/rhel/test_dev_master_and_lts_branches_only.yml +++ b/etc/evergreen_yml_components/variants/rhel/test_dev_master_and_lts_branches_only.yml @@ -10,6 +10,7 @@ variables: # - etc/evergreen_yml_components/variants/rhel/test_dev_master_and_lts_branches_only.yml # - etc/evergreen_yml_components/variants/rhel/test_dev.yml # - etc/evergreen_yml_components/variants/sanitizer/test_dev_master_branch_only.yml + # - etc/evergreen_yml_components/variants/sanitizer/test_dev.yml # ANY MODIFICATIONS HERE SHOULD ALSO BE MADE IN THOSE FILES - &linux_x86_dynamic_compile_variant_dependency depends_on: @@ -28,6 +29,7 @@ variables: # - etc/evergreen_yml_components/variants/rhel/test_dev_master_and_lts_branches_only.yml # - etc/evergreen_yml_components/variants/rhel/test_dev.yml # - etc/evergreen_yml_components/variants/sanitizer/test_dev_master_branch_only.yml + # - etc/evergreen_yml_components/variants/sanitizer/test_dev.yml # ANY MODIFICATIONS HERE SHOULD ALSO BE MADE IN THOSE FILES - &linux_x86_generic_expansions multiversion_platform: rhel80 diff --git a/etc/evergreen_yml_components/variants/rhel/test_dev_master_branch_only.yml b/etc/evergreen_yml_components/variants/rhel/test_dev_master_branch_only.yml index cb0483f1d25..03c6bdf9956 100644 --- a/etc/evergreen_yml_components/variants/rhel/test_dev_master_branch_only.yml +++ b/etc/evergreen_yml_components/variants/rhel/test_dev_master_branch_only.yml @@ -62,6 +62,7 @@ variables: # - etc/evergreen_yml_components/variants/rhel/test_dev_master_and_lts_branches_only.yml # - etc/evergreen_yml_components/variants/rhel/test_dev.yml # - etc/evergreen_yml_components/variants/sanitizer/test_dev_master_branch_only.yml + # - etc/evergreen_yml_components/variants/sanitizer/test_dev.yml # ANY MODIFICATIONS HERE SHOULD ALSO BE MADE IN THOSE FILES - &linux_x86_dynamic_compile_variant_dependency depends_on: @@ -80,6 +81,7 @@ variables: # - etc/evergreen_yml_components/variants/rhel/test_dev_master_and_lts_branches_only.yml # - etc/evergreen_yml_components/variants/rhel/test_dev.yml # - etc/evergreen_yml_components/variants/sanitizer/test_dev_master_branch_only.yml + # - etc/evergreen_yml_components/variants/sanitizer/test_dev.yml # ANY MODIFICATIONS HERE SHOULD ALSO BE MADE IN THOSE FILES - &linux_x86_generic_expansions multiversion_platform: rhel80 @@ -94,6 +96,7 @@ variables: # - etc/evergreen_yml_components/variants/rhel/test_dev_master_branch_only.yml # - etc/evergreen_yml_components/variants/rhel/test_dev.yml # - etc/evergreen_yml_components/variants/sanitizer/test_dev_master_branch_only.yml + # - etc/evergreen_yml_components/variants/sanitizer/test_dev.yml # ANY MODIFICATIONS HERE SHOULD ALSO BE MADE IN THOSE FILES - &enterprise-rhel-88-64-bit-dynamic-expansions <<: *linux_x86_generic_expansions diff --git a/etc/evergreen_yml_components/variants/sanitizer/test_dev.yml b/etc/evergreen_yml_components/variants/sanitizer/test_dev.yml index 521b0cfc107..db6dd492e67 100644 --- a/etc/evergreen_yml_components/variants/sanitizer/test_dev.yml +++ b/etc/evergreen_yml_components/variants/sanitizer/test_dev.yml @@ -31,6 +31,60 @@ variables: scons_cache_mode: all has_packages: false + # THIS HAS COPIES IN: + # - etc/evergreen_yml_components/variants/rhel/test_dev_master_branch_only.yml + # - etc/evergreen_yml_components/variants/rhel/test_dev_master_and_lts_branches_only.yml + # - etc/evergreen_yml_components/variants/rhel/test_dev.yml + # - etc/evergreen_yml_components/variants/sanitizer/test_dev_master_branch_only.yml + # - etc/evergreen_yml_components/variants/sanitizer/test_dev.yml + # ANY MODIFICATIONS HERE SHOULD ALSO BE MADE IN THOSE FILES + - &linux_x86_dynamic_compile_variant_dependency + depends_on: + - name: archive_dist_test_debug + variant: &linux_x86_dynamic_compile_variant_name linux-x86-dynamic-compile + - name: version_gen + variant: generate-tasks-for-version + # This is added because of EVG-18211. + # Without this we are adding extra dependencies on evergreen and it is causing strain + omit_generated_tasks: true + # - name: generate_buildid_to_debug_symbols_mapping + # variant: linux-x86-dynamic-compile + + # THIS HAS COPIES IN: + # - etc/evergreen_yml_components/variants/rhel/test_dev_master_branch_only.yml + # - etc/evergreen_yml_components/variants/rhel/test_dev_master_and_lts_branches_only.yml + # - etc/evergreen_yml_components/variants/rhel/test_dev.yml + # - etc/evergreen_yml_components/variants/sanitizer/test_dev_master_branch_only.yml + # - etc/evergreen_yml_components/variants/sanitizer/test_dev.yml + # ANY MODIFICATIONS HERE SHOULD ALSO BE MADE IN THOSE FILES + - &linux_x86_generic_expansions + multiversion_platform: rhel80 + multiversion_edition: enterprise + repo_edition: enterprise + large_distro_name: rhel80-medium + core_analyzer_distro_name: rhel80-xlarge + num_scons_link_jobs_available: 0.99 + compile_variant: *linux_x86_dynamic_compile_variant_name + + # THIS HAS COPIES IN: + # - etc/evergreen_yml_components/variants/rhel/test_dev_master_branch_only.yml + # - etc/evergreen_yml_components/variants/rhel/test_dev.yml + # - etc/evergreen_yml_components/variants/sanitizer/test_dev_master_branch_only.yml + # - etc/evergreen_yml_components/variants/sanitizer/test_dev.yml + # ANY MODIFICATIONS HERE SHOULD ALSO BE MADE IN THOSE FILES + - &enterprise-rhel-80-64-bit-dynamic-expansions + <<: *linux_x86_generic_expansions + scons_cache_scope: shared + scons_cache_mode: all + has_packages: false + jstestfuzz_num_generated_files: 40 + jstestfuzz_concurrent_num_files: 10 + target_resmoke_time: 10 + max_sub_suites: 5 + idle_timeout_factor: 1.5 + exec_timeout_factor: 1.5 + large_distro_name: rhel80-medium + # THIS HAS COPIES IN # - etc/evergreen_yml_components/variants/sanitizer/test_dev.yml # - etc/evergreen_yml_components/variants/wiredtiger/test_dev_master_branch_only.yml @@ -526,3 +580,34 @@ buildvariants: - name: .serverless - name: unittest_shell_hang_analyzer_gen - name: .watchdog + + - name: &enterprise-rhel-80-64-bit-dynamic-spider-monkey-dbg enterprise-rhel-80-64-bit-dynamic-spider-monkey-dbg + display_name: "~ Shared Library Enterprise RHEL 8.0 SpiderMonkey Debug" + tags: [] + cron: "0 */4 * * *" # From the ${project_required_suggested_cron} parameter + run_on: + - rhel80-small + expansions: + <<: *enterprise-rhel-80-64-bit-dynamic-expansions + # JS_GC_ZEAL modes can be found at https://github.com/mongodb/mongo/blob/r8.0.0-rc9/src/third_party/mozjs/extract/js/src/gc/GC.cpp#L563-L612. + # These modes correspond to collecting the nursery (GenerationalGC) every 50 allocations. + mozjs_options: JS_GC_ZEAL='7,50' + compile_flags: >- + --ssl + MONGO_DISTMOD=rhel80 + -j$(grep -c ^processor /proc/cpuinfo) + --variables-files=etc/scons/mongodbtoolchain_stable_gcc.vars + --link-model=dynamic + --use-diagnostic-latches=on + --spider-monkey-dbg=on + exec_timeout_secs: 32400 # 9 hour timeout + timeout_secs: 18000 # 5 hour idle timeout + depends_on: [] + tasks: + - name: compile_test_parallel_core_stream_TG + distros: + - rhel80-xlarge + - name: aggregation + - name: aggregation_mongos_passthrough + - name: concurrency_simultaneous_gen + - name: jsCore diff --git a/etc/evergreen_yml_components/variants/sanitizer/test_dev_master_branch_only.yml b/etc/evergreen_yml_components/variants/sanitizer/test_dev_master_branch_only.yml index ce216665797..6d5cbea6fa7 100644 --- a/etc/evergreen_yml_components/variants/sanitizer/test_dev_master_branch_only.yml +++ b/etc/evergreen_yml_components/variants/sanitizer/test_dev_master_branch_only.yml @@ -21,6 +21,7 @@ variables: # - etc/evergreen_yml_components/variants/rhel/test_dev_master_and_lts_branches_only.yml # - etc/evergreen_yml_components/variants/rhel/test_dev.yml # - etc/evergreen_yml_components/variants/sanitizer/test_dev_master_branch_only.yml + # - etc/evergreen_yml_components/variants/sanitizer/test_dev.yml # ANY MODIFICATIONS HERE SHOULD ALSO BE MADE IN THOSE FILES - &linux_x86_dynamic_compile_variant_dependency depends_on: @@ -57,6 +58,7 @@ variables: # - etc/evergreen_yml_components/variants/rhel/test_dev_master_and_lts_branches_only.yml # - etc/evergreen_yml_components/variants/rhel/test_dev.yml # - etc/evergreen_yml_components/variants/sanitizer/test_dev_master_branch_only.yml + # - etc/evergreen_yml_components/variants/sanitizer/test_dev.yml # ANY MODIFICATIONS HERE SHOULD ALSO BE MADE IN THOSE FILES - &linux_x86_generic_expansions multiversion_platform: rhel80 @@ -71,6 +73,7 @@ variables: # - etc/evergreen_yml_components/variants/rhel/test_dev_master_branch_only.yml # - etc/evergreen_yml_components/variants/rhel/test_dev.yml # - etc/evergreen_yml_components/variants/sanitizer/test_dev_master_branch_only.yml + # - etc/evergreen_yml_components/variants/sanitizer/test_dev.yml # ANY MODIFICATIONS HERE SHOULD ALSO BE MADE IN THOSE FILES - &enterprise-rhel-88-64-bit-dynamic-expansions <<: *linux_x86_generic_expansions diff --git a/evergreen/resmoke_tests_execute.sh b/evergreen/resmoke_tests_execute.sh index 87594032341..02d255e9993 100644 --- a/evergreen/resmoke_tests_execute.sh +++ b/evergreen/resmoke_tests_execute.sh @@ -125,7 +125,7 @@ if [[ ${disable_unit_tests} = "false" && ! -f ${skip_tests} ]]; then suite_name=${suite} fi - resmoke_env_options="${gcov_environment} ${lang_environment} ${san_options}" + resmoke_env_options="${gcov_environment} ${lang_environment} ${san_options} ${mozjs_options}" echo $resmoke_env_options > resmoke_env_options.txt # The "resmoke_wrapper" expansion is used by the 'burn_in_tests' task to wrap the resmoke.py diff --git a/jstests/aggregation/query_limits_test.js b/jstests/aggregation/query_limits_test.js index 30a97cd4db6..4aeb4351f12 100644 --- a/jstests/aggregation/query_limits_test.js +++ b/jstests/aggregation/query_limits_test.js @@ -24,7 +24,7 @@ import {checkCascadesOptimizerEnabled} from "jstests/libs/optimizer_utils.js"; const debugBuild = db.adminCommand("buildInfo").debug; if (debugBuild || !_optimizationsEnabled() || _isAddressSanitizerActive() || _isLeakSanitizerActive() || _isThreadSanitizerActive() || - _isUndefinedBehaviorSanitizerActive()) { + _isUndefinedBehaviorSanitizerActive() || _isSpiderMonkeyDebugEnabled()) { jsTestLog("Returning early because debug is on, opt is off, or a sanitizer is enabled."); return; } diff --git a/src/mongo/scripting/mozjs/base.h b/src/mongo/scripting/mozjs/base.h index e773be798d3..9e400167356 100644 --- a/src/mongo/scripting/mozjs/base.h +++ b/src/mongo/scripting/mozjs/base.h @@ -65,6 +65,7 @@ struct BaseInfo { static const JSFunctionSpec* freeFunctions; static const JSFunctionSpec* methods; static const unsigned classFlags = 0; + static constexpr uint32_t finalizeFlag = JSCLASS_FOREGROUND_FINALIZE; static void addProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, diff --git a/src/mongo/scripting/mozjs/bindata.h b/src/mongo/scripting/mozjs/bindata.h index 98c336ddc3e..726b390f40e 100644 --- a/src/mongo/scripting/mozjs/bindata.h +++ b/src/mongo/scripting/mozjs/bindata.h @@ -66,7 +66,8 @@ struct BinDataInfo : public BaseInfo { static const JSFunctionSpec freeFunctions[4]; static const char* const className; - static const unsigned classFlags = JSCLASS_HAS_RESERVED_SLOTS(BinDataSlotCount); + static const unsigned classFlags = + JSCLASS_HAS_RESERVED_SLOTS(BinDataSlotCount) | BaseInfo::finalizeFlag; }; } // namespace mozjs diff --git a/src/mongo/scripting/mozjs/bson.h b/src/mongo/scripting/mozjs/bson.h index 234f20884d7..e75e1a269be 100644 --- a/src/mongo/scripting/mozjs/bson.h +++ b/src/mongo/scripting/mozjs/bson.h @@ -73,7 +73,8 @@ struct BSONInfo : public BaseInfo { JS::ObjectOpResult& result); static const char* const className; - static const unsigned classFlags = JSCLASS_HAS_RESERVED_SLOTS(BSONInfoSlotCount); + static const unsigned classFlags = + JSCLASS_HAS_RESERVED_SLOTS(BSONInfoSlotCount) | BaseInfo::finalizeFlag; static const InstallType installType = InstallType::Private; static void postInstall(JSContext* cx, JS::HandleObject global, JS::HandleObject proto); diff --git a/src/mongo/scripting/mozjs/cursor.h b/src/mongo/scripting/mozjs/cursor.h index 92cca7f7e40..fcd7c5a7033 100644 --- a/src/mongo/scripting/mozjs/cursor.h +++ b/src/mongo/scripting/mozjs/cursor.h @@ -69,7 +69,8 @@ struct CursorInfo : public BaseInfo { static const JSFunctionSpec methods[9]; static const char* const className; - static const unsigned classFlags = JSCLASS_HAS_RESERVED_SLOTS(CursorInfoSlotCount); + static const unsigned classFlags = + JSCLASS_HAS_RESERVED_SLOTS(CursorInfoSlotCount) | BaseInfo::finalizeFlag; static const InstallType installType = InstallType::Private; /** diff --git a/src/mongo/scripting/mozjs/cursor_handle.h b/src/mongo/scripting/mozjs/cursor_handle.h index e50e3f5b7d5..0b4861181ea 100644 --- a/src/mongo/scripting/mozjs/cursor_handle.h +++ b/src/mongo/scripting/mozjs/cursor_handle.h @@ -61,7 +61,8 @@ struct CursorHandleInfo : public BaseInfo { static const JSFunctionSpec methods[2]; static const char* const className; - static const unsigned classFlags = JSCLASS_HAS_RESERVED_SLOTS(CursorHandleInfoSlotCount); + static const unsigned classFlags = + JSCLASS_HAS_RESERVED_SLOTS(CursorHandleInfoSlotCount) | BaseInfo::finalizeFlag; static const InstallType installType = InstallType::Private; /** diff --git a/src/mongo/scripting/mozjs/dbref.h b/src/mongo/scripting/mozjs/dbref.h index b6e0dbd5c60..3dc0a37f30f 100644 --- a/src/mongo/scripting/mozjs/dbref.h +++ b/src/mongo/scripting/mozjs/dbref.h @@ -56,7 +56,8 @@ struct DBRefInfo : public BaseInfo { static void construct(JSContext* cx, JS::CallArgs args); static const char* const className; - static const unsigned classFlags = JSCLASS_HAS_RESERVED_SLOTS(DBRefInfoSlotCount); + static const unsigned classFlags = + JSCLASS_HAS_RESERVED_SLOTS(DBRefInfoSlotCount) | BaseInfo::finalizeFlag; static void delProperty(JSContext* cx, JS::HandleObject obj, diff --git a/src/mongo/scripting/mozjs/implscope.cpp b/src/mongo/scripting/mozjs/implscope.cpp index 39369402408..53681f55890 100644 --- a/src/mongo/scripting/mozjs/implscope.cpp +++ b/src/mongo/scripting/mozjs/implscope.cpp @@ -560,7 +560,7 @@ MozJSImplScope::MozJSImplScope(MozJSScriptEngine* engine, boost::optional j } MozJSImplScope::~MozJSImplScope() { - invariant(!_promiseResult.has_value()); + invariant(!_promiseResult.initialized()); currentJSScope = nullptr; for (auto&& x : _funcs) { @@ -712,7 +712,8 @@ void MozJSImplScope::_MozJSCreateFunction(StringData raw, JS::MutableHandleValue bool MozJSImplScope::onSyncPromiseResolved(JSContext* cx, unsigned argc, JS::Value* vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); auto scope = getScope(cx); - scope->_promiseResult.emplace(cx, args[0]); + invariant(!scope->_promiseResult.initialized()); + scope->_promiseResult.init(cx, args[0]); args.rval().setUndefined(); return true; } @@ -763,9 +764,9 @@ bool MozJSImplScope::awaitPromise(JSContext* cx, return false; } - invariant(scope->_promiseResult.has_value()); - out.set(*scope->_promiseResult); - scope->_promiseResult = boost::none; + invariant(scope->_promiseResult.initialized()); + out.set(scope->_promiseResult); + scope->_promiseResult.reset(); return true; } @@ -1166,6 +1167,11 @@ bool MozJSImplScope::_checkErrorState(bool success, bool reportError, bool asser if (_status.isOK()) { JS::RootedValue excn(_context); if (JS_GetPendingException(_context, &excn)) { + // The pending JS exception needs to be cleared before we call ValueWriter below to + // print the exception. ValueWriter::toStringData() may call back into the Interpret, + // which asserts that we don't have an exception pending in DEBUG builds. + JS_ClearPendingException(_context); + if (excn.isObject()) { str::stream ss; // Exceptions originating from C++ should not get the "uncaught exception: " prefix. @@ -1210,6 +1216,8 @@ bool MozJSImplScope::_checkErrorState(bool success, bool reportError, bool asser _status = Status(ErrorCodes::UnknownError, "Unknown Failure from JSInterpreter"); } } + // We always unconditionally clear any pending exception, as this method _checkErrorState is + // expected to report and clear the errors before returning. JS_ClearPendingException(_context); if (auto extraInfo = _status.extraInfo()) { diff --git a/src/mongo/scripting/mozjs/implscope.h b/src/mongo/scripting/mozjs/implscope.h index 114d0f09daf..cd5f0a7f852 100644 --- a/src/mongo/scripting/mozjs/implscope.h +++ b/src/mongo/scripting/mozjs/implscope.h @@ -449,8 +449,6 @@ private: struct MozRuntime { public: MozRuntime(const MozJSScriptEngine* engine, boost::optional jsHeapLimitMB); - - std::unique_ptr> _runtime; std::unique_ptr> _context; }; @@ -516,7 +514,10 @@ private: std::unique_ptr _moduleLoader; std::unique_ptr _environmentPreparer; - boost::optional _promiseResult; + // _promiseResult must be a persistentRootedValue (instead of a simple RootedValue). Using a + // simple RootedValue here affects the stack cleanup conditions in the promise's execution + // context. + JS::PersistentRootedValue _promiseResult; WrapType _binDataProto; WrapType _bsonProto; diff --git a/src/mongo/scripting/mozjs/jsthread.h b/src/mongo/scripting/mozjs/jsthread.h index ddec39c842f..e0d759cd269 100644 --- a/src/mongo/scripting/mozjs/jsthread.h +++ b/src/mongo/scripting/mozjs/jsthread.h @@ -74,7 +74,8 @@ struct JSThreadInfo : public BaseInfo { static const JSFunctionSpec freeFunctions[3]; static const char* const className; - static const unsigned classFlags = JSCLASS_HAS_RESERVED_SLOTS(JSThreadInfoSlotCount); + static const unsigned classFlags = + JSCLASS_HAS_RESERVED_SLOTS(JSThreadInfoSlotCount) | BaseInfo::finalizeFlag; static const InstallType installType = InstallType::Private; }; diff --git a/src/mongo/scripting/mozjs/module_loader.cpp b/src/mongo/scripting/mozjs/module_loader.cpp index d211d67eef3..8cfea9df479 100644 --- a/src/mongo/scripting/mozjs/module_loader.cpp +++ b/src/mongo/scripting/mozjs/module_loader.cpp @@ -361,7 +361,7 @@ JSString* ModuleLoader::fetchSource(JSContext* cx, enum GlobalAppSlot { GlobalAppSlotModuleRegistry, GlobalAppSlotCount }; JSObject* ModuleLoader::getOrCreateModuleRegistry(JSContext* cx) { - JSObject* global = JS::CurrentGlobalOrNull(cx); + JS::RootedObject global(cx, JS::CurrentGlobalOrNull(cx)); if (!global) { return nullptr; } @@ -371,7 +371,7 @@ JSObject* ModuleLoader::getOrCreateModuleRegistry(JSContext* cx) { return &value.toObject(); } - JSObject* registry = JS::NewMapObject(cx); + JS::RootedObject registry(cx, JS::NewMapObject(cx)); if (!registry) { return nullptr; } diff --git a/src/mongo/scripting/mozjs/mongo.h b/src/mongo/scripting/mozjs/mongo.h index 83591e767aa..1ad3c3bc77f 100644 --- a/src/mongo/scripting/mozjs/mongo.h +++ b/src/mongo/scripting/mozjs/mongo.h @@ -112,7 +112,8 @@ struct MongoBase : public BaseInfo { static const JSFunctionSpec methods[31]; static const char* const className; - static const unsigned classFlags = JSCLASS_HAS_RESERVED_SLOTS(MongoBaseSlotCount); + static const unsigned classFlags = + JSCLASS_HAS_RESERVED_SLOTS(MongoBaseSlotCount) | BaseInfo::finalizeFlag; }; /** diff --git a/src/mongo/scripting/mozjs/nativefunction.h b/src/mongo/scripting/mozjs/nativefunction.h index 3ba89ad61b6..bc1461a6e4b 100644 --- a/src/mongo/scripting/mozjs/nativefunction.h +++ b/src/mongo/scripting/mozjs/nativefunction.h @@ -62,7 +62,8 @@ struct NativeFunctionInfo : public BaseInfo { static const char* const inheritFrom; static const char* const className; - static const unsigned classFlags = JSCLASS_HAS_RESERVED_SLOTS(NativeFunctionInfoSlotCount); + static const unsigned classFlags = + JSCLASS_HAS_RESERVED_SLOTS(NativeFunctionInfoSlotCount) | BaseInfo::finalizeFlag; static const InstallType installType = InstallType::Private; struct Functions { diff --git a/src/mongo/scripting/mozjs/numberdecimal.h b/src/mongo/scripting/mozjs/numberdecimal.h index 94a14039613..31947b05161 100644 --- a/src/mongo/scripting/mozjs/numberdecimal.h +++ b/src/mongo/scripting/mozjs/numberdecimal.h @@ -61,8 +61,8 @@ struct NumberDecimalInfo : public BaseInfo { static const JSFunctionSpec methods[3]; static const char* const className; - static const unsigned classFlags = JSCLASS_HAS_RESERVED_SLOTS(NumberDecimalInfoSlotCount); - + static const unsigned classFlags = + JSCLASS_HAS_RESERVED_SLOTS(NumberDecimalInfoSlotCount) | BaseInfo::finalizeFlag; static Decimal128 ToNumberDecimal(JSContext* cx, JS::HandleObject object); static Decimal128 ToNumberDecimal(JSContext* cx, JS::HandleValue value); diff --git a/src/mongo/scripting/mozjs/numberint.h b/src/mongo/scripting/mozjs/numberint.h index 2ac72aaff06..8a5c0d139a0 100644 --- a/src/mongo/scripting/mozjs/numberint.h +++ b/src/mongo/scripting/mozjs/numberint.h @@ -61,7 +61,8 @@ struct NumberIntInfo : public BaseInfo { static const JSFunctionSpec methods[5]; static const char* const className; - static const unsigned classFlags = JSCLASS_HAS_RESERVED_SLOTS(NumberIntInfoSlotCount); + static const unsigned classFlags = + JSCLASS_HAS_RESERVED_SLOTS(NumberIntInfoSlotCount) | BaseInfo::finalizeFlag; static int ToNumberInt(JSContext* cx, JS::HandleObject object); static int ToNumberInt(JSContext* cx, JS::HandleValue value); diff --git a/src/mongo/scripting/mozjs/numberlong.h b/src/mongo/scripting/mozjs/numberlong.h index 89d9cbce1fa..7d6a6aa89cc 100644 --- a/src/mongo/scripting/mozjs/numberlong.h +++ b/src/mongo/scripting/mozjs/numberlong.h @@ -77,7 +77,8 @@ struct NumberLongInfo : public BaseInfo { static const JSFunctionSpec methods[6]; static const char* const className; - static const unsigned classFlags = JSCLASS_HAS_RESERVED_SLOTS(NumberLongInfoSlotCount); + static const unsigned classFlags = + JSCLASS_HAS_RESERVED_SLOTS(NumberLongInfoSlotCount) | BaseInfo::finalizeFlag; static void postInstall(JSContext* cx, JS::HandleObject global, JS::HandleObject proto); diff --git a/src/mongo/scripting/mozjs/oid.h b/src/mongo/scripting/mozjs/oid.h index 74651617bc1..72189a2a915 100644 --- a/src/mongo/scripting/mozjs/oid.h +++ b/src/mongo/scripting/mozjs/oid.h @@ -60,8 +60,8 @@ struct OIDInfo : public BaseInfo { static const JSFunctionSpec methods[3]; - static const unsigned classFlags = JSCLASS_HAS_RESERVED_SLOTS(OIDInfoSlotCount); - + static const unsigned classFlags = + JSCLASS_HAS_RESERVED_SLOTS(OIDInfoSlotCount) | BaseInfo::finalizeFlag; static const char* const className; static void postInstall(JSContext* cx, JS::HandleObject global, JS::HandleObject proto); diff --git a/src/mongo/scripting/mozjs/session.h b/src/mongo/scripting/mozjs/session.h index d5cff762b47..0f3d5a19b54 100644 --- a/src/mongo/scripting/mozjs/session.h +++ b/src/mongo/scripting/mozjs/session.h @@ -67,7 +67,8 @@ struct SessionInfo : public BaseInfo { static const JSFunctionSpec methods[8]; static const char* const className; - static const unsigned classFlags = JSCLASS_HAS_RESERVED_SLOTS(SessionInfoSlotCount); + static const unsigned classFlags = + JSCLASS_HAS_RESERVED_SLOTS(SessionInfoSlotCount) | BaseInfo::finalizeFlag; static const InstallType installType = InstallType::Private; static void make(JSContext* cx, diff --git a/src/mongo/scripting/mozjs/status.h b/src/mongo/scripting/mozjs/status.h index 0163a3ef25d..cf117e39098 100644 --- a/src/mongo/scripting/mozjs/status.h +++ b/src/mongo/scripting/mozjs/status.h @@ -65,7 +65,8 @@ struct MongoStatusInfo : public BaseInfo { static const char* const className; static const char* const inheritFrom; - static const unsigned classFlags = JSCLASS_HAS_RESERVED_SLOTS(MongoStatusInfoSlotCount); + static const unsigned classFlags = + JSCLASS_HAS_RESERVED_SLOTS(MongoStatusInfoSlotCount) | BaseInfo::finalizeFlag; static const InstallType installType = InstallType::Private; static Status toStatus(JSContext* cx, JS::HandleObject object); diff --git a/src/mongo/shell/utils.js b/src/mongo/shell/utils.js index 083b8652346..ccedf85437e 100644 --- a/src/mongo/shell/utils.js +++ b/src/mongo/shell/utils.js @@ -402,6 +402,21 @@ function _isUndefinedBehaviorSanitizerActive() { return __sanitizeMatch("undefined"); } +// Enabling a custom JS_GC_ZEAL value for spidermonkey is a two step process: +// 1) JS_GC_ZEAL preprocessor directive needs to be defined at compilation (spider-monkey-dbg=on). +// 2) A valid JS_GC_ZEAL value needs to be provided as an environment variable at runtime. +// In order to detect whether we are running with JS_GC_ZEAL enabled, ideally we'd like to check for +// the CPPDEFINE for JS_GC_ZEAL. Unfortunately, this CPPDEFINE only applies to libmozjs, and is not +// exposed in the BuildInfo response. Instead, we rely on detecting a non-empty environment variable +// for JS_GC_ZEAL. We could have restricted the RegExp to match a valid input for JS_GC_ZEAL +// For example: RegExp(/^\w+(;\w+)*(,\d+)?$/), but SpiderMonkey performs the validation for us. +// As long as a non-whitespace JS_GC_ZEAL value has been detected, we report it as being enabled. +function _isSpiderMonkeyDebugEnabled() { + const jsGcZeal = _getEnv("JS_GC_ZEAL"); + let regex = RegExp(/^\S+$/); + return regex.test(jsGcZeal); +} + jsTestName = function() { if (TestData) { // If we are using the jsTestName as a database name and performing tenant prefixing diff --git a/src/third_party/SConscript b/src/third_party/SConscript index defef8bf334..bd9ece96bbf 100644 --- a/src/third_party/SConscript +++ b/src/third_party/SConscript @@ -78,6 +78,7 @@ def injectMozJS(thisEnv): thisEnv.Prepend(CPPDEFINES=[ 'DEBUG', 'JS_DEBUG', + 'JS_GC_ZEAL' ]) diff --git a/src/third_party/mozjs/SConscript b/src/third_party/mozjs/SConscript index abbdef7e835..6ebd467c4bd 100644 --- a/src/third_party/mozjs/SConscript +++ b/src/third_party/mozjs/SConscript @@ -147,6 +147,9 @@ sources = [ "extract/js/src/wasm/WasmCode-platform.cpp", ] +if get_option('spider-monkey-dbg') == "on": + sources.extend(["extract/js/src/util/Utility.cpp"]) + if env['TARGET_ARCH'] == 'x86_64' and not env.TargetOSIs('windows'): env.Append(CCFLAGS=['-mavx2']) sources.extend(["extract/mozglue/misc/SIMD_avx2.cpp", "extract/mozglue/misc/SSE.cpp"]) diff --git a/src/third_party/mozjs/extract/js/src/util/Utility.cpp b/src/third_party/mozjs/extract/js/src/util/Utility.cpp index 4fcacaba2e5..2ba975bbec0 100644 --- a/src/third_party/mozjs/extract/js/src/util/Utility.cpp +++ b/src/third_party/mozjs/extract/js/src/util/Utility.cpp @@ -100,6 +100,9 @@ bool js::gExtraPoisoningEnabled = false; # endif #endif +// MONGODB MODIFICATION: We don't want to compile the below code when running in mongo embedding. +// Instead, we would like to rely on our own JS custom allocator implementation in mongo_sources. +#ifndef JS_USE_CUSTOM_ALLOCATOR JS_PUBLIC_DATA arena_id_t js::MallocArena; JS_PUBLIC_DATA arena_id_t js::ArrayBufferContentsArena; JS_PUBLIC_DATA arena_id_t js::StringBufferArena; @@ -121,6 +124,7 @@ void js::ShutDownMallocAllocator() { // moz_dispose_arena(MallocArena); // moz_dispose_arena(ArrayBufferContentsArena); } +#endif extern void js::AssertJSStringBufferInCorrectArena(const void* ptr) { // `jemalloc_ptr_info()` only exists if MOZ_MEMORY is defined, and it only diff --git a/src/third_party/mozjs/extract/js/src/vm/JSObject.cpp b/src/third_party/mozjs/extract/js/src/vm/JSObject.cpp index 292971cf3e4..2b43c1f4269 100644 --- a/src/third_party/mozjs/extract/js/src/vm/JSObject.cpp +++ b/src/third_party/mozjs/extract/js/src/vm/JSObject.cpp @@ -3583,6 +3583,8 @@ void js::AssertJSClassInvariants(const JSClass* clasp) { // // Environment objects unfortunately use these hooks, but environment objects // are not exposed directly to script so they're generally less of an issue. + // MONGODB MODIFICATION: Disable the below MOZ_ASSERT calls when JIT is disabled, as these appear to be JIT specific checks. +#ifndef JS_CODEGEN_NONE if (clasp->isNativeObject() && clasp != &WithEnvironmentObject::class_ && clasp != &ModuleEnvironmentObject::class_ && clasp != &RuntimeLexicalErrorObject::class_) { @@ -3595,6 +3597,7 @@ void js::AssertJSClassInvariants(const JSClass* clasp) { MOZ_ASSERT(!clasp->getOpsGetOwnPropertyDescriptor()); MOZ_ASSERT(!clasp->getOpsDeleteProperty()); } +#endif } /* static */ diff --git a/src/third_party/mozjs/get-sources.sh b/src/third_party/mozjs/get-sources.sh index b42e1398d76..ca1b4e6f870 100755 --- a/src/third_party/mozjs/get-sources.sh +++ b/src/third_party/mozjs/get-sources.sh @@ -9,7 +9,7 @@ set -vx NAME=spidermonkey LIB_GIT_BRANCH=spidermonkey-esr115.7-cpp-only -LIB_GIT_REVISION=bb6edb4fcd43607c87de81df8c58db11a663634a +LIB_GIT_REVISION=8067826deecd3e89bdd85c80364ce5ce824c1f32 LIB_GIT_REPO=git@github.com:mongodb-forks/spidermonkey.git DEST_DIR=$(git rev-parse --show-toplevel)/src/third_party/mozjs