MozJSImplScope::MozRuntime::MozRuntime() { mongo::sm::reset(kMallocMemoryLimit); // If this runtime isn't running on an NSPR thread, then it is // running on a mongo thread. In that case, we need to insert a // fake NSPR thread so that the SM runtime can call PR functions // without falling over. auto thread = PR_GetCurrentThread(); if (!thread) { PR_BindThread(_thread = PR_CreateFakeThread()); } { stdx::unique_lock<stdx::mutex> lk(gRuntimeCreationMutex); if (gFirstRuntimeCreated) { // If we've already made a runtime, just proceed lk.unlock(); } else { // If this is the first one, hold the lock until after the first // one's done gFirstRuntimeCreated = true; } _runtime = JS_NewRuntime(kMaxBytesBeforeGC); const StackLocator locator; const auto available = locator.available(); if (available) { // We fudge by 64k for a two reasons. First, it appears // that the internal recursion checks that SM performs can // have stack usage between checks of more than 32k in // some builds. Second, some platforms report the guard // page (in the linux sense) as "part of the stack", even // though accessing that page will fault the process. We // don't have a good way of getting information about the // guard page on those platforms. // // TODO: What if we are running on a platform with very // large pages, like 4MB? JS_SetNativeStackQuota(_runtime, available.get() - (64 * 1024)); } } uassert(ErrorCodes::JSInterpreterFailure, "Failed to initialize JSRuntime", _runtime); _context = JS_NewContext(_runtime, kStackChunkSize); uassert(ErrorCodes::JSInterpreterFailure, "Failed to initialize JSContext", _context); }
MozJSImplScope::MozRuntime::MozRuntime() { mongol::sm::reset(kMallocMemoryLimit); // If this runtime isn't running on an NSPR thread, then it is // running on a mongol thread. In that case, we need to insert a // fake NSPR thread so that the SM runtime can call PR functions // without falling over. auto thread = PR_GetCurrentThread(); if (!thread) { PR_BindThread(_thread = PR_CreateFakeThread()); } { stdx::unique_lock<stdx::mutex> lk(gRuntimeCreationMutex); if (gFirstRuntimeCreated) { // If we've already made a runtime, just proceed lk.unlock(); } else { // If this is the first one, hold the lock until after the first // one's done gFirstRuntimeCreated = true; } _runtime = JS_NewRuntime(kMaxBytesBeforeGC); // TODO: Re-enable this when it can be done in a way that does // not conflict with the performance fix in SERVER-20678. The // jscore/recursion.js tes tshould be re-enabled when this is // uncommented. // // static_assert(kMaxStackBytes > (32 * 1024), "kMaxStackBytes must be larger than 32k"); // JS_SetNativeStackQuota(_runtime, kMaxStackBytes - (32 * 1024)); } uassert(ErrorCodes::JSInterpreterFailure, "Failed to initialize JSRuntime", _runtime); _context = JS_NewContext(_runtime, kStackChunkSize); uassert(ErrorCodes::JSInterpreterFailure, "Failed to initialize JSContext", _context); }