Merge inbound to m-c.

This commit is contained in:
Ryan VanderMeulen 2014-02-14 15:21:12 -05:00
commit 3bdc9a7575
68 changed files with 373 additions and 1135 deletions

View File

@ -79,6 +79,9 @@ TextAttrsMgr::GetAttributes(nsIPersistentProperties* aAttributes,
if (mOffsetAcc) {
offsetNode = mOffsetAcc->GetContent();
offsetElm = nsCoreUtils::GetDOMElementFor(offsetNode);
NS_ASSERTION(offsetElm, "No element for offset accessible!");
if (!offsetElm)
return;
frame = offsetElm->GetPrimaryFrame();
}

View File

@ -30,9 +30,16 @@
#include "mozilla/layers/PCompositorChild.h"
#include "mozilla/net/NeckoChild.h"
#include "mozilla/Preferences.h"
#if defined(MOZ_CONTENT_SANDBOX) && defined(XP_UNIX) && !defined(XP_MACOSX)
#if defined(MOZ_CONTENT_SANDBOX)
#if defined(XP_WIN)
#define TARGET_SANDBOX_EXPORTS
#include "mozilla/sandboxTarget.h"
#elif defined(XP_UNIX) && !defined(XP_MACOSX)
#include "mozilla/Sandbox.h"
#endif
#endif
#include "mozilla/unused.h"
#include "nsIConsoleListener.h"
@ -593,12 +600,17 @@ ContentChild::RecvSetProcessPrivileges(const ChildPrivileges& aPrivs)
aPrivs;
// If this fails, we die.
SetCurrentProcessPrivileges(privs);
#if defined(MOZ_CONTENT_SANDBOX) && defined(XP_UNIX) && !defined(XP_MACOSX)
#if defined(MOZ_CONTENT_SANDBOX)
#if defined(XP_WIN)
mozilla::SandboxTarget::Instance()->StartSandbox();
#else if defined(XP_UNIX) && !defined(XP_MACOSX)
// SetCurrentProcessSandbox should be moved close to process initialization
// time if/when possible. SetCurrentProcessPrivileges should probably be
// moved as well. Right now this is set ONLY if we receive the
// RecvSetProcessPrivileges message. See bug 880808.
SetCurrentProcessSandbox();
#endif
#endif
return true;
}

View File

@ -25,6 +25,7 @@
#include "sandbox/chromium/base/basictypes.h"
#include "sandbox/win/src/sandbox.h"
#include "sandbox/win/src/sandbox_factory.h"
#include "mozilla/sandboxTarget.h"
#endif
#ifdef MOZ_WIDGET_GONK
@ -67,14 +68,27 @@ InitializeBinder(void *aDummy) {
}
#endif
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
static bool gIsSandboxEnabled = false;
void StartSandboxCallback()
{
if (gIsSandboxEnabled) {
sandbox::TargetServices* target_service =
sandbox::SandboxFactory::GetTargetServices();
target_service->LowerToken();
}
}
#endif
int
main(int argc, char* argv[])
{
bool isNuwa = false;
bool isSandboxEnabled = false;
for (int i = 1; i < argc; i++) {
isNuwa |= strcmp(argv[i], "-nuwa") == 0;
isSandboxEnabled |= strcmp(argv[i], "-sandbox") == 0;
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
gIsSandboxEnabled |= strcmp(argv[i], "-sandbox") == 0;
#endif
}
#ifdef MOZ_NUWA_PROCESS
@ -100,24 +114,6 @@ main(int argc, char* argv[])
#endif
#endif
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
if (isSandboxEnabled) {
sandbox::TargetServices* target_service =
sandbox::SandboxFactory::GetTargetServices();
if (!target_service) {
return 1;
}
sandbox::ResultCode result = target_service->Init();
if (result != sandbox::SBOX_ALL_OK) {
return 2;
}
// Initialization is finished, switch to the lowered token
target_service->LowerToken();
}
#endif
// Check for the absolute minimum number of args we need to move
// forward here. We expect the last arg to be the child process type.
if (argc < 1)
@ -132,6 +128,22 @@ main(int argc, char* argv[])
mozilla::SanitizeEnvironmentVariables();
SetDllDirectory(L"");
}
#ifdef MOZ_CONTENT_SANDBOX
if (gIsSandboxEnabled) {
sandbox::TargetServices* target_service =
sandbox::SandboxFactory::GetTargetServices();
if (!target_service) {
return 1;
}
sandbox::ResultCode result = target_service->Init();
if (result != sandbox::SBOX_ALL_OK) {
return 2;
}
mozilla::SandboxTarget::Instance()->SetStartSandboxCallback(StartSandboxCallback);
}
#endif
#endif
nsresult rv = XRE_InitChildProcess(argc, argv, proctype);

View File

@ -21,3 +21,11 @@ LOCAL_INCLUDES += [
'/toolkit/xre',
'/xpcom/base',
]
if CONFIG['MOZ_CONTENT_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
# For sandbox includes and the include dependencies those have
LOCAL_INCLUDES += [
'/security',
'/security/sandbox',
'/security/sandbox/chromium',
]

View File

@ -826,7 +826,6 @@ StructTypeRepresentation::fieldNamed(jsid id) const
uint32_t unused;
JSAtom *atom = JSID_TO_ATOM(id);
AutoThreadSafeAccess ts(atom);
if (atom->isIndex(&unused))
return nullptr;

View File

@ -2865,12 +2865,10 @@ frontend::EmitFunctionScript(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNo
RootedFunction fun(cx, bce->script->functionNonDelazifying());
JS_ASSERT(fun->isInterpreted());
if (fun->isInterpretedLazy()) {
AutoLockForCompilation lock(cx);
if (fun->isInterpretedLazy())
fun->setUnlazifiedScript(bce->script);
} else {
else
fun->setScript(bce->script);
}
bce->tellDebuggerAboutCompiledScript(cx);

View File

@ -191,9 +191,6 @@ class BarrieredCell : public gc::Cell
static MOZ_ALWAYS_INLINE void readBarrier(T *thing) {
#ifdef JSGC_INCREMENTAL
// Off thread Ion compilation never occurs when barriers are active.
js::AutoThreadSafeAccess ts(thing);
JS::shadow::Zone *shadowZone = thing->shadowZoneFromAnyThread();
if (shadowZone->needsBarrier()) {
MOZ_ASSERT(!RuntimeFromMainThreadIsHeapMajorCollecting(shadowZone));

View File

@ -1109,37 +1109,9 @@ InFreeList(ArenaHeader *aheader, void *thing)
} /* namespace gc */
// Ion compilation mainly occurs off the main thread, and may run while the
// main thread is performing arbitrary VM operations, excepting GC activity.
// The below class is used to mark functions and other operations which can
// safely be performed off thread without racing. When running with thread
// safety checking on, any access to a GC thing outside of AutoThreadSafeAccess
// will cause an access violation.
class MOZ_STACK_CLASS AutoThreadSafeAccess
{
public:
#if defined(DEBUG) && defined(JS_CPU_X64) && !defined(XP_WIN)
#define JS_CAN_CHECK_THREADSAFE_ACCESSES
JSRuntime *runtime;
gc::ArenaHeader *arena;
AutoThreadSafeAccess(const gc::Cell *cell MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
~AutoThreadSafeAccess();
#else
AutoThreadSafeAccess(const gc::Cell *cell MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
}
~AutoThreadSafeAccess() {}
#endif
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
gc::AllocKind
gc::Cell::tenuredGetAllocKind() const
{
AutoThreadSafeAccess ts(this);
return arenaHeader()->getAllocKind();
}

View File

@ -136,10 +136,7 @@ ICStubIterator::unlink(JSContext *cx)
JS_ASSERT(currentStub_ != fallbackStub_);
JS_ASSERT(!unlinked_);
{
AutoLockForCompilation lock(cx);
fallbackStub_->unlinkStub(cx->zone(), previousStub_, currentStub_);
}
fallbackStub_->unlinkStub(cx->zone(), previousStub_, currentStub_);
// Mark the current iterator position as unlinked, so operator++ works properly.
unlinked_ = true;
@ -1066,7 +1063,7 @@ DoProfilerFallback(JSContext *cx, BaselineFrame *frame, ICProfiler_Fallback *stu
ICStub *optStub = compiler.getStub(compiler.getStubSpace(script));
if (!optStub)
return false;
stub->addNewStub(cx, optStub);
stub->addNewStub(optStub);
return true;
}
@ -1797,7 +1794,7 @@ DoCompareFallback(JSContext *cx, BaselineFrame *frame, ICCompare_Fallback *stub,
if (!int32Stub)
return false;
stub->addNewStub(cx, int32Stub);
stub->addNewStub(int32Stub);
return true;
}
@ -1815,7 +1812,7 @@ DoCompareFallback(JSContext *cx, BaselineFrame *frame, ICCompare_Fallback *stub,
if (!doubleStub)
return false;
stub->addNewStub(cx, doubleStub);
stub->addNewStub(doubleStub);
return true;
}
@ -1830,7 +1827,7 @@ DoCompareFallback(JSContext *cx, BaselineFrame *frame, ICCompare_Fallback *stub,
if (!doubleStub)
return false;
stub->addNewStub(cx, doubleStub);
stub->addNewStub(doubleStub);
return true;
}
@ -1841,7 +1838,7 @@ DoCompareFallback(JSContext *cx, BaselineFrame *frame, ICCompare_Fallback *stub,
if (!booleanStub)
return false;
stub->addNewStub(cx, booleanStub);
stub->addNewStub(booleanStub);
return true;
}
@ -1854,7 +1851,7 @@ DoCompareFallback(JSContext *cx, BaselineFrame *frame, ICCompare_Fallback *stub,
if (!optStub)
return false;
stub->addNewStub(cx, optStub);
stub->addNewStub(optStub);
return true;
}
@ -1866,7 +1863,7 @@ DoCompareFallback(JSContext *cx, BaselineFrame *frame, ICCompare_Fallback *stub,
if (!stringStub)
return false;
stub->addNewStub(cx, stringStub);
stub->addNewStub(stringStub);
return true;
}
@ -1878,7 +1875,7 @@ DoCompareFallback(JSContext *cx, BaselineFrame *frame, ICCompare_Fallback *stub,
if (!objectStub)
return false;
stub->addNewStub(cx, objectStub);
stub->addNewStub(objectStub);
return true;
}
@ -1896,7 +1893,7 @@ DoCompareFallback(JSContext *cx, BaselineFrame *frame, ICCompare_Fallback *stub,
if (!objectStub)
return false;
stub->addNewStub(cx, objectStub);
stub->addNewStub(objectStub);
return true;
}
}
@ -2207,7 +2204,7 @@ DoToBoolFallback(JSContext *cx, BaselineFrame *frame, ICToBool_Fallback *stub, H
if (!int32Stub)
return false;
stub->addNewStub(cx, int32Stub);
stub->addNewStub(int32Stub);
return true;
}
@ -2218,7 +2215,7 @@ DoToBoolFallback(JSContext *cx, BaselineFrame *frame, ICToBool_Fallback *stub, H
if (!doubleStub)
return false;
stub->addNewStub(cx, doubleStub);
stub->addNewStub(doubleStub);
return true;
}
@ -2229,7 +2226,7 @@ DoToBoolFallback(JSContext *cx, BaselineFrame *frame, ICToBool_Fallback *stub, H
if (!stringStub)
return false;
stub->addNewStub(cx, stringStub);
stub->addNewStub(stringStub);
return true;
}
@ -2239,7 +2236,7 @@ DoToBoolFallback(JSContext *cx, BaselineFrame *frame, ICToBool_Fallback *stub, H
if (!nilStub)
return false;
stub->addNewStub(cx, nilStub);
stub->addNewStub(nilStub);
return true;
}
@ -2250,7 +2247,7 @@ DoToBoolFallback(JSContext *cx, BaselineFrame *frame, ICToBool_Fallback *stub, H
if (!objStub)
return false;
stub->addNewStub(cx, objStub);
stub->addNewStub(objStub);
return true;
}
@ -2542,11 +2539,11 @@ DoBinaryArithFallback(JSContext *cx, BaselineFrame *frame, ICBinaryArith_Fallbac
}
if (ret.isDouble())
stub->setSawDoubleResult(cx);
stub->setSawDoubleResult();
// Check to see if a new stub should be generated.
if (stub->numOptimizedStubs() >= ICBinaryArith_Fallback::MAX_OPTIMIZED_STUBS) {
stub->noteUnoptimizableOperands(cx);
stub->noteUnoptimizableOperands();
return true;
}
@ -2559,7 +2556,7 @@ DoBinaryArithFallback(JSContext *cx, BaselineFrame *frame, ICBinaryArith_Fallbac
ICStub *strcatStub = compiler.getStub(compiler.getStubSpace(script));
if (!strcatStub)
return false;
stub->addNewStub(cx, strcatStub);
stub->addNewStub(strcatStub);
return true;
}
@ -2572,7 +2569,7 @@ DoBinaryArithFallback(JSContext *cx, BaselineFrame *frame, ICBinaryArith_Fallbac
ICStub *strcatStub = compiler.getStub(compiler.getStubSpace(script));
if (!strcatStub)
return false;
stub->addNewStub(cx, strcatStub);
stub->addNewStub(strcatStub);
return true;
}
}
@ -2588,13 +2585,13 @@ DoBinaryArithFallback(JSContext *cx, BaselineFrame *frame, ICBinaryArith_Fallbac
ICStub *arithStub = compiler.getStub(compiler.getStubSpace(script));
if (!arithStub)
return false;
stub->addNewStub(cx, arithStub);
stub->addNewStub(arithStub);
return true;
}
// Handle only int32 or double.
if (!lhs.isNumber() || !rhs.isNumber()) {
stub->noteUnoptimizableOperands(cx);
stub->noteUnoptimizableOperands();
return true;
}
@ -2618,7 +2615,7 @@ DoBinaryArithFallback(JSContext *cx, BaselineFrame *frame, ICBinaryArith_Fallbac
ICStub *doubleStub = compiler.getStub(compiler.getStubSpace(script));
if (!doubleStub)
return false;
stub->addNewStub(cx, doubleStub);
stub->addNewStub(doubleStub);
return true;
}
default:
@ -2636,7 +2633,7 @@ DoBinaryArithFallback(JSContext *cx, BaselineFrame *frame, ICBinaryArith_Fallbac
ICStub *int32Stub = compilerInt32.getStub(compilerInt32.getStubSpace(script));
if (!int32Stub)
return false;
stub->addNewStub(cx, int32Stub);
stub->addNewStub(int32Stub);
return true;
}
@ -2655,7 +2652,7 @@ DoBinaryArithFallback(JSContext *cx, BaselineFrame *frame, ICBinaryArith_Fallbac
ICStub *optStub = compiler.getStub(compiler.getStubSpace(script));
if (!optStub)
return false;
stub->addNewStub(cx, optStub);
stub->addNewStub(optStub);
return true;
}
default:
@ -2663,7 +2660,7 @@ DoBinaryArithFallback(JSContext *cx, BaselineFrame *frame, ICBinaryArith_Fallbac
}
}
stub->noteUnoptimizableOperands(cx);
stub->noteUnoptimizableOperands();
return true;
}
#if defined(_MSC_VER)
@ -3058,7 +3055,7 @@ DoUnaryArithFallback(JSContext *cx, BaselineFrame *frame, ICUnaryArith_Fallback
ICStub *int32Stub = compiler.getStub(compiler.getStubSpace(script));
if (!int32Stub)
return false;
stub->addNewStub(cx, int32Stub);
stub->addNewStub(int32Stub);
return true;
}
@ -3072,7 +3069,7 @@ DoUnaryArithFallback(JSContext *cx, BaselineFrame *frame, ICUnaryArith_Fallback
ICStub *doubleStub = compiler.getStub(compiler.getStubSpace(script));
if (!doubleStub)
return false;
stub->addNewStub(cx, doubleStub);
stub->addNewStub(doubleStub);
return true;
}
@ -3757,7 +3754,7 @@ static bool TryAttachNativeGetElemStub(JSContext *cx, HandleScript script, jsbyt
if (!newStub)
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
return true;
}
@ -3809,7 +3806,7 @@ static bool TryAttachNativeGetElemStub(JSContext *cx, HandleScript script, jsbyt
if (!newStub)
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
return true;
}
@ -3843,7 +3840,7 @@ TryAttachGetElemStub(JSContext *cx, JSScript *script, jsbytecode *pc, ICGetElem_
if (!stringStub)
return false;
stub->addNewStub(cx, stringStub);
stub->addNewStub(stringStub);
return true;
}
@ -3861,7 +3858,7 @@ TryAttachGetElemStub(JSContext *cx, JSScript *script, jsbytecode *pc, ICGetElem_
if (!argsStub)
return false;
stub->addNewStub(cx, argsStub);
stub->addNewStub(argsStub);
return true;
}
@ -3883,7 +3880,7 @@ TryAttachGetElemStub(JSContext *cx, JSScript *script, jsbytecode *pc, ICGetElem_
if (!argsStub)
return false;
stub->addNewStub(cx, argsStub);
stub->addNewStub(argsStub);
return true;
}
}
@ -3898,7 +3895,7 @@ TryAttachGetElemStub(JSContext *cx, JSScript *script, jsbytecode *pc, ICGetElem_
if (!denseStub)
return false;
stub->addNewStub(cx, denseStub);
stub->addNewStub(denseStub);
return true;
}
@ -3934,7 +3931,7 @@ TryAttachGetElemStub(JSContext *cx, JSScript *script, jsbytecode *pc, ICGetElem_
if (!typedArrayStub)
return false;
stub->addNewStub(cx, typedArrayStub);
stub->addNewStub(typedArrayStub);
return true;
}
@ -3942,13 +3939,13 @@ TryAttachGetElemStub(JSContext *cx, JSScript *script, jsbytecode *pc, ICGetElem_
// be cached by either Baseline or Ion. Indicate this in the cache so that
// Ion does not generate a cache for this op.
if (!obj->isNative() && !obj->is<TypedArrayObject>())
stub->noteNonNativeAccess(cx);
stub->noteNonNativeAccess();
// GetElem operations which could access negative indexes generally can't
// be optimized without the potential for bailouts, as we can't statically
// determine that an object has no properties on such indexes.
if (rhs.isNumber() && rhs.toNumber() < 0)
stub->noteNegativeIndex(cx);
stub->noteNegativeIndex();
return true;
}
@ -5014,7 +5011,7 @@ DoSetElemFallback(JSContext *cx, BaselineFrame *frame, ICSetElem_Fallback *stub,
if (!denseStub->addUpdateStubForValue(cx, script, obj, JSID_VOIDHANDLE, rhs))
return false;
stub->addNewStub(cx, denseStub);
stub->addNewStub(denseStub);
} else if (!addingCase &&
!DenseSetElemStubExists(cx, ICStub::SetElem_Dense, stub, obj))
{
@ -5028,7 +5025,7 @@ DoSetElemFallback(JSContext *cx, BaselineFrame *frame, ICSetElem_Fallback *stub,
if (!denseStub->addUpdateStubForValue(cx, script, obj, JSID_VOIDHANDLE, rhs))
return false;
stub->addNewStub(cx, denseStub);
stub->addNewStub(denseStub);
}
}
@ -5061,7 +5058,7 @@ DoSetElemFallback(JSContext *cx, BaselineFrame *frame, ICSetElem_Fallback *stub,
if (!typedArrayStub)
return false;
stub->addNewStub(cx, typedArrayStub);
stub->addNewStub(typedArrayStub);
return true;
}
}
@ -5111,13 +5108,13 @@ ICSetElem_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
}
void
BaselineScript::noteArrayWriteHole(JSContext *cx, uint32_t pcOffset)
BaselineScript::noteArrayWriteHole(uint32_t pcOffset)
{
ICEntry &entry = icEntryFromPCOffset(pcOffset);
ICFallbackStub *stub = entry.fallbackStub();
if (stub->isSetElem_Fallback())
stub->toSetElem_Fallback()->noteArrayWriteHole(cx);
stub->toSetElem_Fallback()->noteArrayWriteHole();
}
//
@ -5639,7 +5636,7 @@ TryAttachGlobalNameStub(JSContext *cx, HandleScript script, ICGetName_Fallback *
if (!newStub)
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
return true;
}
@ -5729,7 +5726,7 @@ TryAttachScopeNameStub(JSContext *cx, HandleScript script, ICGetName_Fallback *s
if (!newStub)
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
return true;
}
@ -5936,7 +5933,7 @@ DoGetIntrinsicFallback(JSContext *cx, BaselineFrame *frame, ICGetIntrinsic_Fallb
if (!newStub)
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
return true;
}
@ -5984,7 +5981,7 @@ TryAttachLengthStub(JSContext *cx, JSScript *script, ICGetProp_Fallback *stub, H
return false;
*attached = true;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
return true;
}
@ -5996,7 +5993,7 @@ TryAttachLengthStub(JSContext *cx, JSScript *script, ICGetProp_Fallback *stub, H
return false;
*attached = true;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
return true;
}
@ -6013,7 +6010,7 @@ TryAttachLengthStub(JSContext *cx, JSScript *script, ICGetProp_Fallback *stub, H
return false;
*attached = true;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
return true;
}
if (obj->is<TypedArrayObject>()) {
@ -6025,7 +6022,7 @@ TryAttachLengthStub(JSContext *cx, JSScript *script, ICGetProp_Fallback *stub, H
return false;
*attached = true;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
return true;
}
@ -6041,7 +6038,7 @@ TryAttachLengthStub(JSContext *cx, JSScript *script, ICGetProp_Fallback *stub, H
return false;
*attached = true;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
return true;
}
@ -6124,7 +6121,7 @@ TryAttachNativeGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc,
if (!newStub)
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
*attached = true;
return true;
}
@ -6155,7 +6152,7 @@ TryAttachNativeGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc,
if (!newStub)
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
*attached = true;
return true;
}
@ -6202,7 +6199,7 @@ TryAttachNativeGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc,
}
if (!newStub)
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
*attached = true;
return true;
}
@ -6222,7 +6219,7 @@ TryAttachNativeGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc,
ICStub *newStub = compiler.getStub(compiler.getStubSpace(script));
if (!newStub)
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
*attached = true;
return true;
}
@ -6277,7 +6274,7 @@ TryAttachPrimitiveGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc
if (!newStub)
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
*attached = true;
return true;
}
@ -6364,7 +6361,7 @@ DoGetPropFallback(JSContext *cx, BaselineFrame *frame, ICGetProp_Fallback *stub,
}
JS_ASSERT(!attached);
stub->noteUnoptimizableAccess(cx);
stub->noteUnoptimizableAccess();
return true;
}
@ -7109,13 +7106,13 @@ ICGetProp_ArgumentsLength::Compiler::generateStubCode(MacroAssembler &masm)
}
void
BaselineScript::noteAccessedGetter(JSContext *cx, uint32_t pcOffset)
BaselineScript::noteAccessedGetter(uint32_t pcOffset)
{
ICEntry &entry = icEntryFromPCOffset(pcOffset);
ICFallbackStub *stub = entry.fallbackStub();
if (stub->isGetProp_Fallback())
stub->toGetProp_Fallback()->noteAccessedGetter(cx);
stub->toGetProp_Fallback()->noteAccessedGetter();
}
//
@ -7156,7 +7153,7 @@ TryAttachSetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc, ICSetPr
if (!newStub->addUpdateStubForValue(cx, script, obj, id, rhs))
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
*attached = true;
return true;
}
@ -7174,7 +7171,7 @@ TryAttachSetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc, ICSetPr
if (!newStub->addUpdateStubForValue(cx, script, obj, id, rhs))
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
*attached = true;
return true;
}
@ -7196,7 +7193,7 @@ TryAttachSetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc, ICSetPr
if (!newStub)
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
*attached = true;
return true;
}
@ -7215,7 +7212,7 @@ TryAttachSetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc, ICSetPr
if (!newStub)
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
*attached = true;
return true;
}
@ -7290,7 +7287,7 @@ DoSetPropFallback(JSContext *cx, BaselineFrame *frame, ICSetProp_Fallback *stub,
return true;
JS_ASSERT(!attached);
stub->noteUnoptimizableAccess(cx);
stub->noteUnoptimizableAccess();
return true;
}
@ -7796,7 +7793,7 @@ TryAttachFunApplyStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script,
if (!newStub)
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
return true;
}
@ -7813,7 +7810,7 @@ TryAttachFunApplyStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script,
if (!newStub)
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
return true;
}
}
@ -7957,7 +7954,7 @@ TryAttachCallStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script, jsb
stub->unlinkStubsWithKind(cx, ICStub::Call_Scripted);
// Add new generalized stub.
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
return true;
}
@ -7986,7 +7983,7 @@ TryAttachCallStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script, jsb
if (!newStub)
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
return true;
}
@ -8023,7 +8020,7 @@ TryAttachCallStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script, jsb
if (!newStub)
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
return true;
}
@ -9155,7 +9152,7 @@ DoIteratorMoreFallback(JSContext *cx, BaselineFrame *frame, ICIteratorMore_Fallb
ICStub *newStub = compiler.getStub(compiler.getStubSpace(frame->script()));
if (!newStub)
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
}
return true;
@ -9229,7 +9226,7 @@ DoIteratorNextFallback(JSContext *cx, BaselineFrame *frame, ICIteratorNext_Fallb
return false;
if (!res.isString() && !stub->hasNonStringResult())
stub->setHasNonStringResult(cx);
stub->setHasNonStringResult();
if (iteratorObject->is<PropertyIteratorObject>() &&
!stub->hasStub(ICStub::IteratorNext_Native))
@ -9238,7 +9235,7 @@ DoIteratorNextFallback(JSContext *cx, BaselineFrame *frame, ICIteratorNext_Fallb
ICStub *newStub = compiler.getStub(compiler.getStubSpace(frame->script()));
if (!newStub)
return false;
stub->addNewStub(cx, newStub);
stub->addNewStub(newStub);
}
return true;
@ -9402,7 +9399,7 @@ DoTypeOfFallback(JSContext *cx, BaselineFrame *frame, ICTypeOf_Fallback *stub, H
ICStub *typeOfStub = compiler.getStub(compiler.getStubSpace(frame->script()));
if (!typeOfStub)
return false;
stub->addNewStub(cx, typeOfStub);
stub->addNewStub(typeOfStub);
}
return true;
@ -9489,7 +9486,7 @@ DoRetSubFallback(JSContext *cx, BaselineFrame *frame, ICRetSub_Fallback *stub,
if (!optStub)
return false;
stub->addNewStub(cx, optStub);
stub->addNewStub(optStub);
return true;
}

View File

@ -835,8 +835,7 @@ class ICFallbackStub : public ICStub
}
// Add a new stub to the IC chain terminated by this fallback stub.
void addNewStub(JSContext *cx, ICStub *stub) {
AutoLockForCompilation lock(cx);
void addNewStub(ICStub *stub) {
JS_ASSERT(*lastStubPtrAddr_ == this);
JS_ASSERT(stub->next() == nullptr);
stub->setNext(this);
@ -2442,15 +2441,13 @@ class ICBinaryArith_Fallback : public ICFallbackStub
bool sawDoubleResult() const {
return extra_ & SAW_DOUBLE_RESULT_BIT;
}
void setSawDoubleResult(JSContext *cx) {
AutoLockForCompilation lock(cx);
void setSawDoubleResult() {
extra_ |= SAW_DOUBLE_RESULT_BIT;
}
bool hadUnoptimizableOperands() const {
return extra_ & UNOPTIMIZABLE_OPERANDS_BIT;
}
void noteUnoptimizableOperands(JSContext *cx) {
AutoLockForCompilation lock(cx);
void noteUnoptimizableOperands() {
extra_ |= UNOPTIMIZABLE_OPERANDS_BIT;
}
@ -2851,16 +2848,14 @@ class ICGetElem_Fallback : public ICMonitoredFallbackStub
return space->allocate<ICGetElem_Fallback>(code);
}
void noteNonNativeAccess(JSContext *cx) {
AutoLockForCompilation lock(cx);
void noteNonNativeAccess() {
extra_ |= EXTRA_NON_NATIVE;
}
bool hasNonNativeAccess() const {
return extra_ & EXTRA_NON_NATIVE;
}
void noteNegativeIndex(JSContext *cx) {
AutoLockForCompilation lock(cx);
void noteNegativeIndex() {
extra_ |= EXTRA_NEGATIVE_INDEX;
}
bool hasNegativeIndex() const {
@ -3448,8 +3443,7 @@ class ICSetElem_Fallback : public ICFallbackStub
return space->allocate<ICSetElem_Fallback>(code);
}
void noteArrayWriteHole(JSContext *cx) {
AutoLockForCompilation lock(cx);
void noteArrayWriteHole() {
extra_ = 1;
}
bool hasArrayWriteHole() const {
@ -4024,16 +4018,14 @@ class ICGetProp_Fallback : public ICMonitoredFallbackStub
static const size_t UNOPTIMIZABLE_ACCESS_BIT = 0;
static const size_t ACCESSED_GETTER_BIT = 1;
void noteUnoptimizableAccess(JSContext *cx) {
AutoLockForCompilation lock(cx);
void noteUnoptimizableAccess() {
extra_ |= (1u << UNOPTIMIZABLE_ACCESS_BIT);
}
bool hadUnoptimizableAccess() const {
return extra_ & (1u << UNOPTIMIZABLE_ACCESS_BIT);
}
void noteAccessedGetter(JSContext *cx) {
AutoLockForCompilation lock(cx);
void noteAccessedGetter() {
extra_ |= (1u << ACCESSED_GETTER_BIT);
}
bool hasAccessedGetter() const {
@ -4840,8 +4832,7 @@ class ICSetProp_Fallback : public ICFallbackStub
}
static const size_t UNOPTIMIZABLE_ACCESS_BIT = 0;
void noteUnoptimizableAccess(JSContext *cx) {
AutoLockForCompilation lock(cx);
void noteUnoptimizableAccess() {
extra_ |= (1u << UNOPTIMIZABLE_ACCESS_BIT);
}
bool hadUnoptimizableAccess() const {
@ -5742,8 +5733,7 @@ class ICIteratorNext_Fallback : public ICFallbackStub
return space->allocate<ICIteratorNext_Fallback>(code);
}
void setHasNonStringResult(JSContext *cx) {
AutoLockForCompilation lock(cx);
void setHasNonStringResult() {
JS_ASSERT(extra_ == 0);
extra_ = 1;
}

View File

@ -18,8 +18,6 @@ using mozilla::DebugOnly;
bool
SetElemICInspector::sawOOBDenseWrite() const
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
if (!icEntry_)
return false;
@ -40,8 +38,6 @@ SetElemICInspector::sawOOBDenseWrite() const
bool
SetElemICInspector::sawOOBTypedArrayWrite() const
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
if (!icEntry_)
return false;
@ -58,8 +54,6 @@ SetElemICInspector::sawOOBTypedArrayWrite() const
bool
SetElemICInspector::sawDenseWrite() const
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
if (!icEntry_)
return false;
@ -74,8 +68,6 @@ SetElemICInspector::sawDenseWrite() const
bool
SetElemICInspector::sawTypedArrayWrite() const
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
if (!icEntry_)
return false;
@ -90,8 +82,6 @@ SetElemICInspector::sawTypedArrayWrite() const
bool
BaselineInspector::maybeShapesForPropertyOp(jsbytecode *pc, ShapeVector &shapes)
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
// Return a list of shapes seen by the baseline IC for the current op.
// An empty list indicates no shapes are known, or there was an uncacheable
// access.
@ -149,8 +139,6 @@ BaselineInspector::maybeShapesForPropertyOp(jsbytecode *pc, ShapeVector &shapes)
ICStub *
BaselineInspector::monomorphicStub(jsbytecode *pc)
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
if (!hasBaselineScript())
return nullptr;
@ -168,8 +156,6 @@ BaselineInspector::monomorphicStub(jsbytecode *pc)
bool
BaselineInspector::dimorphicStub(jsbytecode *pc, ICStub **pfirst, ICStub **psecond)
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
if (!hasBaselineScript())
return false;
@ -190,8 +176,6 @@ BaselineInspector::dimorphicStub(jsbytecode *pc, ICStub **pfirst, ICStub **pseco
MIRType
BaselineInspector::expectedResultType(jsbytecode *pc)
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
// Look at the IC entries for this op to guess what type it will produce,
// returning MIRType_None otherwise.
@ -238,8 +222,6 @@ CanUseInt32Compare(ICStub::Kind kind)
MCompare::CompareType
BaselineInspector::expectedCompareType(jsbytecode *pc)
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
ICStub *first = monomorphicStub(pc), *second = nullptr;
if (!first && !dimorphicStub(pc, &first, &second))
return MCompare::Compare_Unknown;
@ -322,8 +304,6 @@ TryToSpecializeBinaryArithOp(ICStub **stubs,
MIRType
BaselineInspector::expectedBinaryArithSpecialization(jsbytecode *pc)
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
MIRType result;
ICStub *stubs[2];
@ -352,8 +332,6 @@ BaselineInspector::expectedBinaryArithSpecialization(jsbytecode *pc)
bool
BaselineInspector::hasSeenNonNativeGetElement(jsbytecode *pc)
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
if (!hasBaselineScript())
return false;
@ -368,8 +346,6 @@ BaselineInspector::hasSeenNonNativeGetElement(jsbytecode *pc)
bool
BaselineInspector::hasSeenNegativeIndexGetElement(jsbytecode *pc)
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
if (!hasBaselineScript())
return false;
@ -384,8 +360,6 @@ BaselineInspector::hasSeenNegativeIndexGetElement(jsbytecode *pc)
bool
BaselineInspector::hasSeenAccessedGetter(jsbytecode *pc)
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
if (!hasBaselineScript())
return false;
@ -400,8 +374,6 @@ BaselineInspector::hasSeenAccessedGetter(jsbytecode *pc)
bool
BaselineInspector::hasSeenNonStringIterNext(jsbytecode *pc)
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
JS_ASSERT(JSOp(*pc) == JSOP_ITERNEXT);
if (!hasBaselineScript())
@ -416,8 +388,6 @@ BaselineInspector::hasSeenNonStringIterNext(jsbytecode *pc)
bool
BaselineInspector::hasSeenDoubleResult(jsbytecode *pc)
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
if (!hasBaselineScript())
return false;
@ -437,8 +407,6 @@ BaselineInspector::hasSeenDoubleResult(jsbytecode *pc)
JSObject *
BaselineInspector::getTemplateObject(jsbytecode *pc)
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
if (!hasBaselineScript())
return nullptr;
@ -466,8 +434,6 @@ BaselineInspector::getTemplateObject(jsbytecode *pc)
JSObject *
BaselineInspector::getTemplateObjectForNative(jsbytecode *pc, Native native)
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
if (!hasBaselineScript())
return nullptr;
@ -501,8 +467,6 @@ BaselineInspector::templateCallObject()
JSObject *
BaselineInspector::commonGetPropFunction(jsbytecode *pc, Shape **lastProperty, JSFunction **commonGetter)
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
const ICEntry &entry = icEntryFromPC(pc);
for (ICStub *stub = entry.firstStub(); stub; stub = stub->next()) {
if (stub->isGetProp_CallScripted() || stub->isGetProp_CallNative()) {
@ -518,8 +482,6 @@ BaselineInspector::commonGetPropFunction(jsbytecode *pc, Shape **lastProperty, J
JSObject *
BaselineInspector::commonSetPropFunction(jsbytecode *pc, Shape **lastProperty, JSFunction **commonSetter)
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
const ICEntry &entry = icEntryFromPC(pc);
for (ICStub *stub = entry.firstStub(); stub; stub = stub->next()) {
if (stub->isSetProp_CallScripted() || stub->isSetProp_CallNative()) {

View File

@ -294,8 +294,8 @@ struct BaselineScript
void toggleSPS(bool enable);
void noteAccessedGetter(JSContext *cx, uint32_t pcOffset);
void noteArrayWriteHole(JSContext *cx, uint32_t pcOffset);
void noteAccessedGetter(uint32_t pcOffset);
void noteArrayWriteHole(uint32_t pcOffset);
static size_t offsetOfFlags() {
return offsetof(BaselineScript, flags_);

View File

@ -3568,7 +3568,6 @@ CodeGenerator::visitNewCallObject(LNewCallObject *lir)
Register obj = ToRegister(lir->output());
JSObject *templateObj = lir->mir()->templateObject();
AutoThreadSafeAccess ts(templateObj);
// If we have a template object, we can inline call object creation.
OutOfLineCode *ool;

View File

@ -252,15 +252,6 @@ CompileCompartment::setSingletonsAsValues()
return JS::CompartmentOptionsRef(compartment()).setSingletonsAsValues();
}
#ifdef JS_THREADSAFE
AutoLockForCompilation::AutoLockForCompilation(CompileCompartment *compartment
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
init(compartment->compartment()->runtimeFromAnyThread());
}
#endif
JitCompileOptions::JitCompileOptions()
: cloneSingletons_(false),
spsSlowAssertionsEnabled_(false)

View File

@ -102,8 +102,6 @@ class CompileCompartment
{
JSCompartment *compartment();
friend class js::AutoLockForCompilation;
public:
static CompileCompartment *get(JSCompartment *comp);

View File

@ -52,7 +52,6 @@
using namespace js;
using namespace js::jit;
using mozilla::Maybe;
using mozilla::ThreadLocal;
// Assert that JitCode is gc::Cell aligned.
@ -492,8 +491,6 @@ JitCompartment::ensureIonStubsExist(JSContext *cx)
void
jit::FinishOffThreadBuilder(IonBuilder *builder)
{
builder->script()->runtimeFromMainThread()->removeCompilationThread();
ExecutionMode executionMode = builder->info().executionMode();
// Clear the recompiling flag if it would have failed.
@ -1565,9 +1562,6 @@ AttachFinishedCompilations(JSContext *cx)
// operation callback and can't propagate failures.
cx->clearPendingException();
}
} else {
if (builder->abortReason() == AbortReason_Disable)
SetIonScript(builder->script(), builder->info().executionMode(), ION_DISABLED_SCRIPT);
}
FinishOffThreadBuilder(builder);
@ -1722,6 +1716,14 @@ IonCompile(JSContext *cx, JSScript *script,
builderScript->ionScript()->setRecompiling();
}
IonSpewNewFunction(graph, builderScript);
bool succeeded = builder->build();
builder->clearForBackEnd();
if (!succeeded)
return builder->abortReason();
// If possible, compile the script off thread.
if (OffThreadCompilationAvailable(cx)) {
if (!recompile)
@ -1742,42 +1744,12 @@ IonCompile(JSContext *cx, JSScript *script,
return AbortReason_NoAbort;
}
Maybe<AutoEnterIonCompilation> ionCompiling;
if (!cx->runtime()->profilingScripts && !IonSpewEnabled(IonSpew_Logs)) {
// Compilation with script profiling is only done on the main thread,
// and may modify scripts directly. Same for logging. It is only
// enabled when offthread compilation is disabled. So don't watch for
// proper use of the compilation lock.
ionCompiling.construct();
}
Maybe<AutoProtectHeapForIonCompilation> protect;
if (js_JitOptions.checkThreadSafety &&
cx->runtime()->gcIncrementalState == gc::NO_INCREMENTAL &&
!cx->runtime()->profilingScripts)
{
protect.construct(cx->runtime());
}
IonSpewNewFunction(graph, builderScript);
bool succeeded = builder->build();
builder->clearForBackEnd();
if (!succeeded)
return builder->abortReason();
ScopedJSDeletePtr<CodeGenerator> codegen(CompileBackEnd(builder));
if (!codegen) {
IonSpew(IonSpew_Abort, "Failed during back-end compilation.");
return AbortReason_Disable;
}
if (!protect.empty())
protect.destroy();
if (!ionCompiling.empty())
ionCompiling.destroy();
bool success = codegen->link(cx, builder->constraints());
IonSpewEndFunction();

View File

@ -140,21 +140,13 @@ IonBuilder::IonBuilder(JSContext *analysisContext, CompileCompartment *comp,
script_ = info->script();
pc = info->startPC();
#ifdef DEBUG
lock();
JS_ASSERT(script()->hasBaselineScript());
unlock();
#endif
JS_ASSERT(!!analysisContext == (info->executionMode() == DefinitePropertiesAnalysis));
}
void
IonBuilder::clearForBackEnd()
{
// This case should only be hit if there was a failure while building.
if (!lock_.empty())
lock_.destroy();
JS_ASSERT(!analysisContext);
baselineFrame_ = nullptr;
@ -292,8 +284,6 @@ IonBuilder::getPolyCallTargets(types::TemporaryTypeSet *calleeTypes, bool constr
fun = &obj->as<JSFunction>();
} else {
types::TypeObject *typeObj = calleeTypes->getTypeObject(i);
AutoThreadSafeAccess ts(typeObj);
JS_ASSERT(typeObj);
if (!typeObj->interpretedFunction) {
targets.clear();
@ -593,16 +583,12 @@ IonBuilder::pushLoop(CFGState::State initial, jsbytecode *stopAt, MBasicBlock *e
bool
IonBuilder::init()
{
lock();
if (!types::TypeScript::FreezeTypeSets(constraints(), script(),
&thisTypes, &argTypes, &typeArray))
{
return false;
}
unlock();
if (!analysis().init(alloc(), gsn))
return false;
@ -721,8 +707,6 @@ IonBuilder::build()
if (!traverseBytecode())
return false;
unlock();
if (!maybeAddOsrTypeBarriers())
return false;
@ -882,7 +866,6 @@ IonBuilder::buildInline(IonBuilder *callerBuilder, MResumePoint *callerResumePoi
if (!traverseBytecode())
return false;
unlock();
return true;
}
@ -937,9 +920,6 @@ IonBuilder::initParameters()
// interpreter and didn't accumulate type information, try to use that OSR
// frame to determine possible initial types for 'this' and parameters.
// For unknownProperties() tests under addType.
lock();
if (thisTypes->empty() && baselineFrame_) {
if (!thisTypes->addType(baselineFrame_->thisType, alloc_->lifoAlloc()))
return false;
@ -963,8 +943,6 @@ IonBuilder::initParameters()
current->initSlot(info().argSlotUnchecked(i), param);
}
unlock();
return true;
}
@ -987,8 +965,6 @@ IonBuilder::initScopeChain(MDefinition *callee)
if (!script()->compileAndGo())
return abort("non-CNG global scripts are not supported");
lock();
if (JSFunction *fun = info().funMaybeLazy()) {
if (!callee) {
MCallee *calleeIns = MCallee::New(alloc());
@ -1014,8 +990,6 @@ IonBuilder::initScopeChain(MDefinition *callee)
scope = constant(ObjectValue(script()->global()));
}
unlock();
current->setScopeChain(scope);
return true;
}
@ -1209,14 +1183,6 @@ IonBuilder::maybeAddOsrTypeBarriers()
bool
IonBuilder::traverseBytecode()
{
// Always hold the compilation lock when traversing bytecode, though release
// it before reacquiring it every few opcodes so that the main thread does not
// block for long when updating compilation data.
lock();
size_t lockOpcodeCount = 0;
static const size_t LOCK_OPCODE_GRANULARITY = 5;
for (;;) {
JS_ASSERT(pc < info().limitPC());
@ -1291,12 +1257,6 @@ IonBuilder::traverseBytecode()
if (!inspectOpcode(op))
return false;
if (++lockOpcodeCount == LOCK_OPCODE_GRANULARITY) {
unlock();
lock();
lockOpcodeCount = 0;
}
#ifdef DEBUG
for (size_t i = 0; i < popped.length(); i++) {
switch (op) {
@ -3881,21 +3841,17 @@ IonBuilder::inlineScriptedCall(CallInfo &callInfo, JSFunction *target)
JSScript *calleeScript = target->nonLazyScript();
BaselineInspector inspector(calleeScript);
// Improve type information of |this| when not set.
if (callInfo.constructing() &&
!callInfo.thisArg()->resultTypeSet() &&
calleeScript->types)
{
AutoThreadSafeAccess ts(calleeScript);
// Improve type information of |this| when not set.
if (callInfo.constructing() &&
!callInfo.thisArg()->resultTypeSet() &&
calleeScript->types)
{
types::StackTypeSet *types = types::TypeScript::ThisTypes(calleeScript);
if (!types->unknown()) {
MTypeBarrier *barrier =
MTypeBarrier::New(alloc(), callInfo.thisArg(), types->clone(alloc_->lifoAlloc()));
current->add(barrier);
callInfo.setThis(barrier);
}
types::StackTypeSet *types = types::TypeScript::ThisTypes(calleeScript);
if (!types->unknown()) {
MTypeBarrier *barrier =
MTypeBarrier::New(alloc(), callInfo.thisArg(), types->clone(alloc_->lifoAlloc()));
current->add(barrier);
callInfo.setThis(barrier);
}
}
@ -3911,8 +3867,6 @@ IonBuilder::inlineScriptedCall(CallInfo &callInfo, JSFunction *target)
MIRGraphReturns returns(alloc());
AutoAccumulateReturns aar(graph(), returns);
unlock();
// Build the graph.
IonBuilder inlineBuilder(analysisContext, compartment, options, &alloc(), &graph(), constraints(),
&inspector, info, &optimizationInfo(), nullptr, inliningDepth_ + 1,
@ -3927,7 +3881,6 @@ IonBuilder::inlineScriptedCall(CallInfo &callInfo, JSFunction *target)
// Inlining the callee failed. Mark the callee as uninlineable only if
// the inlining was aborted for a non-exception reason.
if (inlineBuilder.abortReason_ == AbortReason_Disable) {
AutoThreadSafeAccess ts(calleeScript);
calleeScript->setUninlineable();
abortReason_ = AbortReason_Inlining;
} else if (inlineBuilder.abortReason_ == AbortReason_Inlining) {
@ -3937,8 +3890,6 @@ IonBuilder::inlineScriptedCall(CallInfo &callInfo, JSFunction *target)
return false;
}
lock();
// Create return block.
jsbytecode *postCall = GetNextPc(pc);
MBasicBlock *returnBlock = newBlock(nullptr, postCall);
@ -3957,7 +3908,6 @@ IonBuilder::inlineScriptedCall(CallInfo &callInfo, JSFunction *target)
// Accumulate return values.
if (returns.empty()) {
// Inlining of functions that have no exit is not supported.
AutoThreadSafeAccess ts(calleeScript);
calleeScript->setUninlineable();
abortReason_ = AbortReason_Inlining;
return false;
@ -4618,7 +4568,6 @@ IonBuilder::createDeclEnvObject(MDefinition *callee, MDefinition *scope)
// Get a template CallObject that we'll use to generate inline object
// creation.
DeclEnvObject *templateObj = inspector->templateDeclEnvObject();
AutoThreadSafeAccess ts(templateObj);
// One field is added to the function to handle its name. This cannot be a
// dynamic slot because there is still plenty of room on the DeclEnv object.
@ -4646,12 +4595,11 @@ IonBuilder::createCallObject(MDefinition *callee, MDefinition *scope)
// Get a template CallObject that we'll use to generate inline object
// creation.
CallObject *templateObj = inspector->templateCallObject();
AutoThreadSafeAccess ts(templateObj);
// If the CallObject needs dynamic slots, allocate those now.
MInstruction *slots;
if (templateObj->hasDynamicSlots()) {
size_t nslots = JSObject::dynamicSlotsCount(templateObj->numFixedSlotsForCompilation(),
size_t nslots = JSObject::dynamicSlotsCount(templateObj->numFixedSlots(),
templateObj->lastProperty()->slotSpan(templateObj->getClass()),
templateObj->getClass());
slots = MNewSlots::New(alloc(), nslots);
@ -4677,8 +4625,8 @@ IonBuilder::createCallObject(MDefinition *callee, MDefinition *scope)
unsigned slot = i.scopeSlot();
unsigned formal = i.frameIndex();
MDefinition *param = current->getSlot(info().argSlotUnchecked(formal));
if (slot >= templateObj->numFixedSlotsForCompilation())
current->add(MStoreSlot::New(alloc(), slots, slot - templateObj->numFixedSlotsForCompilation(), param));
if (slot >= templateObj->numFixedSlots())
current->add(MStoreSlot::New(alloc(), slots, slot - templateObj->numFixedSlots(), param));
else
current->add(MStoreFixedSlot::New(alloc(), callObj, slot, param));
}
@ -4750,13 +4698,10 @@ IonBuilder::createThisScriptedSingleton(JSFunction *target, MDefinition *callee)
if (!templateObject->hasTenuredProto() || templateObject->getProto() != proto)
return nullptr;
{
AutoThreadSafeAccess ts(target->nonLazyScript());
if (!target->nonLazyScript()->types)
return nullptr;
if (!types::TypeScript::ThisTypes(target->nonLazyScript())->hasType(types::Type::ObjectType(templateObject)))
return nullptr;
}
if (!target->nonLazyScript()->types)
return nullptr;
if (!types::TypeScript::ThisTypes(target->nonLazyScript())->hasType(types::Type::ObjectType(templateObject)))
return nullptr;
// For template objects with NewScript info, the appropriate allocation
// kind to use may change due to dynamic property adds. In these cases
@ -5157,8 +5102,6 @@ IonBuilder::testNeedsArgumentCheck(JSFunction *target, CallInfo &callInfo)
JSScript *targetScript = target->nonLazyScript();
AutoThreadSafeAccess ts(targetScript);
if (!targetScript->types)
return true;
@ -5357,7 +5300,6 @@ IonBuilder::jsop_eval(uint32_t argc)
string->getOperand(1)->toConstant()->value().isString())
{
JSAtom *atom = &string->getOperand(1)->toConstant()->value().toString()->asAtom();
AutoThreadSafeAccess ts(atom);
if (StringEqualsAscii(atom, "()")) {
MDefinition *name = string->getOperand(0);
@ -5431,7 +5373,6 @@ IonBuilder::jsop_newarray(uint32_t count)
types::TemporaryTypeSet::DoubleConversion conversion =
ins->resultTypeSet()->convertDoubleElements(constraints());
AutoThreadSafeAccess ts(templateObject);
if (conversion == types::TemporaryTypeSet::AlwaysConvertToDoubles)
templateObject->setShouldConvertDoubleElements();
else
@ -5514,7 +5455,6 @@ IonBuilder::jsop_initelem_array()
current->add(elements);
JSObject *templateObject = obj->toNewArray()->templateObject();
AutoThreadSafeAccess ts(templateObject);
if (templateObject->shouldConvertDoubleElements()) {
MInstruction *valueDouble = MToDouble::New(alloc(), value);
@ -5556,7 +5496,6 @@ IonBuilder::jsop_initprop(PropertyName *name)
MDefinition *obj = current->peek(-1);
JSObject *templateObject = obj->toNewObject()->templateObject();
AutoThreadSafeAccess ts(templateObject);
Shape *shape = templateObject->lastProperty()->searchLinear(NameToId(name));
@ -9179,9 +9118,6 @@ IonBuilder::jsop_regexp(RegExpObject *reobj)
// then check if this regex object only flows into known natives and can
// avoid cloning in this case.
// RegExpObjects embedded in scripts are immutable.
AutoThreadSafeAccess ts(reobj);
bool mustClone = true;
types::TypeObjectKey *typeObj = types::TypeObjectKey::get(&script()->global());
if (!typeObj->hasFlags(constraints(), types::OBJECT_FLAG_REGEXP_FLAGS_SET)) {

View File

@ -787,17 +787,6 @@ class IonBuilder : public MIRGenerator
// Constraints for recording dependencies on type information.
types::CompilerConstraintList *constraints_;
mozilla::Maybe<AutoLockForCompilation> lock_;
void lock() {
if (!analysisContext)
lock_.construct(compartment);
}
void unlock() {
if (!analysisContext)
lock_.destroy();
}
// Basic analysis information about the script.
BytecodeAnalysis analysis_;
BytecodeAnalysis &analysis() {

View File

@ -82,7 +82,6 @@ class JitCode : public gc::BarrieredCell<JitCode>
public:
uint8_t *raw() const {
AutoThreadSafeAccess ts(this);
return code_;
}
size_t instructionsSize() const {

View File

@ -787,10 +787,6 @@ MacroAssembler::initGCThing(const Register &obj, JSObject *templateObject)
{
// Fast initialization of an empty object returned by NewGCThing().
AutoThreadSafeAccess ts0(templateObject);
AutoThreadSafeAccess ts1(templateObject->lastProperty());
AutoThreadSafeAccess ts2(templateObject->lastProperty()->base()); // For isNative() assertions.
JS_ASSERT(!templateObject->hasDynamicElements());
storePtr(ImmGCPtr(templateObject->lastProperty()), Address(obj, JSObject::offsetOfShape()));
@ -822,7 +818,7 @@ MacroAssembler::initGCThing(const Register &obj, JSObject *templateObject)
// Fixed slots of non-array objects are required to be initialized.
// Use the values currently in the template object.
size_t nslots = Min(templateObject->numFixedSlotsForCompilation(),
size_t nslots = Min(templateObject->numFixedSlots(),
templateObject->lastProperty()->slotSpan(templateObject->getClass()));
for (unsigned i = 0; i < nslots; i++) {
storeValue(templateObject->getFixedSlot(i),

View File

@ -33,10 +33,6 @@ JitOptions::JitOptions()
// RangeAnalysis results.
checkRangeAnalysis = false;
// Whether to protect the GC heap during Ion compilation and ensure that
// only threadsafe operations are performed on it.
checkThreadSafety = false;
// Whether Ion should compile try-catch statements.
compileTryCatch = true;

View File

@ -45,7 +45,6 @@ struct JitOptions
bool checkOsiPointRegisters;
#endif
bool checkRangeAnalysis;
bool checkThreadSafety;
bool compileTryCatch;
bool disableGvn;
bool disableLicm;

View File

@ -257,13 +257,10 @@ IonBuilder::inlineArray(CallInfo &callInfo)
types::TemporaryTypeSet::DoubleConversion conversion =
getInlineReturnTypeSet()->convertDoubleElements(constraints());
{
AutoThreadSafeAccess ts(templateObject);
if (conversion == types::TemporaryTypeSet::AlwaysConvertToDoubles)
templateObject->setShouldConvertDoubleElements();
else
templateObject->clearShouldConvertDoubleElements();
}
if (conversion == types::TemporaryTypeSet::AlwaysConvertToDoubles)
templateObject->setShouldConvertDoubleElements();
else
templateObject->clearShouldConvertDoubleElements();
MNewArray *ins = MNewArray::New(alloc(), constraints(), initLength, templateObject,
templateObject->type()->initialHeap(constraints()),

View File

@ -788,8 +788,6 @@ MStringLength::foldsTo(TempAllocator &alloc, bool useValueNumbers)
if ((type() == MIRType_Int32) && (string()->isConstant())) {
Value value = string()->toConstant()->value();
JSAtom *atom = &value.toString()->asAtom();
AutoThreadSafeAccess ts(atom);
return MConstant::New(alloc, Int32Value(atom->length()));
}
@ -2607,7 +2605,6 @@ MBeta::printOpcode(FILE *fp) const
bool
MNewObject::shouldUseVM() const
{
AutoThreadSafeAccess ts(templateObject());
return templateObject()->hasSingletonType() ||
templateObject()->hasDynamicSlots();
}

View File

@ -279,7 +279,6 @@ CodeGeneratorShared::encode(LSnapshot *snapshot)
#ifdef DEBUG
if (GetIonContext()->cx) {
AutoThreadSafeAccess ts(script);
uint32_t stackDepth;
bool reachablePC;
if (!ReconstructStackDepth(GetIonContext()->cx, script, bailPC, &stackDepth, &reachablePC))

View File

@ -31,7 +31,6 @@ namespace js {
inline jsid
AtomToId(JSAtom *atom)
{
AutoThreadSafeAccess ts(atom);
JS_STATIC_ASSERT(JSID_INT_MIN == 0);
uint32_t index;

View File

@ -29,8 +29,6 @@ BooleanGetPrimitiveValue(HandleObject obj, JSContext *cx)
inline bool
EmulatesUndefined(JSObject *obj)
{
AutoThreadSafeAccess ts0(obj);
AutoThreadSafeAccess ts1(obj->typeRaw());
JSObject *actual = MOZ_LIKELY(!obj->is<WrapperObject>()) ? obj : UncheckedUnwrap(obj);
return actual->getClass()->emulatesUndefined();
}

View File

@ -116,7 +116,6 @@ js::ExistingCloneFunctionAtCallsite(const CallsiteCloneTable &table, JSFunction
JS_ASSERT(fun->nonLazyScript()->shouldCloneAtCallsite());
JS_ASSERT(!fun->nonLazyScript()->enclosingStaticScope());
JS_ASSERT(types::UseNewTypeForClone(fun));
JS_ASSERT(CurrentThreadCanReadCompilationData());
/*
* If we start allocating function objects in the nursery, then the callsite
@ -154,8 +153,6 @@ js::CloneFunctionAtCallsite(JSContext *cx, HandleFunction fun, HandleScript scri
typedef CallsiteCloneKey Key;
typedef CallsiteCloneTable Table;
AutoLockForCompilation lock(cx);
Table &table = cx->compartment()->callsiteClones;
if (!table.initialized() && !table.init())
return nullptr;

View File

@ -1087,69 +1087,6 @@ class AutoLockForExclusiveAccess
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
class AutoLockForCompilation
{
#ifdef JS_THREADSAFE
JSRuntime *runtime;
void init(JSRuntime *rt) {
runtime = rt;
if (runtime->numCompilationThreads) {
runtime->assertCanLock(CompilationLock);
PR_Lock(runtime->compilationLock);
#ifdef DEBUG
runtime->compilationLockOwner = PR_GetCurrentThread();
#endif
} else {
#ifdef DEBUG
JS_ASSERT(!runtime->mainThreadHasCompilationLock);
runtime->mainThreadHasCompilationLock = true;
#endif
}
}
public:
AutoLockForCompilation(ExclusiveContext *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
if (cx->isJSContext())
init(cx->asJSContext()->runtime());
else
runtime = nullptr;
}
AutoLockForCompilation(jit::CompileCompartment *compartment MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
~AutoLockForCompilation() {
if (runtime) {
if (runtime->numCompilationThreads) {
JS_ASSERT(runtime->compilationLockOwner == PR_GetCurrentThread());
#ifdef DEBUG
runtime->compilationLockOwner = nullptr;
#endif
PR_Unlock(runtime->compilationLock);
} else {
#ifdef DEBUG
JS_ASSERT(runtime->mainThreadHasCompilationLock);
runtime->mainThreadHasCompilationLock = false;
#endif
}
}
}
#else // JS_THREADSAFE
public:
AutoLockForCompilation(ExclusiveContext *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
}
AutoLockForCompilation(jit::CompileCompartment *compartment MOZ_GUARD_OBJECT_NOTIFIER_PARAM) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
}
~AutoLockForCompilation() {
// An empty destructor is needed to avoid warnings from clang about
// unused local variables of this type.
}
#endif // JS_THREADSAFE
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
} /* namespace js */
#ifdef _MSC_VER

View File

@ -22,14 +22,7 @@ JSCompartment::initGlobal(js::GlobalObject &global)
js::GlobalObject *
JSCompartment::maybeGlobal() const
{
#ifdef DEBUG
if (global_) {
js::AutoThreadSafeAccess ts0(global_);
js::AutoThreadSafeAccess ts1(global_->lastProperty());
js::AutoThreadSafeAccess ts2(global_->lastProperty()->base());
JS_ASSERT(global_->compartment() == this);
}
#endif
JS_ASSERT_IF(global_, global_->compartment() == this);
return global_;
}

View File

@ -1150,7 +1150,6 @@ JSFunction::createScriptForLazilyInterpretedFunction(JSContext *cx, HandleFuncti
RootedScript script(cx, lazy->maybeScript());
if (script) {
AutoLockForCompilation lock(cx);
fun->setUnlazifiedScript(script);
// Remember the lazy script on the compiled script, so it can be
// stored on the function again in case of re-lazification.
@ -1167,7 +1166,6 @@ JSFunction::createScriptForLazilyInterpretedFunction(JSContext *cx, HandleFuncti
if (!script)
return false;
AutoLockForCompilation lock(cx);
fun->setUnlazifiedScript(script);
return true;
}
@ -1196,10 +1194,7 @@ JSFunction::createScriptForLazilyInterpretedFunction(JSContext *cx, HandleFuncti
fun->initAtom(script->functionNonDelazifying()->displayAtom());
clonedScript->setFunction(fun);
{
AutoLockForCompilation lock(cx);
fun->setUnlazifiedScript(clonedScript);
}
fun->setUnlazifiedScript(clonedScript);
CallNewScriptHook(cx, clonedScript, fun);

View File

@ -105,12 +105,10 @@ class JSFunction : public JSObject
}
size_t nargs() const {
js::AutoThreadSafeAccess ts(this);
return nargs_;
}
uint16_t flags() const {
js::AutoThreadSafeAccess ts(this);
return flags_;
}
@ -134,14 +132,10 @@ class JSFunction : public JSObject
return flags() & SH_WRAPPABLE;
}
// Functions can change between being lazily interpreted and having scripts
// when under the compilation lock.
bool isInterpretedLazy() const {
JS_ASSERT(js::CurrentThreadCanReadCompilationData());
return flags() & INTERPRETED_LAZY;
}
bool hasScript() const {
JS_ASSERT(js::CurrentThreadCanReadCompilationData());
return flags() & INTERPRETED;
}
@ -238,7 +232,6 @@ class JSFunction : public JSObject
void initAtom(JSAtom *atom) { atom_.init(atom); }
JSAtom *displayAtom() const {
js::AutoThreadSafeAccess ts(this);
return atom_;
}
@ -258,7 +251,6 @@ class JSFunction : public JSObject
* activations (stack frames) of the function.
*/
JSObject *environment() const {
js::AutoThreadSafeAccess ts(this);
JS_ASSERT(isInterpreted());
return u.i.env_;
}
@ -332,8 +324,6 @@ class JSFunction : public JSObject
}
JSScript *nonLazyScript() const {
js::AutoThreadSafeAccess ts(this);
JS_ASSERT(js::CurrentThreadCanReadCompilationData());
JS_ASSERT(hasScript());
JS_ASSERT(u.i.s.script_);
return u.i.s.script_;
@ -355,16 +345,12 @@ class JSFunction : public JSObject
}
js::LazyScript *lazyScript() const {
js::AutoThreadSafeAccess ts(this);
JS_ASSERT(isInterpretedLazy() && u.i.s.lazy_);
JS_ASSERT(js::CurrentThreadCanReadCompilationData());
return u.i.s.lazy_;
}
js::LazyScript *lazyScriptOrNull() const {
js::AutoThreadSafeAccess ts(this);
JS_ASSERT(isInterpretedLazy());
JS_ASSERT(js::CurrentThreadCanReadCompilationData());
return u.i.s.lazy_;
}
@ -398,7 +384,6 @@ class JSFunction : public JSObject
void setUnlazifiedScript(JSScript *script) {
// Note: createScriptForLazilyInterpretedFunction triggers a barrier on
// lazy script before it is overwritten here.
JS_ASSERT(js::CurrentThreadCanWriteCompilationData());
JS_ASSERT(isInterpretedLazy());
if (!lazyScript()->maybeScript())
lazyScript()->initScript(script);
@ -415,7 +400,6 @@ class JSFunction : public JSObject
}
JSNative native() const {
js::AutoThreadSafeAccess ts(this);
JS_ASSERT(isNative());
return u.n.native;
}
@ -440,7 +424,6 @@ class JSFunction : public JSObject
}
const JSJitInfo *jitInfo() const {
js::AutoThreadSafeAccess ts(this);
JS_ASSERT(isNative());
return u.n.jitinfo;
}

View File

@ -688,9 +688,6 @@ TypeScript::FreezeTypeSets(CompilerConstraintList *constraints, JSScript *script
TemporaryTypeSet **pArgTypes,
TemporaryTypeSet **pBytecodeTypes)
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
AutoThreadSafeAccess ts(script);
LifoAlloc *alloc = constraints->alloc();
StackTypeSet *existing = script->types->typeArray();
@ -810,7 +807,6 @@ TypeObjectKey::proto()
bool
ObjectImpl::hasTenuredProto() const
{
AutoThreadSafeAccess ts(this);
return type_->hasTenuredProto();
}
@ -856,7 +852,6 @@ HeapTypeSetKey
TypeObjectKey::property(jsid id)
{
JS_ASSERT(!unknownProperties());
JS_ASSERT(CurrentThreadCanReadCompilationData());
HeapTypeSetKey property;
property.object_ = this;
@ -1513,10 +1508,8 @@ ObjectStateChange(ExclusiveContext *cxArg, TypeObject *object, bool markingUnkno
HeapTypeSet *types = object->maybeGetProperty(JSID_EMPTY);
/* Mark as unknown after getting the types, to avoid assertion. */
if (markingUnknown) {
AutoLockForCompilation lock(cxArg);
if (markingUnknown)
object->addFlags(OBJECT_FLAG_DYNAMIC_MASK | OBJECT_FLAG_UNKNOWN_PROPERTIES);
}
if (types) {
if (JSContext *cx = cxArg->maybeJSContext()) {
@ -2336,7 +2329,6 @@ TypeCompartment::markSetsUnknown(JSContext *cx, TypeObject *target)
}
}
AutoLockForCompilation lock(cx);
target->addFlags(OBJECT_FLAG_SETS_MARKED_UNKNOWN);
}
@ -2756,28 +2748,9 @@ TypeCompartment::newTypedObject(JSContext *cx, IdValuePair *properties, size_t n
// TypeObject
/////////////////////////////////////////////////////////////////////
#ifdef DEBUG
void
TypeObject::assertCanAccessProto() const
{
// The proto pointer for type objects representing singletons may move.
JS_ASSERT_IF(singleton(), CurrentThreadCanReadCompilationData());
// Any proto pointer which is in the nursery may be moved, and may not be
// accessed during off thread compilation.
#if defined(JSGC_GENERATIONAL) && defined(JS_THREADSAFE)
PerThreadData *pt = TlsPerThreadData.get();
TaggedProto proto(proto_);
JS_ASSERT_IF(proto.isObject() && !proto.toObject()->isTenured(),
!pt || !pt->ionCompiling);
#endif
}
#endif // DEBUG
void
TypeObject::setProto(JSContext *cx, TaggedProto proto)
{
JS_ASSERT(CurrentThreadCanWriteCompilationData());
JS_ASSERT(singleton());
if (proto.isObject() && IsInsideNursery(cx->runtime(), proto.toObject()))
@ -3056,10 +3029,7 @@ TypeObject::setFlags(ExclusiveContext *cx, TypeObjectFlags flags)
singleton()->lastProperty()->hasObjectFlag(BaseShape::ITERATED_SINGLETON));
}
{
AutoLockForCompilation lock(cx);
addFlags(flags);
}
addFlags(flags);
InferSpew(ISpewOps, "%s: setFlags 0x%x", TypeObjectString(this), flags);
@ -3104,10 +3074,8 @@ void
TypeObject::clearAddendum(ExclusiveContext *cx)
{
JS_ASSERT(!(flags() & OBJECT_FLAG_ADDENDUM_CLEARED));
{
AutoLockForCompilation lock(cx);
addFlags(OBJECT_FLAG_ADDENDUM_CLEARED);
}
addFlags(OBJECT_FLAG_ADDENDUM_CLEARED);
/*
* It is possible for the object to not have a new script or other
@ -3521,10 +3489,7 @@ CheckNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun)
#endif
new (newScript) TypeNewScript();
{
AutoLockForCompilation lock(cx);
type->setAddendum(newScript);
}
type->setAddendum(newScript);
if (!newScript) {
cx->compartment()->types.setPendingNukeTypes(cx);
@ -3692,10 +3657,7 @@ JSScript::makeTypes(JSContext *cx)
for (unsigned i = 0; i < count; i++)
new (&typeArray[i]) StackTypeSet();
{
AutoLockForCompilation lock(cx);
types = typeScript;
}
types = typeScript;
#ifdef DEBUG
for (unsigned i = 0; i < nTypeSets(); i++) {
@ -3825,12 +3787,8 @@ JSObject::splicePrototype(JSContext *cx, const Class *clasp, Handle<TaggedProto>
return true;
}
{
AutoLockForCompilation lock(cx);
type->setClasp(clasp);
type->setProto(cx, proto);
}
type->setClasp(clasp);
type->setProto(cx, proto);
return true;
}
@ -3883,10 +3841,7 @@ JSObject::makeLazyType(JSContext *cx, HandleObject obj)
if (obj->is<JSFunction>() && obj->as<JSFunction>().isInterpreted())
type->interpretedFunction = &obj->as<JSFunction>();
{
AutoLockForCompilation lock(cx);
obj->type_ = type;
}
obj->type_ = type;
return type;
}
@ -4628,7 +4583,6 @@ TypeScript::printTypes(JSContext *cx, HandleScript script) const
void
TypeObject::setAddendum(TypeObjectAddendum *addendum)
{
JS_ASSERT(CurrentThreadCanWriteCompilationData());
this->addendum = addendum;
}

View File

@ -27,11 +27,6 @@ namespace js {
class TypeDescr;
#ifdef DEBUG
bool CurrentThreadCanWriteCompilationData();
bool CurrentThreadCanReadCompilationData();
#endif
class TaggedProto
{
public:
@ -890,12 +885,6 @@ struct TypeObject : gc::BarrieredCell<TypeObject>
/* Prototype shared by objects using this type. */
HeapPtrObject proto_;
#ifdef DEBUG
void assertCanAccessProto() const;
#else
void assertCanAccessProto() const {}
#endif
/*
* Whether there is a singleton JS object with this type. That JS object
* must appear in type sets instead of this; we include the back reference
@ -906,24 +895,19 @@ struct TypeObject : gc::BarrieredCell<TypeObject>
public:
const Class *clasp() const {
AutoThreadSafeAccess ts(this);
return clasp_;
}
void setClasp(const Class *clasp) {
JS_ASSERT(CurrentThreadCanWriteCompilationData());
JS_ASSERT(singleton());
clasp_ = clasp;
}
TaggedProto proto() const {
AutoThreadSafeAccess ts(this);
assertCanAccessProto();
return TaggedProto(proto_);
}
JSObject *singleton() const {
AutoThreadSafeAccess ts(this);
return singleton_;
}
@ -965,42 +949,30 @@ struct TypeObject : gc::BarrieredCell<TypeObject>
public:
TypeObjectFlags flags() const {
JS_ASSERT(CurrentThreadCanReadCompilationData());
AutoThreadSafeAccess ts(this);
return flags_;
}
void addFlags(TypeObjectFlags flags) {
JS_ASSERT(CurrentThreadCanWriteCompilationData());
flags_ |= flags;
}
void clearFlags(TypeObjectFlags flags) {
JS_ASSERT(CurrentThreadCanWriteCompilationData());
flags_ &= ~flags;
}
bool hasNewScript() const {
JS_ASSERT(CurrentThreadCanReadCompilationData());
AutoThreadSafeAccess ts(this);
return addendum && addendum->isNewScript();
}
TypeNewScript *newScript() {
JS_ASSERT(CurrentThreadCanReadCompilationData());
AutoThreadSafeAccess ts(this);
return addendum->asNewScript();
}
bool hasTypedObject() {
JS_ASSERT(CurrentThreadCanReadCompilationData());
AutoThreadSafeAccess ts(this);
return addendum && addendum->isTypedObject();
}
TypeTypedObject *typedObject() {
JS_ASSERT(CurrentThreadCanReadCompilationData());
AutoThreadSafeAccess ts(this);
return addendum->asTypedObject();
}

View File

@ -87,7 +87,6 @@ Type::ObjectType(JSObject *obj)
/* static */ inline Type
Type::ObjectType(TypeObject *obj)
{
AutoThreadSafeAccess ts(obj);
if (obj->singleton())
return Type(uintptr_t(obj->singleton()) | 1);
return Type(uintptr_t(obj));
@ -178,7 +177,6 @@ IdToTypeId(jsid id)
*/
if (JSID_IS_STRING(id)) {
JSAtom *atom = JSID_TO_ATOM(id);
js::AutoThreadSafeAccess ts(atom);
JS::TwoByteChars cp = atom->range();
if (cp.length() > 0 && (JS7_ISDEC(cp[0]) || cp[0] == '-')) {
for (size_t i = 1; i < cp.length(); ++i) {
@ -565,7 +563,6 @@ TypeScript::NumTypeSets(JSScript *script)
/* static */ inline StackTypeSet *
TypeScript::ThisTypes(JSScript *script)
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
return script->types->typeArray() + script->nTypeSets() + analyze::ThisSlot();
}
@ -579,7 +576,6 @@ TypeScript::ThisTypes(JSScript *script)
TypeScript::ArgTypes(JSScript *script, unsigned i)
{
JS_ASSERT(i < script->functionNonDelazifying()->nargs());
JS_ASSERT(CurrentThreadCanReadCompilationData());
return script->types->typeArray() + script->nTypeSets() + analyze::ArgSlot(i);
}
@ -1128,12 +1124,9 @@ ConstraintTypeSet::addType(ExclusiveContext *cxArg, Type type)
if (hasType(type))
return;
{
AutoLockForCompilation lock(cxArg);
if (!TypeSet::addType(type, &cxArg->typeLifoAlloc())) {
cxArg->compartment()->types.setPendingNukeTypes(cxArg);
return;
}
if (!TypeSet::addType(type, &cxArg->typeLifoAlloc())) {
cxArg->compartment()->types.setPendingNukeTypes(cxArg);
return;
}
InferSpew(ISpewOps, "addType: %sT%p%s %s",
@ -1277,7 +1270,6 @@ inline TypeObject::TypeObject(const Class *clasp, TaggedProto proto, TypeObjectF
inline uint32_t
TypeObject::basePropertyCount() const
{
JS_ASSERT(CurrentThreadCanReadCompilationData());
return (flags() & OBJECT_FLAG_PROPERTY_COUNT_MASK) >> OBJECT_FLAG_PROPERTY_COUNT_SHIFT;
}
@ -1302,27 +1294,21 @@ TypeObject::getProperty(ExclusiveContext *cx, jsid id)
if (HeapTypeSet *types = maybeGetProperty(id))
return types;
uint32_t propertyCount;
Property **pprop;
{
AutoLockForCompilation lock(cx);
uint32_t propertyCount = basePropertyCount();
Property **pprop = HashSetInsert<jsid,Property,Property>
(cx->typeLifoAlloc(), propertySet, propertyCount, id);
if (!pprop) {
cx->compartment()->types.setPendingNukeTypes(cx);
return nullptr;
}
propertyCount = basePropertyCount();
pprop = HashSetInsert<jsid,Property,Property>
(cx->typeLifoAlloc(), propertySet, propertyCount, id);
if (!pprop) {
cx->compartment()->types.setPendingNukeTypes(cx);
return nullptr;
}
JS_ASSERT(!*pprop);
JS_ASSERT(!*pprop);
setBasePropertyCount(propertyCount);
if (!addProperty(cx, id, pprop)) {
setBasePropertyCount(0);
propertySet = nullptr;
return nullptr;
}
setBasePropertyCount(propertyCount);
if (!addProperty(cx, id, pprop)) {
setBasePropertyCount(0);
propertySet = nullptr;
return nullptr;
}
if (propertyCount == OBJECT_FLAG_PROPERTY_COUNT_LIMIT) {
@ -1350,9 +1336,6 @@ TypeObject::maybeGetProperty(jsid id)
JS_ASSERT(JSID_IS_VOID(id) || JSID_IS_EMPTY(id) || JSID_IS_STRING(id));
JS_ASSERT_IF(!JSID_IS_EMPTY(id), id == IdToTypeId(id));
JS_ASSERT(!unknownProperties());
JS_ASSERT(CurrentThreadCanReadCompilationData());
AutoThreadSafeAccess ts(this);
Property *prop = HashSetLookup<jsid,Property,Property>
(propertySet, basePropertyCount(), id);

View File

@ -2048,7 +2048,6 @@ GlobalObject::initIteratorClasses(JSContext *cx, Handle<GlobalObject *> global)
if (!LinkConstructorAndPrototype(cx, genFunction, genFunctionProto))
return false;
AutoLockForCompilation lock(cx);
global->setSlot(STAR_GENERATOR_OBJECT_PROTO, ObjectValue(*genObjectProto));
global->setConstructor(JSProto_GeneratorFunction, ObjectValue(*genFunction));
global->setPrototype(JSProto_GeneratorFunction, ObjectValue(*genFunctionProto));

View File

@ -2250,12 +2250,9 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &
* Swap the object's types, to restore their initial type information.
* The prototypes and classes of the objects were swapped in ReserveForTradeGuts.
*/
{
AutoLockForCompilation lock(cx);
TypeObject *tmp = a->type_;
a->type_ = b->type_;
b->type_ = tmp;
}
TypeObject *tmp = a->type_;
a->type_ = b->type_;
b->type_ = tmp;
/* Don't try to swap a JSFunction for a plain function JSObject. */
JS_ASSERT_IF(a->is<JSFunction>(), a->tenuredSizeOfThis() == b->tenuredSizeOfThis());
@ -2287,12 +2284,9 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &
char tmp[mozilla::tl::Max<sizeof(JSFunction), sizeof(JSObject_Slots16)>::value];
JS_ASSERT(size <= sizeof(tmp));
{
AutoLockForCompilation lock(cx);
js_memcpy(tmp, a, size);
js_memcpy(a, b, size);
js_memcpy(b, tmp, size);
}
js_memcpy(tmp, a, size);
js_memcpy(a, b, size);
js_memcpy(b, tmp, size);
#ifdef JSGC_GENERATIONAL
/*
@ -2330,12 +2324,9 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &
void *bpriv = b->hasPrivate() ? b->getPrivate() : nullptr;
char tmp[sizeof(JSObject)];
{
AutoLockForCompilation lock(cx);
js_memcpy(&tmp, a, sizeof tmp);
js_memcpy(a, b, sizeof tmp);
js_memcpy(b, &tmp, sizeof tmp);
}
js_memcpy(&tmp, a, sizeof tmp);
js_memcpy(a, b, sizeof tmp);
js_memcpy(b, &tmp, sizeof tmp);
if (a->isNative())
a->shape_->setNumFixedSlots(reserved.newafixed);
@ -2785,12 +2776,6 @@ JSObject::growSlots(ThreadSafeContext *cx, HandleObject obj, uint32_t oldCount,
}
}
// Global slots may be read during off thread compilation, and updates to
// their slot pointers need to be synchronized.
Maybe<AutoLockForCompilation> lock;
if (obj->is<GlobalObject>())
lock.construct(cx->asExclusiveContext());
if (!oldCount) {
obj->slots = AllocateSlots(cx, obj, newCount);
if (!obj->slots)
@ -2835,12 +2820,6 @@ JSObject::shrinkSlots(ThreadSafeContext *cx, HandleObject obj, uint32_t oldCount
JS_ASSERT_IF(!obj->is<ArrayObject>(), newCount >= SLOT_CAPACITY_MIN);
// Global slots may be read during off thread compilation, and updates to
// their slot pointers need to be synchronized.
Maybe<AutoLockForCompilation> lock;
if (obj->is<GlobalObject>())
lock.construct(cx->asExclusiveContext());
HeapSlot *newslots = ReallocateSlots(cx, obj, obj->slots, oldCount, newCount);
if (!newslots)
return; /* Leave slots at its old size. */
@ -3227,10 +3206,7 @@ js::SetClassAndProto(JSContext *cx, HandleObject obj,
MarkTypeObjectUnknownProperties(cx, obj->type(), true);
MarkTypeObjectUnknownProperties(cx, type, true);
{
AutoLockForCompilation lock(cx);
obj->setType(type);
}
obj->setType(type);
*succeeded = true;
return true;
@ -4303,7 +4279,7 @@ NativeGetInline(JSContext *cx,
case JSOP_GETPROP:
case JSOP_CALLPROP:
case JSOP_LENGTH:
script->baselineScript()->noteAccessedGetter(cx, script->pcToOffset(pc));
script->baselineScript()->noteAccessedGetter(script->pcToOffset(pc));
break;
default:
break;
@ -5697,8 +5673,6 @@ DumpProperty(JSObject *obj, Shape &shape)
bool
JSObject::uninlinedIsProxy() const
{
AutoThreadSafeAccess ts0(this);
AutoThreadSafeAccess ts1(type_);
return is<ProxyObject>();
}

View File

@ -289,10 +289,6 @@ class JSObject : public js::ObjectImpl
}
bool isBoundFunction() const {
// Note: This function can race when it is called during off thread compilation.
js::AutoThreadSafeAccess ts0(this);
js::AutoThreadSafeAccess ts1(lastProperty());
js::AutoThreadSafeAccess ts2(lastProperty()->base());
return lastProperty()->hasObjectFlag(js::BaseShape::BOUND_FUNCTION);
}
@ -354,10 +350,6 @@ class JSObject : public js::ObjectImpl
return lastProperty()->entryCount();
}
uint32_t propertyCountForCompilation() const {
return lastProperty()->entryCountForCompilation();
}
bool hasShapeTable() const {
return lastProperty()->hasTable();
}
@ -376,13 +368,13 @@ class JSObject : public js::ObjectImpl
/* Whether a slot is at a fixed offset from this object. */
bool isFixedSlot(size_t slot) {
return slot < numFixedSlotsForCompilation();
return slot < numFixedSlots();
}
/* Index into the dynamic slots array to use for a dynamic slot. */
size_t dynamicSlotIndex(size_t slot) {
JS_ASSERT(slot >= numFixedSlotsForCompilation());
return slot - numFixedSlotsForCompilation();
JS_ASSERT(slot >= numFixedSlots());
return slot - numFixedSlots();
}
/*

View File

@ -400,9 +400,6 @@ JSObject::clearType(JSContext *cx, js::HandleObject obj)
inline void
JSObject::setType(js::types::TypeObject *newType)
{
// Note: This is usually called for newly created objects that haven't
// escaped to script yet, so don't require that the compilation lock be
// held here.
JS_ASSERT(newType);
JS_ASSERT(!hasSingletonType());
type_ = newType;
@ -999,11 +996,8 @@ DefineConstructorAndPrototype(JSContext *cx, Handle<GlobalObject*> global,
JS_ASSERT(!global->nativeLookup(cx, id));
/* Set these first in case AddTypePropertyId looks for this class. */
{
AutoLockForCompilation lock(cx);
global->setConstructor(key, ObjectValue(*ctor));
global->setPrototype(key, ObjectValue(*proto));
}
global->setConstructor(key, ObjectValue(*ctor));
global->setPrototype(key, ObjectValue(*proto));
global->setConstructorPropertySlot(key, ObjectValue(*ctor));
if (!global->addDataProperty(cx, id, GlobalObject::constructorPropertySlot(key), 0)) {

View File

@ -3167,10 +3167,7 @@ JSScript::argumentsOptimizationFailed(JSContext *cx, HandleScript script)
JS_ASSERT(!script->isGenerator());
{
AutoLockForCompilation lock(cx);
script->needsArgsObj_ = true;
}
script->needsArgsObj_ = true;
#ifdef JS_ION
/*
@ -3230,14 +3227,12 @@ JSScript::argumentsOptimizationFailed(JSContext *cx, HandleScript script)
bool
JSScript::varIsAliased(uint32_t varSlot)
{
AutoThreadSafeAccess ts(this);
return bindings.bindingIsAliased(bindings.numArgs() + varSlot);
}
bool
JSScript::formalIsAliased(unsigned argSlot)
{
AutoThreadSafeAccess ts(this);
return bindings.bindingIsAliased(argSlot);
}

View File

@ -249,8 +249,6 @@ class Bindings
if (!callObjShape_)
return false;
// Binding shapes are immutable once constructed.
AutoThreadSafeAccess ts(callObjShape_);
return !callObjShape_->isEmptyShape();
}
@ -554,10 +552,6 @@ class ScriptSourceObject : public JSObject
const ReadOnlyCompileOptions &options);
ScriptSource *source() {
// Script source objects are immutable.
AutoThreadSafeAccess ts0(this);
AutoThreadSafeAccess ts1(lastProperty());
AutoThreadSafeAccess ts2(lastProperty()->base());
return static_cast<ScriptSource *>(getReservedSlot(SOURCE_SLOT).toPrivate());
}
@ -638,22 +632,18 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
(and arguments if this is a function script) */
bool hasAnyAliasedBindings() const {
js::AutoThreadSafeAccess ts(this);
return bindings.hasAnyAliasedBindings();
}
js::Binding *bindingArray() const {
js::AutoThreadSafeAccess ts(this);
return bindings.bindingArray();
}
unsigned numArgs() const {
js::AutoThreadSafeAccess ts(this);
return bindings.numArgs();
}
js::Shape *callObjShape() const {
js::AutoThreadSafeAccess ts(this);
return bindings.callObjShape();
}
@ -889,11 +879,9 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
// Script bytecode is immutable after creation.
jsbytecode *code() const {
js::AutoThreadSafeAccess ts(this);
return code_;
}
size_t length() const {
js::AutoThreadSafeAccess ts(this);
return length_;
}
@ -917,94 +905,77 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
}
size_t mainOffset() const {
js::AutoThreadSafeAccess ts(this);
return mainOffset_;
}
size_t lineno() const {
js::AutoThreadSafeAccess ts(this);
return lineno_;
}
size_t column() const {
js::AutoThreadSafeAccess ts(this);
return column_;
}
void setColumn(size_t column) { column_ = column; }
size_t nfixed() const {
js::AutoThreadSafeAccess ts(this);
return function_ ? bindings.numVars() : 0;
}
size_t nslots() const {
js::AutoThreadSafeAccess ts(this);
return nslots_;
}
size_t staticLevel() const {
js::AutoThreadSafeAccess ts(this);
return staticLevel_;
}
size_t nTypeSets() const {
js::AutoThreadSafeAccess ts(this);
return nTypeSets_;
}
size_t funLength() const {
js::AutoThreadSafeAccess ts(this);
return funLength_;
}
size_t sourceStart() const {
js::AutoThreadSafeAccess ts(this);
return sourceStart_;
}
size_t sourceEnd() const {
js::AutoThreadSafeAccess ts(this);
return sourceEnd_;
}
bool noScriptRval() const {
js::AutoThreadSafeAccess ts(this);
return noScriptRval_;
}
bool savedCallerFun() const { return savedCallerFun_; }
bool strict() const {
js::AutoThreadSafeAccess ts(this);
return strict_;
}
bool explicitUseStrict() const { return explicitUseStrict_; }
bool compileAndGo() const {
js::AutoThreadSafeAccess ts(this);
return compileAndGo_;
}
bool selfHosted() const { return selfHosted_; }
bool bindingsAccessedDynamically() const { return bindingsAccessedDynamically_; }
bool funHasExtensibleScope() const {
js::AutoThreadSafeAccess ts(this);
return funHasExtensibleScope_;
}
bool funNeedsDeclEnvObject() const {
js::AutoThreadSafeAccess ts(this);
return funNeedsDeclEnvObject_;
}
bool funHasAnyAliasedFormal() const {
js::AutoThreadSafeAccess ts(this);
return funHasAnyAliasedFormal_;
}
bool hasSingletons() const { return hasSingletons_; }
bool treatAsRunOnce() const {
js::AutoThreadSafeAccess ts(this);
return treatAsRunOnce_;
}
bool hasRunOnce() const { return hasRunOnce_; }
@ -1034,17 +1005,14 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
void setDirectlyInsideEval() { directlyInsideEval_ = true; }
bool usesArgumentsAndApply() const {
js::AutoThreadSafeAccess ts(this);
return usesArgumentsAndApply_;
}
void setUsesArgumentsAndApply() { usesArgumentsAndApply_ = true; }
bool shouldCloneAtCallsite() const {
js::AutoThreadSafeAccess ts(this);
return shouldCloneAtCallsite_;
}
bool shouldInline() const {
js::AutoThreadSafeAccess ts(this);
return shouldInline_;
}
@ -1052,29 +1020,23 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
void setShouldInline() { shouldInline_ = true; }
bool isCallsiteClone() const {
js::AutoThreadSafeAccess ts(this);
return isCallsiteClone_;
}
bool isGeneratorExp() const { return isGeneratorExp_; }
bool failedBoundsCheck() const {
js::AutoThreadSafeAccess ts(this);
return failedBoundsCheck_;
}
bool failedShapeGuard() const {
js::AutoThreadSafeAccess ts(this);
return failedShapeGuard_;
}
bool hadFrequentBailouts() const {
js::AutoThreadSafeAccess ts(this);
return hadFrequentBailouts_;
}
bool uninlineable() const {
js::AutoThreadSafeAccess ts(this);
return uninlineable_;
}
bool invalidatedIdempotentCache() const {
js::AutoThreadSafeAccess ts(this);
return invalidatedIdempotentCache_;
}
@ -1095,7 +1057,6 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
/* See ContextFlags::funArgumentsHasLocalBinding comment. */
bool argumentsHasVarBinding() const {
js::AutoThreadSafeAccess ts(this);
return argsHasVarBinding_;
}
jsbytecode *argumentsBytecode() const { JS_ASSERT(code()[0] == JSOP_ARGUMENTS); return code(); }
@ -1105,7 +1066,6 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
}
js::GeneratorKind generatorKind() const {
js::AutoThreadSafeAccess ts(this);
return js::GeneratorKindFromBits(generatorKindBits_);
}
bool isGenerator() const { return generatorKind() != js::NotGenerator; }
@ -1130,8 +1090,6 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
*/
bool analyzedArgsUsage() const { return !needsArgsAnalysis_; }
bool needsArgsObj() const {
js::AutoThreadSafeAccess ts(this);
JS_ASSERT(js::CurrentThreadCanReadCompilationData());
JS_ASSERT(analyzedArgsUsage());
return needsArgsObj_;
}
@ -1156,17 +1114,9 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
}
bool hasIonScript() const {
// Note: While a script's baseline script is protected by the
// compilation lock, writes to the ion script are not. This helps lock
// ordering issues in CodeGenerator::link. Tests of script->ion during
// off thread compilation can therefore race, though these are fairly
// benign and the IonScript itself is never accessed.
js::AutoThreadSafeAccess ts(this);
return ion && ion != ION_DISABLED_SCRIPT && ion != ION_COMPILING_SCRIPT;
}
bool canIonCompile() const {
// Note: see above comment.
js::AutoThreadSafeAccess ts(this);
return ion != ION_DISABLED_SCRIPT;
}
@ -1192,8 +1142,6 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
}
bool hasBaselineScript() const {
JS_ASSERT(js::CurrentThreadCanReadCompilationData());
js::AutoThreadSafeAccess ts(this);
return baseline && baseline != BASELINE_DISABLED_SCRIPT;
}
bool canBaselineCompile() const {
@ -1201,7 +1149,6 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
}
js::jit::BaselineScript *baselineScript() const {
JS_ASSERT(hasBaselineScript());
js::AutoThreadSafeAccess ts(this);
return baseline;
}
inline void setBaselineScript(JSContext *maybecx, js::jit::BaselineScript *baselineScript);
@ -1213,7 +1160,6 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
}
bool canParallelIonCompile() const {
js::AutoThreadSafeAccess ts(this);
return parallelIon != ION_DISABLED_SCRIPT;
}
@ -1264,21 +1210,19 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
/*
* Original compiled function for the script, if it has a function.
* nullptr for global and eval scripts.
* The delazifying variant ensures that the function isn't lazy, but can
* only be used under a compilation lock. The non-delazifying variant
* can be used off-thread and without the lock, but must only be used
* after earlier code has called ensureNonLazyCanonicalFunction and
* while the function can't have been relazified.
* The delazifying variant ensures that the function isn't lazy. The
* non-delazifying variant must only be used after earlier code has
* called ensureNonLazyCanonicalFunction and while the function can't
* have been relazified.
*/
inline JSFunction *functionDelazifying() const;
JSFunction *functionNonDelazifying() const {
js::AutoThreadSafeAccess ts(this);
return function_;
}
inline void setFunction(JSFunction *fun);
/*
* Takes a compilation lock and de-lazifies the canonical function. Must
* be called before entering code that expects the function to be non-lazy.
* De-lazifies the canonical function. Must be called before entering code
* that expects the function to be non-lazy.
*/
inline void ensureNonLazyCanonicalFunction(JSContext *cx);
@ -1294,7 +1238,6 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
void setSourceObject(JSObject *object);
JSObject *sourceObject() const {
js::AutoThreadSafeAccess ts(this);
return sourceObject_;
}
js::ScriptSource *scriptSource() const;
@ -1335,7 +1278,6 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
JSObject *enclosingStaticScope() const {
if (isCallsiteClone())
return nullptr;
js::AutoThreadSafeAccess ts(this);
return enclosingScopeOrOriginalFunction_;
}
@ -1345,8 +1287,6 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
public:
uint32_t getUseCount() const {
// Note: We ignore races when reading the use count of a script off thread.
js::AutoThreadSafeAccess ts(this);
return useCount;
}
uint32_t incUseCount(uint32_t amount = 1) { return useCount += amount; }
@ -1381,7 +1321,6 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
jssrcnote *notes() { return (jssrcnote *)(code() + length()); }
bool hasArray(ArrayKind kind) {
js::AutoThreadSafeAccess ts(this);
return (hasArrayBits & (1 << kind));
}
void setHasArray(ArrayKind kind) { hasArrayBits |= (1 << kind); }
@ -1405,31 +1344,26 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
js::ConstArray *consts() {
JS_ASSERT(hasConsts());
js::AutoThreadSafeAccess ts(this);
return reinterpret_cast<js::ConstArray *>(data + constsOffset());
}
js::ObjectArray *objects() {
JS_ASSERT(hasObjects());
js::AutoThreadSafeAccess ts(this);
return reinterpret_cast<js::ObjectArray *>(data + objectsOffset());
}
js::ObjectArray *regexps() {
JS_ASSERT(hasRegexps());
js::AutoThreadSafeAccess ts(this);
return reinterpret_cast<js::ObjectArray *>(data + regexpsOffset());
}
js::TryNoteArray *trynotes() {
JS_ASSERT(hasTrynotes());
js::AutoThreadSafeAccess ts(this);
return reinterpret_cast<js::TryNoteArray *>(data + trynotesOffset());
}
js::BlockScopeArray *blockScopes() {
JS_ASSERT(hasBlockScopes());
js::AutoThreadSafeAccess ts(this);
return reinterpret_cast<js::BlockScopeArray *>(data + blockScopesOffset());
}
@ -1438,7 +1372,6 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
size_t natoms() const { return natoms_; }
js::HeapPtrAtom &getAtom(size_t index) const {
js::AutoThreadSafeAccess ts(this);
JS_ASSERT(index < natoms());
return atoms[index];
}
@ -1795,7 +1728,6 @@ class LazyScript : public gc::BarrieredCell<LazyScript>
}
bool usesArgumentsAndApply() const {
AutoThreadSafeAccess ts(this);
return usesArgumentsAndApply_;
}
void setUsesArgumentsAndApply() {
@ -1820,11 +1752,9 @@ class LazyScript : public gc::BarrieredCell<LazyScript>
return sourceObject()->source();
}
uint32_t begin() const {
AutoThreadSafeAccess ts(this);
return begin_;
}
uint32_t end() const {
AutoThreadSafeAccess ts(this);
return end_;
}
uint32_t lineno() const {

View File

@ -58,8 +58,6 @@ LazyScript::functionDelazifying(JSContext *cx) const
inline JSFunction *
JSScript::functionDelazifying() const
{
js::AutoThreadSafeAccess ts(this);
JS_ASSERT(js::CurrentThreadCanWriteCompilationData());
if (function_ && function_->isInterpretedLazy()) {
function_->setUnlazifiedScript(const_cast<JSScript *>(this));
// If this script has a LazyScript, make sure the LazyScript has a
@ -81,19 +79,15 @@ inline void
JSScript::ensureNonLazyCanonicalFunction(JSContext *cx)
{
// Infallibly delazify the canonical script.
if (function_ && function_->isInterpretedLazy()) {
js::AutoLockForCompilation lock(cx);
if (function_ && function_->isInterpretedLazy())
functionDelazifying();
}
}
inline JSFunction *
JSScript::getFunction(size_t index)
{
JSFunction *fun = &getObject(index)->as<JSFunction>();
#ifdef DEBUG
JS_ASSERT_IF(fun->isNative(), IsAsmJSModuleNative(fun->native()));
#endif
return fun;
}
@ -138,7 +132,6 @@ JSScript::global() const
* A JSScript always marks its compartment's global (via bindings) so we
* can assert that maybeGlobal is non-null here.
*/
js::AutoThreadSafeAccess ts(this);
return *compartment()->maybeGlobal();
}
@ -149,14 +142,16 @@ JSScript::principals()
}
inline JSFunction *
JSScript::donorFunction() const {
JSScript::donorFunction() const
{
if (!isCallsiteClone())
return nullptr;
return &enclosingScopeOrOriginalFunction_->as<JSFunction>();
}
inline void
JSScript::setIsCallsiteClone(JSObject *fun) {
JSScript::setIsCallsiteClone(JSObject *fun)
{
JS_ASSERT(shouldCloneAtCallsite());
shouldCloneAtCallsite_ = false;
isCallsiteClone_ = true;
@ -166,14 +161,12 @@ JSScript::setIsCallsiteClone(JSObject *fun) {
}
inline void
JSScript::setBaselineScript(JSContext *maybecx, js::jit::BaselineScript *baselineScript) {
JSScript::setBaselineScript(JSContext *maybecx, js::jit::BaselineScript *baselineScript)
{
#ifdef JS_ION
if (hasBaselineScript())
js::jit::BaselineScript::writeBarrierPre(tenuredZone(), baseline);
#endif
mozilla::Maybe<js::AutoLockForCompilation> lock;
if (maybecx)
lock.construct(maybecx);
baseline = baselineScript;
updateBaselineOrIonRaw();
}

View File

@ -4254,8 +4254,6 @@ js::CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32_t *resul
int32_t
js::CompareAtoms(JSAtom *atom1, JSAtom *atom2)
{
AutoThreadSafeAccess ts0(atom1);
AutoThreadSafeAccess ts1(atom2);
return CompareChars(atom1->chars(), atom1->length(), atom2->chars(), atom2->length());
}

View File

@ -93,8 +93,6 @@ js::StartOffThreadIonCompile(JSContext *cx, jit::IonBuilder *builder)
if (!WorkerThreadState().ionWorklist().append(builder))
return false;
cx->runtime()->addCompilationThread();
WorkerThreadState().notifyAll(GlobalWorkerThreadState::PRODUCER);
return true;
}
@ -649,8 +647,6 @@ GlobalWorkerThreadState::finishParseTask(JSContext *maybecx, JSRuntime *rt, void
JSObject *newProto = GetClassPrototypePure(&parseTask->scopeChain->global(), key);
JS_ASSERT(newProto);
// Note: this is safe to do without requiring the compilation lock, as
// the new type is not yet available to compilation threads.
object->setProtoUnchecked(newProto);
}
@ -791,11 +787,7 @@ WorkerThread::handleIonWorkload()
jit::IonContext ictx(jit::CompileRuntime::get(rt),
jit::CompileCompartment::get(ionBuilder->script()->compartment()),
&ionBuilder->alloc());
AutoEnterIonCompilation ionCompiling;
bool succeeded = ionBuilder->build();
ionBuilder->clearForBackEnd();
if (succeeded)
ionBuilder->setBackgroundCodegen(jit::CompileBackEnd(ionBuilder));
ionBuilder->setBackgroundCodegen(jit::CompileBackEnd(ionBuilder));
}
FinishOffThreadIonCompile(ionBuilder);

View File

@ -83,9 +83,6 @@ js::UncheckedUnwrap(JSObject *wrapped, bool stopAtOuter, unsigned *flagsp)
{
unsigned flags = 0;
while (true) {
AutoThreadSafeAccess ts0(wrapped);
AutoThreadSafeAccess ts1(wrapped->typeRaw());
AutoThreadSafeAccess ts2(wrapped->lastProperty());
if (!wrapped->is<WrapperObject>() ||
MOZ_UNLIKELY(stopAtOuter && wrapped->getClass()->ext.innerObject))
{

View File

@ -5511,9 +5511,6 @@ ProcessArgs(JSContext *cx, JSObject *obj_, OptionParser *op)
if (op->getBoolOption("ion-check-range-analysis"))
jit::js_JitOptions.checkRangeAnalysis = true;
if (op->getBoolOption("ion-check-thread-safety"))
jit::js_JitOptions.checkThreadSafety = true;
if (const char *str = op->getStringOption("ion-inlining")) {
if (strcmp(str, "on") == 0)
jit::js_JitOptions.disableInlining = false;
@ -5788,8 +5785,6 @@ main(int argc, char **argv, char **envp)
"Range analysis (default: on, off to disable)")
|| !op.addBoolOption('\0', "ion-check-range-analysis",
"Range analysis checking")
|| !op.addBoolOption('\0', "ion-check-thread-safety",
"IonBuilder thread safety checking")
|| !op.addStringOption('\0', "ion-inlining", "on/off",
"Inline methods where possible (default: on, off to disable)")
|| !op.addStringOption('\0', "ion-osr", "on/off",
@ -5898,15 +5893,8 @@ main(int argc, char **argv, char **envp)
if (!JS_Init())
return 1;
// When doing thread safety checks for VM accesses made during Ion compilation,
// we rely on protected memory and only the main thread should be active.
JSUseHelperThreads useHelperThreads =
op.getBoolOption("ion-check-thread-safety")
? JS_NO_HELPER_THREADS
: JS_USE_HELPER_THREADS;
/* Use the same parameters as the browser in xpcjsruntime.cpp. */
rt = JS_NewRuntime(32L * 1024L * 1024L, useHelperThreads);
rt = JS_NewRuntime(32L * 1024L * 1024L, JS_USE_HELPER_THREADS);
if (!rt)
return 1;
gTimeoutFunc = NullValue();

View File

@ -554,14 +554,14 @@ GlobalObject::getOrCreateEval(JSContext *cx, Handle<GlobalObject*> global,
{
if (!global->getOrCreateObjectPrototype(cx))
return false;
eval.set(&global->getSlotForCompilation(EVAL).toObject());
eval.set(&global->getSlot(EVAL).toObject());
return true;
}
bool
GlobalObject::valueIsEval(Value val)
{
Value eval = getSlotForCompilation(EVAL);
Value eval = getSlot(EVAL);
return eval.isObject() && eval == val;
}
@ -788,10 +788,6 @@ GlobalObject::addIntrinsicValue(JSContext *cx, HandleId id, HandleValue value)
{
RootedObject holder(cx, intrinsicsHolder());
// Work directly with the shape machinery underlying the object, so that we
// don't take the compilation lock until we are ready to update the object
// without triggering a GC.
uint32_t slot = holder->slotSpan();
RootedShape last(cx, holder->lastProperty());
Rooted<UnownedBaseShape*> base(cx, last->base()->unowned());
@ -801,7 +797,6 @@ GlobalObject::addIntrinsicValue(JSContext *cx, HandleId id, HandleValue value)
if (!shape)
return false;
AutoLockForCompilation lock(cx);
if (!JSObject::setLastProperty(cx, holder, shape))
return false;

View File

@ -158,7 +158,7 @@ class GlobalObject : public JSObject
public:
Value getConstructor(JSProtoKey key) const {
JS_ASSERT(key <= JSProto_LIMIT);
return getSlotForCompilation(APPLICATION_SLOTS + key);
return getSlot(APPLICATION_SLOTS + key);
}
static bool ensureConstructor(JSContext *cx, Handle<GlobalObject*> global, JSProtoKey key);
static bool initConstructor(JSContext *cx, Handle<GlobalObject*> global, JSProtoKey key);
@ -170,7 +170,7 @@ class GlobalObject : public JSObject
Value getPrototype(JSProtoKey key) const {
JS_ASSERT(key <= JSProto_LIMIT);
return getSlotForCompilation(APPLICATION_SLOTS + JSProto_LIMIT + key);
return getSlot(APPLICATION_SLOTS + JSProto_LIMIT + key);
}
void setPrototype(JSProtoKey key, const Value &value) {
@ -457,19 +457,6 @@ class GlobalObject : public JSObject
return &self->getSlot(slot).toObject();
}
Value getSlotForCompilation(uint32_t slot) const {
// This method should only be used for slots that are either eagerly
// initialized on creation of the global or only change under the
// compilation lock. Note that the dynamic slots pointer for global
// objects can only change under the compilation lock.
JS_ASSERT(slot < JSCLASS_RESERVED_SLOTS(getClass()));
uint32_t fixed = numFixedSlotsForCompilation();
AutoThreadSafeAccess ts(this);
if (slot < fixed)
return fixedSlots()[slot];
return slots[slot - fixed];
}
public:
static JSObject *getOrCreateIteratorPrototype(JSContext *cx,
Handle<GlobalObject*> global)
@ -547,18 +534,13 @@ class GlobalObject : public JSObject
}
JSObject *intrinsicsHolder() {
JS_ASSERT(!getSlotForCompilation(INTRINSICS).isUndefined());
return &getSlotForCompilation(INTRINSICS).toObject();
JS_ASSERT(!getSlot(INTRINSICS).isUndefined());
return &getSlot(INTRINSICS).toObject();
}
bool maybeGetIntrinsicValue(jsid id, Value *vp) {
JS_ASSERT(CurrentThreadCanReadCompilationData());
JSObject *holder = intrinsicsHolder();
AutoThreadSafeAccess ts0(holder);
AutoThreadSafeAccess ts1(holder->lastProperty());
AutoThreadSafeAccess ts2(holder->lastProperty()->base());
if (Shape *shape = holder->nativeLookupPure(id)) {
*vp = holder->getSlot(shape->slot());
return true;
@ -596,8 +578,7 @@ class GlobalObject : public JSObject
unsigned nargs, MutableHandleValue funVal);
RegExpStatics *getRegExpStatics() const {
JSObject &resObj = getSlotForCompilation(REGEXP_STATICS).toObject();
AutoThreadSafeAccess ts(&resObj);
JSObject &resObj = getSlot(REGEXP_STATICS).toObject();
return static_cast<RegExpStatics *>(resObj.getPrivate(/* nfixed = */ 1));
}

View File

@ -1320,7 +1320,7 @@ SetObjectElementOperation(JSContext *cx, Handle<JSObject*> obj, HandleId id, con
if ((uint32_t)i >= length) {
// Annotate script if provided with information (e.g. baseline)
if (script && script->hasBaselineScript() && *pc == JSOP_SETELEM)
script->baselineScript()->noteArrayWriteHole(cx, script->pcToOffset(pc));
script->baselineScript()->noteArrayWriteHole(script->pcToOffset(pc));
}
}
#endif

View File

@ -334,25 +334,6 @@ js::ObjectImpl::nativeLookupPure(jsid id)
return Shape::searchNoHashify(lastProperty(), id);
}
uint32_t
js::ObjectImpl::numFixedSlotsForCompilation() const
{
// This is an alternative method for getting the number of fixed slots
// in an object. It requires more logic and memory accesses than
// numFixedSlots() but is safe to be called from the compilation thread,
// even if the main thread is actively mutating the VM.
if (static_cast<const JSObject *>(this)->is<ArrayObject>())
return 0;
#ifdef JSGC_GENERATIONAL
// The compiler does not have access to nursery things, so if this object
// is in the nursery we can fall back to numFixedSlots().
if (IsInsideNursery(GetGCThingRuntime(this), this))
return numFixedSlots();
#endif
gc::AllocKind kind = tenuredGetAllocKind();
return gc::GetGCKindSlots(kind, getClass());
}
uint32_t
js::ObjectImpl::dynamicSlotsCount(uint32_t nfixed, uint32_t span, const Class *clasp)
{

View File

@ -984,14 +984,12 @@ class ObjectImpl : public gc::BarrieredCell<ObjectImpl>
public:
TaggedProto getTaggedProto() const {
AutoThreadSafeAccess ts(this);
return type_->proto();
}
bool hasTenuredProto() const;
const Class *getClass() const {
AutoThreadSafeAccess ts(this);
return type_->clasp();
}
@ -1206,8 +1204,6 @@ class ObjectImpl : public gc::BarrieredCell<ObjectImpl>
}
types::TypeObject *typeRaw() const {
AutoThreadSafeAccess ts0(this);
AutoThreadSafeAccess ts1(type_);
return type_;
}
@ -1215,14 +1211,11 @@ class ObjectImpl : public gc::BarrieredCell<ObjectImpl>
return reinterpret_cast<const shadow::Object *>(this)->numFixedSlots();
}
uint32_t numFixedSlotsForCompilation() const;
/*
* Whether this is the only object which has its specified type. This
* object will have its type constructed lazily as needed by analysis.
*/
bool hasSingletonType() const {
AutoThreadSafeAccess ts(this);
return !!type_->singleton();
}
@ -1231,7 +1224,6 @@ class ObjectImpl : public gc::BarrieredCell<ObjectImpl>
* might have a lazy type, use getType() below, otherwise type().
*/
bool hasLazyType() const {
AutoThreadSafeAccess ts(this);
return type_->lazy();
}
@ -1391,7 +1383,7 @@ class ObjectImpl : public gc::BarrieredCell<ObjectImpl>
}
const Value &getFixedSlot(uint32_t slot) const {
MOZ_ASSERT(slot < numFixedSlotsForCompilation());
MOZ_ASSERT(slot < numFixedSlots());
return fixedSlots()[slot];
}
@ -1478,7 +1470,7 @@ class ObjectImpl : public gc::BarrieredCell<ObjectImpl>
* Private pointers are stored immediately after the last fixed slot of
* the object.
*/
MOZ_ASSERT(nfixed == numFixedSlotsForCompilation());
MOZ_ASSERT(nfixed == numFixedSlots());
MOZ_ASSERT(hasPrivate());
HeapSlot *end = &fixedSlots()[nfixed];
return *reinterpret_cast<void**>(end);
@ -1555,10 +1547,6 @@ MOZ_ALWAYS_INLINE Zone *
BarrieredCell<ObjectImpl>::zoneFromAnyThread() const
{
const ObjectImpl* obj = static_cast<const ObjectImpl*>(this);
// Note: This read of obj->shape_ may race, though the zone fetched will be the same.
AutoThreadSafeAccess ts(obj->shape_);
return obj->shape_->zoneFromAnyThread();
}

View File

@ -80,9 +80,6 @@ PerThreadData::PerThreadData(JSRuntime *runtime)
#endif
dtoaState(nullptr),
suppressGC(0),
#ifdef DEBUG
ionCompiling(false),
#endif
activeCompilations(0)
{}
@ -132,12 +129,6 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
exclusiveAccessOwner(nullptr),
mainThreadHasExclusiveAccess(false),
numExclusiveThreads(0),
compilationLock(nullptr),
#ifdef DEBUG
compilationLockOwner(nullptr),
mainThreadHasCompilationLock(false),
#endif
numCompilationThreads(0),
#else
operationCallbackLockTaken(false),
#endif
@ -280,7 +271,6 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
decimalSeparator(0),
numGrouping(0),
#endif
heapProtected_(false),
mathCache_(nullptr),
activeCompilations_(0),
keepAtoms_(0),
@ -360,10 +350,6 @@ JSRuntime::init(uint32_t maxbytes)
exclusiveAccessLock = PR_NewLock();
if (!exclusiveAccessLock)
return false;
compilationLock = PR_NewLock();
if (!compilationLock)
return false;
#endif
if (!mainThread.init())
@ -495,10 +481,6 @@ JSRuntime::~JSRuntime()
JS_ASSERT(!numExclusiveThreads);
mainThreadHasExclusiveAccess = true;
JS_ASSERT(!compilationLockOwner);
if (compilationLock)
PR_DestroyLock(compilationLock);
JS_ASSERT(!operationCallbackOwner);
if (operationCallbackLock)
PR_DestroyLock(operationCallbackLock);
@ -859,76 +841,6 @@ JSRuntime::activeGCInAtomsZone()
return zone->needsBarrier() || zone->isGCScheduled() || zone->wasGCStarted();
}
#ifdef JS_CAN_CHECK_THREADSAFE_ACCESSES
AutoProtectHeapForIonCompilation::AutoProtectHeapForIonCompilation(JSRuntime *rt MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
: runtime(rt)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
JS_ASSERT(!runtime->heapProtected_);
runtime->heapProtected_ = true;
for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront()) {
Chunk *chunk = r.front();
// Note: Don't protect the last page in the chunk, which stores
// immutable info and needs to be accessible for runtimeFromAnyThread()
// in AutoThreadSafeAccess.
if (mprotect(chunk, ChunkSize - sizeof(Arena), PROT_NONE))
MOZ_CRASH();
}
}
AutoProtectHeapForIonCompilation::~AutoProtectHeapForIonCompilation()
{
JS_ASSERT(runtime->heapProtected_);
JS_ASSERT(runtime->unprotectedArenas.empty());
runtime->heapProtected_ = false;
for (GCChunkSet::Range r(runtime->gcChunkSet.all()); !r.empty(); r.popFront()) {
Chunk *chunk = r.front();
if (mprotect(chunk, ChunkSize - sizeof(Arena), PROT_READ | PROT_WRITE))
MOZ_CRASH();
}
}
AutoThreadSafeAccess::AutoThreadSafeAccess(const Cell *cell MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
: runtime(cell->runtimeFromAnyThread()), arena(nullptr)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
if (!runtime->heapProtected_)
return;
ArenaHeader *base = cell->arenaHeader();
for (size_t i = 0; i < runtime->unprotectedArenas.length(); i++) {
if (base == runtime->unprotectedArenas[i])
return;
}
arena = base;
if (mprotect(arena, sizeof(Arena), PROT_READ | PROT_WRITE))
MOZ_CRASH();
if (!runtime->unprotectedArenas.append(arena))
MOZ_CRASH();
}
AutoThreadSafeAccess::~AutoThreadSafeAccess()
{
if (!arena)
return;
if (mprotect(arena, sizeof(Arena), PROT_NONE))
MOZ_CRASH();
JS_ASSERT(arena == runtime->unprotectedArenas.back());
runtime->unprotectedArenas.popBack();
}
#endif // JS_CAN_CHECK_THREADSAFE_ACCESSES
#ifdef JS_THREADSAFE
void
@ -993,8 +905,6 @@ JSRuntime::assertCanLock(RuntimeLock which)
JS_ASSERT(exclusiveAccessOwner != PR_GetCurrentThread());
case WorkerThreadStateLock:
JS_ASSERT(!WorkerThreadState().isLocked());
case CompilationLock:
JS_ASSERT(compilationLockOwner != PR_GetCurrentThread());
case OperationCallbackLock:
JS_ASSERT(!currentThreadOwnsOperationCallbackLock());
case GCLock:
@ -1006,64 +916,6 @@ JSRuntime::assertCanLock(RuntimeLock which)
#endif // JS_THREADSAFE
}
AutoEnterIonCompilation::AutoEnterIonCompilation(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
#ifdef JS_THREADSAFE
PerThreadData *pt = js::TlsPerThreadData.get();
JS_ASSERT(!pt->ionCompiling);
pt->ionCompiling = true;
#endif
}
AutoEnterIonCompilation::~AutoEnterIonCompilation()
{
#ifdef JS_THREADSAFE
PerThreadData *pt = js::TlsPerThreadData.get();
JS_ASSERT(pt->ionCompiling);
pt->ionCompiling = false;
#endif
}
bool
js::CurrentThreadCanWriteCompilationData()
{
#ifdef JS_THREADSAFE
PerThreadData *pt = TlsPerThreadData.get();
// Data can only be read from during compilation.
if (pt->ionCompiling)
return false;
// Ignore what threads with exclusive contexts are doing; these never have
// run scripts or have associated compilation threads.
JSRuntime *rt = pt->runtimeIfOnOwnerThread();
if (!rt)
return true;
return rt->currentThreadHasCompilationLock();
#else
return true;
#endif
}
bool
js::CurrentThreadCanReadCompilationData()
{
#ifdef JS_THREADSAFE
PerThreadData *pt = TlsPerThreadData.get();
// Data can always be read from freely outside of compilation.
if (!pt || !pt->ionCompiling)
return true;
return pt->runtime_->currentThreadHasCompilationLock();
#else
return true;
#endif
}
void
js::AssertCurrentThreadCanLock(RuntimeLock which)
{

View File

@ -483,7 +483,6 @@ AtomStateOffsetToName(const JSAtomState &atomState, size_t offset)
enum RuntimeLock {
ExclusiveAccessLock,
WorkerThreadStateLock,
CompilationLock,
OperationCallbackLock,
GCLock
};
@ -553,7 +552,6 @@ class PerThreadData : public PerThreadDataFriendFields
friend class js::jit::JitActivation;
friend class js::AsmJSActivation;
#ifdef DEBUG
friend bool js::CurrentThreadCanReadCompilationData();
friend void js::AssertCurrentThreadCanLock(RuntimeLock which);
#endif
@ -603,11 +601,6 @@ class PerThreadData : public PerThreadDataFriendFields
*/
int32_t suppressGC;
#ifdef DEBUG
// Whether this thread is actively Ion compiling.
bool ionCompiling;
#endif
// Number of active bytecode compilation on this thread.
unsigned activeCompilations;
@ -658,8 +651,6 @@ class MarkingValidator;
typedef Vector<JS::Zone *, 4, SystemAllocPolicy> ZoneVector;
class AutoLockForExclusiveAccess;
class AutoLockForCompilation;
class AutoProtectHeapForIonCompilation;
void RecomputeStackLimit(JSRuntime *rt, StackKind kind);
@ -774,28 +765,6 @@ struct JSRuntime : public JS::shadow::Runtime,
friend class js::AutoLockForExclusiveAccess;
/*
* Lock taken when using data that can be modified by the main thread but
* read by Ion compilation threads. Any time either the main thread writes
* such data or the compilation thread reads it, this lock must be taken.
* Note that no externally visible data is modified by the compilation
* thread, so the main thread never needs to take this lock when reading.
*/
PRLock *compilationLock;
#ifdef DEBUG
PRThread *compilationLockOwner;
bool mainThreadHasCompilationLock;
#endif
/* Number of in flight Ion compilations. */
size_t numCompilationThreads;
friend class js::AutoLockForCompilation;
#ifdef DEBUG
friend bool js::CurrentThreadCanWriteCompilationData();
friend bool js::CurrentThreadCanReadCompilationData();
#endif
public:
void setUsedByExclusiveThread(JS::Zone *zone);
void clearUsedByExclusiveThread(JS::Zone *zone);
@ -821,41 +790,6 @@ struct JSRuntime : public JS::shadow::Runtime,
#endif
}
void addCompilationThread() {
#ifdef JS_THREADSAFE
numCompilationThreads++;
#else
MOZ_ASSUME_UNREACHABLE("No threads");
#endif
}
void removeCompilationThread() {
#ifdef JS_THREADSAFE
JS_ASSERT(numCompilationThreads);
numCompilationThreads--;
#else
MOZ_ASSUME_UNREACHABLE("No threads");
#endif
}
bool compilationThreadsPresent() const {
#ifdef JS_THREADSAFE
return numCompilationThreads > 0;
#else
return false;
#endif
}
#ifdef DEBUG
bool currentThreadHasCompilationLock() {
#ifdef JS_THREADSAFE
return (!numCompilationThreads && mainThreadHasCompilationLock) ||
compilationLockOwner == PR_GetCurrentThread();
#else
return true;
#endif
}
#endif // DEBUG
/* Embedders can use this zone however they wish. */
JS::Zone *systemZone;
@ -1474,18 +1408,6 @@ struct JSRuntime : public JS::shadow::Runtime,
const char *numGrouping;
#endif
friend class js::AutoProtectHeapForIonCompilation;
friend class js::AutoThreadSafeAccess;
mozilla::DebugOnly<bool> heapProtected_;
#ifdef DEBUG
js::Vector<js::gc::ArenaHeader *, 0, js::SystemAllocPolicy> unprotectedArenas;
public:
bool heapProtected() {
return heapProtected_;
}
#endif
private:
js::MathCache *mathCache_;
js::MathCache *createMathCache(JSContext *cx);
@ -2083,43 +2005,6 @@ class RuntimeAllocPolicy
extern const JSSecurityCallbacks NullSecurityCallbacks;
// Debugging RAII class which marks the current thread as performing an Ion
// compilation, for use by CurrentThreadCan{Read,Write}CompilationData
class AutoEnterIonCompilation
{
public:
#ifdef DEBUG
AutoEnterIonCompilation(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
~AutoEnterIonCompilation();
#else
AutoEnterIonCompilation(MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
}
#endif
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
// Debugging RAII class which protects the entire GC heap for the duration of an
// Ion compilation. When used only the main thread will be active and all
// accesses to GC things must be wrapped by an AutoThreadSafeAccess instance.
class AutoProtectHeapForIonCompilation
{
public:
#ifdef JS_CAN_CHECK_THREADSAFE_ACCESSES
JSRuntime *runtime;
AutoProtectHeapForIonCompilation(JSRuntime *rt MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
~AutoProtectHeapForIonCompilation();
#else
AutoProtectHeapForIonCompilation(JSRuntime *rt MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
}
#endif
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
} /* namespace js */
#ifdef _MSC_VER

View File

@ -76,10 +76,8 @@ StaticScopeIter<allowGC>::scopeShape() const
{
JS_ASSERT(hasDynamicScopeObject());
JS_ASSERT(type() != NAMED_LAMBDA);
if (type() == BLOCK) {
AutoThreadSafeAccess ts(&block());
if (type() == BLOCK)
return block().lastProperty();
}
return funScript()->callObjShape();
}

View File

@ -200,7 +200,6 @@ class ScopeObject : public JSObject
* enclosing scope of a ScopeObject is necessarily non-null.
*/
inline JSObject &enclosingScope() const {
AutoThreadSafeAccess ts(this);
return getFixedSlot(SCOPE_CHAIN_SLOT).toObject();
}
@ -252,7 +251,6 @@ class CallObject : public ScopeObject
/* True if this is for a strict mode eval frame. */
bool isForEval() const {
AutoThreadSafeAccess ts(this);
JS_ASSERT(getFixedSlot(CALLEE_SLOT).isObjectOrNull());
JS_ASSERT_IF(getFixedSlot(CALLEE_SLOT).isObject(),
getFixedSlot(CALLEE_SLOT).toObject().is<JSFunction>());
@ -264,7 +262,6 @@ class CallObject : public ScopeObject
* only be called if !isForEval.)
*/
JSFunction &callee() const {
AutoThreadSafeAccess ts(this);
return getFixedSlot(CALLEE_SLOT).toObject().as<JSFunction>();
}
@ -410,7 +407,7 @@ class BlockObject : public NestedScopeObject
/* Return the number of variables associated with this block. */
uint32_t slotCount() const {
return propertyCountForCompilation();
return propertyCount();
}
/*
@ -464,9 +461,6 @@ class StaticBlockObject : public BlockObject
* variable of the block isAliased.
*/
bool needsClone() {
// The first variable slot will always indicate whether the object has
// any aliased vars. Bypass slotValue() to allow testing this off thread.
AutoThreadSafeAccess ts(this);
return !getFixedSlot(RESERVED_SLOTS).isFalse();
}

View File

@ -1026,13 +1026,11 @@ class Shape : public gc::BarrieredCell<Shape>
void popFront() {
JS_ASSERT(!empty());
AutoThreadSafeAccess ts(cursor);
cursor = cursor->parent;
}
};
const Class *getObjectClass() const {
AutoThreadSafeAccess ts(base());
return base()->clasp;
}
JSObject *getObjectParent() const { return base()->parent; }
@ -1092,7 +1090,6 @@ class Shape : public gc::BarrieredCell<Shape>
};
bool inDictionary() const {
AutoThreadSafeAccess ts(this);
return (flags & IN_DICTIONARY) != 0;
}
unsigned getFlags() const { return flags & PUBLIC_FLAGS; }
@ -1158,20 +1155,14 @@ class Shape : public gc::BarrieredCell<Shape>
BaseShape *base() const { return base_.get(); }
bool hasSlot() const {
AutoThreadSafeAccess ts(this);
return (attrs & JSPROP_SHARED) == 0;
}
uint32_t slot() const { JS_ASSERT(hasSlot() && !hasMissingSlot()); return maybeSlot(); }
uint32_t maybeSlot() const {
// Note: Reading a shape's slot off thread can race against main thread
// updates to the number of linear searches on the shape, which is
// stored in the same slotInfo field. We tolerate this.
AutoThreadSafeAccess ts(this);
return slotInfo & SLOT_MASK;
}
bool isEmptyShape() const {
AutoThreadSafeAccess ts(this);
JS_ASSERT_IF(JSID_IS_EMPTY(propid_), hasMissingSlot());
return JSID_IS_EMPTY(propid_);
}
@ -1193,8 +1184,6 @@ class Shape : public gc::BarrieredCell<Shape>
}
uint32_t numFixedSlots() const {
// Note: The same race applies here as in maybeSlot().
AutoThreadSafeAccess ts(this);
return (slotInfo >> FIXED_SLOTS_SHIFT);
}
@ -1216,7 +1205,6 @@ class Shape : public gc::BarrieredCell<Shape>
}
const EncapsulatedId &propid() const {
AutoThreadSafeAccess ts(this);
JS_ASSERT(!isEmptyShape());
JS_ASSERT(!JSID_IS_VOID(propid_));
return propid_;
@ -1224,7 +1212,6 @@ class Shape : public gc::BarrieredCell<Shape>
EncapsulatedId &propidRef() { JS_ASSERT(!JSID_IS_VOID(propid_)); return propid_; }
jsid propidRaw() const {
// Return the actual jsid, not an internal reference.
AutoThreadSafeAccess ts(this);
return propid();
}
@ -1241,8 +1228,6 @@ class Shape : public gc::BarrieredCell<Shape>
bool configurable() const { return (attrs & JSPROP_PERMANENT) == 0; }
bool enumerable() const { return (attrs & JSPROP_ENUMERATE) != 0; }
bool writable() const {
// JS_ASSERT(isDataDescriptor());
AutoThreadSafeAccess ts(this);
return (attrs & JSPROP_READONLY) == 0;
}
bool hasGetterValue() const { return attrs & JSPROP_GETTER; }
@ -1279,10 +1264,6 @@ class Shape : public gc::BarrieredCell<Shape>
uint32_t entryCount() {
if (hasTable())
return table().entryCount;
return entryCountForCompilation();
}
uint32_t entryCountForCompilation() {
uint32_t count = 0;
for (Shape::Range<NoGC> r(this); !r.empty(); r.popFront())
++count;
@ -1649,7 +1630,6 @@ Shape::searchLinear(jsid id)
JS_ASSERT(!inDictionary());
for (Shape *shape = this; shape; ) {
AutoThreadSafeAccess ts(shape);
if (shape->propidRef() == id)
return shape;
shape = shape->parent;

View File

@ -382,7 +382,6 @@ class JSString : public js::gc::BarrieredCell<JSString>
MOZ_ALWAYS_INLINE
JSAtom &asAtom() const {
js::AutoThreadSafeAccess ts(this);
JS_ASSERT(isAtom());
return *(JSAtom *)this;
}
@ -1015,7 +1014,6 @@ JSString::base() const
inline js::PropertyName *
JSAtom::asPropertyName()
{
js::AutoThreadSafeAccess ts(this);
#ifdef DEBUG
uint32_t dummy;
JS_ASSERT(!isIndex(&dummy));

View File

@ -1195,8 +1195,6 @@ TypedArrayObject::isArrayIndex(jsid id, uint32_t *ip)
void
TypedArrayObject::neuter(JSContext *cx)
{
AutoLockForCompilation lock(cx);
setSlot(LENGTH_SLOT, Int32Value(0));
setSlot(BYTELENGTH_SLOT, Int32Value(0));
setSlot(BYTEOFFSET_SLOT, Int32Value(0));

View File

@ -311,11 +311,9 @@ class TypedArrayObject : public ArrayBufferViewObject
return tarr->getFixedSlot(BYTEOFFSET_SLOT);
}
static Value byteLengthValue(TypedArrayObject *tarr) {
AutoThreadSafeAccess ts(tarr);
return tarr->getFixedSlot(BYTELENGTH_SLOT);
}
static Value lengthValue(TypedArrayObject *tarr) {
AutoThreadSafeAccess ts(tarr);
return tarr->getFixedSlot(LENGTH_SLOT);
}
@ -333,11 +331,9 @@ class TypedArrayObject : public ArrayBufferViewObject
}
uint32_t type() const {
AutoThreadSafeAccess ts(this);
return getFixedSlot(TYPE_SLOT).toInt32();
}
void *viewData() const {
AutoThreadSafeAccess ts(this);
return static_cast<void*>(getPrivate(DATA_SLOT));
}

View File

@ -177,8 +177,10 @@ CacheFile::~CacheFile()
LOG(("CacheFile::~CacheFile() [this=%p]", this));
MutexAutoLock lock(mLock);
if (!mMemoryOnly)
if (!mMemoryOnly && mReady) {
// mReady flag indicates we have metadata plus in a valid state.
WriteMetadataIfNeededLocked(true);
}
}
nsresult
@ -1335,6 +1337,11 @@ CacheFile::WriteMetadataIfNeededLocked(bool aFireAndForget)
AssertOwnsLock();
MOZ_ASSERT(!mMemoryOnly);
if (!mMetadata) {
MOZ_CRASH("Must have metadata here");
return;
}
if (!aFireAndForget) {
// if aFireAndForget is set, we are called from dtor. Write
// scheduler hard-refers CacheFile otherwise, so we cannot be here.

View File

@ -916,7 +916,12 @@ CacheFileIOManager::OnProfile()
{
LOG(("CacheFileIOManager::OnProfile() [gInstance=%p]", gInstance));
MOZ_ASSERT(gInstance);
nsRefPtr<CacheFileIOManager> ioMan = gInstance;
if (!ioMan) {
// CacheFileIOManager::Init() failed, probably could not create the IO
// thread, just go with it...
return NS_ERROR_NOT_INITIALIZED;
}
nsresult rv;
@ -941,10 +946,10 @@ CacheFileIOManager::OnProfile()
}
if (directory) {
rv = directory->Clone(getter_AddRefs(gInstance->mCacheDirectory));
rv = directory->Clone(getter_AddRefs(ioMan->mCacheDirectory));
NS_ENSURE_SUCCESS(rv, rv);
rv = gInstance->mCacheDirectory->Append(NS_LITERAL_STRING("cache2"));
rv = ioMan->mCacheDirectory->Append(NS_LITERAL_STRING("cache2"));
NS_ENSURE_SUCCESS(rv, rv);
}

View File

@ -13,7 +13,10 @@ elif CONFIG['OS_ARCH'] == 'WINNT':
EXPORT_LIBRARY = True
FORCE_STATIC_LIB = True
DIRS += ['win/src/sandboxbroker']
DIRS += [
'win/src/sandboxbroker',
'win/src/sandboxtarget',
]
SOURCES += [
'chromium/base/at_exit.cc',

View File

@ -23,16 +23,26 @@ SandboxBroker::SandboxBroker()
sBrokerService = nullptr;
}
}
// We'll start to increase the restrictions over time.
mPolicy = sBrokerService->CreatePolicy();
}
}
bool
SandboxBroker::AllowPipe(const wchar_t *aPath)
{
return mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES,
sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, aPath);
}
bool
SandboxBroker::LaunchApp(const wchar_t *aPath,
const wchar_t *aArguments,
void **aProcessHandle)
{
// If the broker service isn't already initialized, do it now
if (!sBrokerService) {
if (!sBrokerService || !mPolicy) {
return false;
}
@ -40,16 +50,15 @@ SandboxBroker::LaunchApp(const wchar_t *aPath,
// Medium integrity, unrestricted, in the same window station, within the
// same desktop, and has no job object.
// We'll start to increase the restrictions over time.
sandbox::TargetPolicy *policy = sBrokerService->CreatePolicy();
policy->SetJobLevel(sandbox::JOB_NONE, 0);
policy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
sandbox::USER_RESTRICTED_SAME_ACCESS);
policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_MEDIUM);
mPolicy->SetJobLevel(sandbox::JOB_NONE, 0);
mPolicy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
sandbox::USER_RESTRICTED_SAME_ACCESS);
mPolicy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_UNTRUSTED);
// Ceate the sandboxed process
PROCESS_INFORMATION targetInfo;
sandbox::ResultCode result;
result = sBrokerService->SpawnTarget(aPath, aArguments, policy, &targetInfo);
result = sBrokerService->SpawnTarget(aPath, aArguments, mPolicy, &targetInfo);
// The sandboxed process is started in a suspended state, resumeit now that
// we'eve set things up.
@ -59,13 +68,15 @@ SandboxBroker::LaunchApp(const wchar_t *aPath,
// Return the process handle to the caller
*aProcessHandle = targetInfo.hProcess;
policy->Release();
return true;
}
SandboxBroker::~SandboxBroker()
{
if (mPolicy) {
mPolicy->Release();
mPolicy = nullptr;
}
}
}

View File

@ -15,6 +15,7 @@
namespace sandbox {
class BrokerServices;
class TargetPolicy;
}
namespace mozilla {
@ -23,12 +24,14 @@ class SANDBOX_EXPORT SandboxBroker
{
public:
SandboxBroker();
bool AllowPipe(const wchar_t *aPath);
bool LaunchApp(const wchar_t *aPath, const wchar_t *aArguments,
void **aProcessHandle);
virtual ~SandboxBroker();
private:
static sandbox::BrokerServices *sBrokerService;
sandbox::TargetPolicy *mPolicy;
};
} // mozilla

View File

@ -0,0 +1,9 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
EXPORTS.mozilla += [
'sandboxTarget.h',
]

View File

@ -0,0 +1,65 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 __SECURITY_SANDBOX_SANDBOXTARGET_H__
#define __SECURITY_SANDBOX_SANDBOXTARGET_H__
#ifdef TARGET_SANDBOX_EXPORTS
#define TARGET_SANDBOX_EXPORT __declspec(dllexport)
#else
#define TARGET_SANDBOX_EXPORT __declspec(dllimport)
#endif
namespace mozilla {
class TARGET_SANDBOX_EXPORT SandboxTarget
{
public:
typedef void (*StartSandboxPtr)();
/**
* Obtains a pointer to the singleton instance
*/
static SandboxTarget* Instance()
{
static SandboxTarget sb;
return &sb;
}
/**
* Called by the application that will lower the sandbox token
*
* @param aStartSandboxCallback A callback function which will lower privs
*/
void SetStartSandboxCallback(StartSandboxPtr aStartSandboxCallback)
{
mStartSandboxCallback = aStartSandboxCallback;
}
/**
* Called by the library that wants to start the sandbox, which in turn
* calls into the previously set StartSandboxCallback.
*/
void StartSandbox()
{
if (mStartSandboxCallback) {
mStartSandboxCallback();
}
}
protected:
SandboxTarget() :
mStartSandboxCallback(nullptr)
{
}
StartSandboxPtr mStartSandboxCallback;
};
} // mozilla
#endif

View File

@ -99,10 +99,11 @@ this.BookmarkJSONUtils = Object.freeze({
Components.utils.reportError("Unable to report telemetry.");
}
// Write to the temp folder first, to avoid leaving back partial files.
let tmpPath = OS.Path.join(OS.Constants.Path.tmpDir,
OS.Path.basename(aFilePath) + ".tmp");
yield OS.File.writeAtomic(aFilePath, jsonString, { tmpPath: tmpPath });
// Do not write to the tmp folder, otherwise if it has a different
// filesystem writeAtomic will fail. Eventual dangling .tmp files should
// be cleaned up by the caller.
yield OS.File.writeAtomic(aFilePath, jsonString,
{ tmpPath: OS.Path.join(aFilePath + ".tmp") });
return count;
});
},

View File

@ -132,6 +132,13 @@ this.PlacesBackups = {
let backupFolderPath = yield this.getBackupFolder();
let iterator = new OS.File.DirectoryIterator(backupFolderPath);
yield iterator.forEach(function(aEntry) {
// Since this is a lazy getter and OS.File I/O is serialized, we can
// safely remove .tmp files without risking to remove ongoing backups.
if (aEntry.name.endsWith(".tmp")) {
OS.File.remove(aEntry.path);
return;
}
let matches = aEntry.name.match(this._filenamesRegex);
if (matches) {
// Remove bogus backups in future dates.