From 017cbb1f8d17fd431ca1e2fbbacf954c10ab8f7b Mon Sep 17 00:00:00 2001 From: Roy Tam Date: Sat, 30 May 2020 08:12:41 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - more pointer style... take away, put again... (640edf447) - Bug 1139683 - Rewrite SetExistingProperty with comments and references to the standard. r=efaust. (0da1e634b) - Bug 1142775 - Rename NativeSet -> NativeSetExistingDataProperty and simplify it since it is only called for data properties. Delete Shape::set. Add comments. No change in behavior. r=efaust. (1fec7be0a) - Bug 1142794 - Change 'receiver' argument to SetProperty functions and ProxyHandler::set methods to be a HandleValue. r=Waldo. (032f78c22) - Bug 1149377 - Disable PGO on ICCallStubCompiler::guardFunApply. r=jandem (aa0617c41) - Revert Bug 1137180 - Allow unboxed objects to be extended with new properties, r=jandem. (1970f92f0) - Bug 1137180 - Add most functionality necessary for extensible unboxed objects, r=jandem. (30768aa93) - Bug 1137180 - Add baseline caches for extensible unboxed objects, and enable extensible unboxed objects (still off by default), r=jandem. (8c6aa02f9) - Bug 1143011 - Extract the has/add/take logic out of the register sets to distinguish between allocatable and live sets. r=jandem,Waldo (430b0830f) - Bug 1143011 - Use AllocatableSet or LiveSet for all register set uses. r=jandem (69dc22ad9) - Bug 1150384 - IonMonkey: MIPS: Fix build failure caused by Bug 1143011. r=rankov (f532d5095) - Bug 1145811 - Remove simdSet argument of PushRegsInMask. r=bbouvier (7c1dd4847) - Bug 1148880 - Make Trampoline-arm.cpp compile with Clang again. r=nbp (b89564285) - Bump the XDR version two more to account for yet more branch-versioning oddities. No bug, r=me as trivial, DONTBUILD because really building bytecode-bumping patchwork twice is just too much for an opaque identifier that we already built once, pushing in a CLOSED TREE because version bumps are risk-free and these versions are needed for a branch backport and otherwise I'm spinning wheels waiting on the tree to reopen right now (ab7ac9762) - partial of Bug 1144366 - Switch SpiderMonkey and XPConnect style from |T *t| to |T* t|. r=jorendorff (9e27b1ba4) - Bug 1134626 part 1 - Move all x86-shared files into their own directory. r=jandem (6267cdb05) - Bug 1134626 part 2 - Move x86 & x64 Architecture into a shared file. r=jandem (467731dfc) --- dom/base/nsGlobalWindow.cpp | 11 +- dom/bindings/Codegen.py | 30 +- dom/bindings/DOMJSProxyHandler.cpp | 11 +- dom/bindings/DOMJSProxyHandler.h | 6 +- js/ipc/JavaScriptBase.h | 14 +- js/ipc/PJavaScript.ipdl | 2 +- js/ipc/WrapperAnswer.cpp | 21 +- js/ipc/WrapperAnswer.h | 5 +- js/ipc/WrapperOwner.cpp | 61 +- js/ipc/WrapperOwner.h | 9 +- js/public/Class.h | 38 +- js/public/Proxy.h | 9 +- js/public/TrackedOptimizationInfo.h | 12 +- js/src/asmjs/AsmJSValidate.cpp | 61 +- js/src/builtin/Intl.h | 2 +- js/src/builtin/RegExp.h | 4 +- js/src/builtin/TypedObject.cpp | 20 +- js/src/builtin/TypedObject.h | 4 +- js/src/ds/IdValuePair.h | 2 +- js/src/frontend/BytecodeEmitter.cpp | 88 +- js/src/gc/Allocator.cpp | 64 +- js/src/gc/Allocator.h | 10 +- js/src/gc/Iteration.cpp | 4 +- js/src/gc/Marking.cpp | 232 ++--- js/src/gc/Nursery.cpp | 4 +- js/src/gc/Statistics.h | 4 +- js/src/gc/StoreBuffer.cpp | 4 +- .../irregexp/NativeRegExpMacroAssembler.cpp | 6 +- js/src/irregexp/NativeRegExpMacroAssembler.h | 4 +- js/src/jit/AlignmentMaskAnalysis.cpp | 2 +- js/src/jit/AlignmentMaskAnalysis.h | 4 +- js/src/jit/BacktrackingAllocator.cpp | 10 +- js/src/jit/BaselineCompiler.cpp | 13 +- js/src/jit/BaselineDebugModeOSR.cpp | 4 +- js/src/jit/BaselineIC.cpp | 399 ++++----- js/src/jit/BaselineIC.h | 96 +- js/src/jit/BaselineInspector.cpp | 2 +- js/src/jit/CodeGenerator.cpp | 56 +- js/src/jit/CodeGenerator.h | 8 +- js/src/jit/EagerSimdUnbox.cpp | 40 +- js/src/jit/EagerSimdUnbox.h | 2 +- js/src/jit/IonCaches.cpp | 143 +-- js/src/jit/IonCaches.h | 16 +- js/src/jit/JitCommon.h | 6 +- js/src/jit/JitFrames.cpp | 38 +- js/src/jit/JitcodeMap.cpp | 120 +-- js/src/jit/LIR.h | 22 +- js/src/jit/LinearScan.cpp | 29 +- js/src/jit/LiveRangeAllocator.cpp | 14 +- js/src/jit/Lowering.cpp | 28 +- js/src/jit/MIRGraph.cpp | 2 +- js/src/jit/MacroAssembler.cpp | 115 ++- js/src/jit/MacroAssembler.h | 18 +- js/src/jit/MoveEmitter.h | 2 +- js/src/jit/RegisterAllocator.cpp | 4 +- js/src/jit/RegisterAllocator.h | 2 +- js/src/jit/RegisterSets.h | 832 +++++++++++++----- js/src/jit/Registers.h | 11 +- js/src/jit/Safepoints.cpp | 10 +- js/src/jit/Safepoints.h | 20 +- js/src/jit/StupidAllocator.cpp | 10 +- js/src/jit/TypePolicy.cpp | 34 +- js/src/jit/VMFunctions.cpp | 7 +- js/src/jit/arm/Architecture-arm.cpp | 6 +- js/src/jit/arm/Architecture-arm.h | 34 +- js/src/jit/arm/BaselineIC-arm.cpp | 4 +- js/src/jit/arm/Lowering-arm.cpp | 2 +- js/src/jit/arm/MacroAssembler-arm.cpp | 14 +- js/src/jit/arm/MoveEmitter-arm.cpp | 2 +- js/src/jit/arm/MoveEmitter-arm.h | 2 +- js/src/jit/arm/Trampoline-arm.cpp | 14 +- js/src/jit/mips/Architecture-mips.cpp | 6 +- js/src/jit/mips/Architecture-mips.h | 9 + js/src/jit/mips/BaselineIC-mips.cpp | 4 +- js/src/jit/mips/Lowering-mips.cpp | 2 +- js/src/jit/mips/MacroAssembler-mips.cpp | 6 +- js/src/jit/mips/MoveEmitter-mips.cpp | 2 +- js/src/jit/mips/MoveEmitter-mips.h | 2 +- js/src/jit/mips/Trampoline-mips.cpp | 10 +- js/src/jit/none/Architecture-none.h | 1 + js/src/jit/none/Trampoline-none.cpp | 10 +- js/src/jit/shared/CodeGenerator-shared-inl.h | 8 +- js/src/jit/shared/CodeGenerator-shared.cpp | 27 +- js/src/jit/shared/CodeGenerator-shared.h | 38 +- js/src/jit/x64/Assembler-x64.cpp | 49 +- js/src/jit/x64/Assembler-x64.h | 2 +- js/src/jit/x64/BaselineCompiler-x64.h | 2 +- js/src/jit/x64/CodeGenerator-x64.h | 2 +- js/src/jit/x64/Lowering-x64.cpp | 16 +- js/src/jit/x64/Lowering-x64.h | 2 +- js/src/jit/x64/MacroAssembler-x64.h | 8 +- js/src/jit/x64/Trampoline-x64.cpp | 20 +- .../x86-shared/Architecture-x86-shared.cpp | 98 +++ .../Architecture-x86-shared.h} | 198 +++-- .../Assembler-x86-shared.cpp | 29 - .../Assembler-x86-shared.h | 12 +- .../AssemblerBuffer-x86-shared.cpp | 2 +- .../AssemblerBuffer-x86-shared.h | 6 +- .../BaseAssembler-x86-shared.h | 12 +- .../BaselineCompiler-x86-shared.cpp | 2 +- .../BaselineCompiler-x86-shared.h | 6 +- .../BaselineIC-x86-shared.cpp | 0 .../CodeGenerator-x86-shared.cpp | 2 +- .../CodeGenerator-x86-shared.h | 6 +- .../Constants-x86-shared.h | 6 +- .../Disassembler-x86-shared.cpp | 2 +- .../Encoding-x86-shared.h | 8 +- .../{shared => x86-shared}/LIR-x86-shared.h | 6 +- .../Lowering-x86-shared.cpp | 2 +- .../Lowering-x86-shared.h | 6 +- .../MacroAssembler-x86-shared.cpp | 79 +- .../MacroAssembler-x86-shared.h | 186 ++-- .../MoveEmitter-x86-shared.cpp | 4 +- .../MoveEmitter-x86-shared.h | 2 +- .../Patching-x86-shared.h | 6 +- js/src/jit/x86/Architecture-x86.h | 340 ------- js/src/jit/x86/Assembler-x86.cpp | 42 +- js/src/jit/x86/Assembler-x86.h | 4 +- js/src/jit/x86/BaselineCompiler-x86.h | 2 +- js/src/jit/x86/CodeGenerator-x86.h | 2 +- js/src/jit/x86/Lowering-x86.cpp | 16 +- js/src/jit/x86/Lowering-x86.h | 2 +- js/src/jit/x86/MacroAssembler-x86.h | 6 +- js/src/jit/x86/Trampoline-x86.cpp | 25 +- js/src/js.msg | 1 + js/src/jsapi-tests/moz.build | 1 + js/src/jsapi-tests/testJitRegisterSet.cpp | 138 +++ .../testSetPropertyIgnoringNamedGetter.cpp | 6 +- js/src/jsapi.cpp | 102 +-- js/src/jsarray.cpp | 12 +- js/src/jsfriendapi.h | 24 +- js/src/jsgc.h | 30 +- js/src/jsgcinlines.h | 12 +- js/src/jsobj.cpp | 31 +- js/src/jsobj.h | 142 +-- js/src/jsobjinlines.h | 80 +- js/src/jsstr.cpp | 14 +- js/src/jswrapper.h | 4 +- js/src/moz.build | 19 +- js/src/proxy/BaseProxyHandler.cpp | 33 +- js/src/proxy/CrossCompartmentWrapper.cpp | 13 +- js/src/proxy/DeadObjectProxy.cpp | 4 +- js/src/proxy/DirectProxyHandler.cpp | 6 +- js/src/proxy/Proxy.cpp | 14 +- js/src/proxy/Proxy.h | 4 +- js/src/proxy/ScriptedDirectProxyHandler.cpp | 12 +- js/src/proxy/ScriptedDirectProxyHandler.h | 4 +- js/src/proxy/ScriptedIndirectProxyHandler.cpp | 50 +- js/src/proxy/ScriptedIndirectProxyHandler.h | 8 +- js/src/shell/jsoptparse.cpp | 8 +- js/src/vm/Debugger.cpp | 2 +- js/src/vm/DebuggerMemory.h | 30 +- js/src/vm/GlobalObject.h | 6 +- js/src/vm/Interpreter-inl.h | 11 +- js/src/vm/Interpreter.cpp | 65 +- js/src/vm/Interpreter.h | 8 +- js/src/vm/NativeObject-inl.h | 6 +- js/src/vm/NativeObject.cpp | 233 ++--- js/src/vm/NativeObject.h | 32 +- js/src/vm/ObjectGroup.cpp | 68 +- js/src/vm/Runtime-inl.h | 20 +- js/src/vm/Runtime.h | 8 +- js/src/vm/SavedStacks.cpp | 72 +- js/src/vm/SavedStacks.h | 4 +- js/src/vm/ScopeObject.cpp | 30 +- js/src/vm/SelfHosting.cpp | 4 +- js/src/vm/Shape-inl.h | 32 +- js/src/vm/Shape.h | 11 +- js/src/vm/Symbol.cpp | 22 +- js/src/vm/UnboxedObject.cpp | 28 +- js/src/vm/UnboxedObject.h | 4 +- js/src/vm/Xdr.h | 4 +- js/xpconnect/src/Sandbox.cpp | 6 +- js/xpconnect/wrappers/AddonWrapper.cpp | 12 +- js/xpconnect/wrappers/AddonWrapper.h | 5 +- js/xpconnect/wrappers/ChromeObjectWrapper.cpp | 9 +- js/xpconnect/wrappers/ChromeObjectWrapper.h | 5 +- js/xpconnect/wrappers/XrayWrapper.cpp | 8 +- js/xpconnect/wrappers/XrayWrapper.h | 16 +- mfbt/Attributes.h | 13 +- 180 files changed, 2974 insertions(+), 2856 deletions(-) create mode 100644 js/src/jit/x86-shared/Architecture-x86-shared.cpp rename js/src/jit/{x64/Architecture-x64.h => x86-shared/Architecture-x86-shared.h} (77%) rename js/src/jit/{shared => x86-shared}/Assembler-x86-shared.cpp (90%) rename js/src/jit/{shared => x86-shared}/Assembler-x86-shared.h (99%) rename js/src/jit/{shared => x86-shared}/AssemblerBuffer-x86-shared.cpp (93%) rename js/src/jit/{shared => x86-shared}/AssemblerBuffer-x86-shared.h (97%) rename js/src/jit/{shared => x86-shared}/BaseAssembler-x86-shared.h (99%) rename js/src/jit/{shared => x86-shared}/BaselineCompiler-x86-shared.cpp (90%) rename js/src/jit/{shared => x86-shared}/BaselineCompiler-x86-shared.h (78%) rename js/src/jit/{shared => x86-shared}/BaselineIC-x86-shared.cpp (100%) rename js/src/jit/{shared => x86-shared}/CodeGenerator-x86-shared.cpp (99%) rename js/src/jit/{shared => x86-shared}/CodeGenerator-x86-shared.h (98%) rename js/src/jit/{shared => x86-shared}/Constants-x86-shared.h (97%) rename js/src/jit/{shared => x86-shared}/Disassembler-x86-shared.cpp (99%) rename js/src/jit/{shared => x86-shared}/Encoding-x86-shared.h (98%) rename js/src/jit/{shared => x86-shared}/LIR-x86-shared.h (98%) rename js/src/jit/{shared => x86-shared}/Lowering-x86-shared.cpp (99%) rename js/src/jit/{shared => x86-shared}/Lowering-x86-shared.h (95%) rename js/src/jit/{shared => x86-shared}/MacroAssembler-x86-shared.cpp (77%) rename js/src/jit/{shared => x86-shared}/MacroAssembler-x86-shared.h (89%) rename js/src/jit/{shared => x86-shared}/MoveEmitter-x86-shared.cpp (99%) rename js/src/jit/{shared => x86-shared}/MoveEmitter-x86-shared.h (99%) rename js/src/jit/{shared => x86-shared}/Patching-x86-shared.h (95%) delete mode 100644 js/src/jit/x86/Architecture-x86.h create mode 100644 js/src/jsapi-tests/testJitRegisterSet.cpp diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 67e1ff844e..10ffdda992 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -645,9 +645,8 @@ public: JS::Handle id, JS::MutableHandle vp) const override; virtual bool set(JSContext *cx, JS::Handle proxy, - JS::Handle receiver, - JS::Handle id, - JS::MutableHandle vp, + JS::Handle id, JS::Handle v, + JS::Handle receiver, JS::ObjectOpResult &result) const override; // SpiderMonkey extensions @@ -911,9 +910,9 @@ nsOuterWindowProxy::get(JSContext *cx, JS::Handle proxy, bool nsOuterWindowProxy::set(JSContext *cx, JS::Handle proxy, - JS::Handle receiver, JS::Handle id, - JS::MutableHandle vp, + JS::Handle v, + JS::Handle receiver, JS::ObjectOpResult &result) const { int32_t index = GetArrayIndexFromId(cx, id); @@ -923,7 +922,7 @@ nsOuterWindowProxy::set(JSContext *cx, JS::Handle proxy, return result.failReadOnly(); } - return js::Wrapper::set(cx, proxy, receiver, id, vp, result); + return js::Wrapper::set(cx, proxy, id, v, receiver, result); } bool diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index ff3bbb1c53..be0f73652f 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -9822,7 +9822,7 @@ class CGProxySpecialOperation(CGPerSignatureCall): false. """ def __init__(self, descriptor, operation, checkFound=True, - argumentMutableValue=None, resultVar=None, foundVar=None): + argumentHandleValue=None, resultVar=None, foundVar=None): self.checkFound = checkFound self.foundVar = foundVar or "found" @@ -9847,12 +9847,12 @@ class CGProxySpecialOperation(CGPerSignatureCall): treatNullAs=argument.treatNullAs, sourceDescription=("value being assigned to %s setter" % descriptor.interface.identifier.name)) - if argumentMutableValue is None: - argumentMutableValue = "desc.value()" + if argumentHandleValue is None: + argumentHandleValue = "desc.value()" templateValues = { "declName": argument.identifier.name, "holderName": argument.identifier.name + "_holder", - "val": argumentMutableValue, + "val": argumentHandleValue, "obj": "obj", "passedToJSImpl": "false" } @@ -9897,10 +9897,10 @@ class CGProxyIndexedOperation(CGProxySpecialOperation): foundVar: See the docstring for CGProxySpecialOperation. """ def __init__(self, descriptor, name, doUnwrap=True, checkFound=True, - argumentMutableValue=None, resultVar=None, foundVar=None): + argumentHandleValue=None, resultVar=None, foundVar=None): self.doUnwrap = doUnwrap CGProxySpecialOperation.__init__(self, descriptor, name, checkFound, - argumentMutableValue=argumentMutableValue, + argumentHandleValue=argumentHandleValue, resultVar=resultVar, foundVar=foundVar) @@ -9958,9 +9958,9 @@ class CGProxyIndexedSetter(CGProxyIndexedOperation): """ Class to generate a call to an indexed setter. """ - def __init__(self, descriptor, argumentMutableValue=None): + def __init__(self, descriptor, argumentHandleValue=None): CGProxyIndexedOperation.__init__(self, descriptor, 'IndexedSetter', - argumentMutableValue=argumentMutableValue) + argumentHandleValue=argumentHandleValue) class CGProxyIndexedDeleter(CGProxyIndexedOperation): @@ -9988,10 +9988,10 @@ class CGProxyNamedOperation(CGProxySpecialOperation): foundVar: See the docstring for CGProxySpecialOperation. """ - def __init__(self, descriptor, name, value=None, argumentMutableValue=None, + def __init__(self, descriptor, name, value=None, argumentHandleValue=None, resultVar=None, foundVar=None): CGProxySpecialOperation.__init__(self, descriptor, name, - argumentMutableValue=argumentMutableValue, + argumentHandleValue=argumentHandleValue, resultVar=resultVar, foundVar=foundVar) self.value = value @@ -10089,9 +10089,9 @@ class CGProxyNamedSetter(CGProxyNamedOperation): """ Class to generate a call to a named setter. """ - def __init__(self, descriptor, argumentMutableValue=None): + def __init__(self, descriptor, argumentHandleValue=None): CGProxyNamedOperation.__init__(self, descriptor, 'NamedSetter', - argumentMutableValue=argumentMutableValue) + argumentHandleValue=argumentHandleValue) class CGProxyNamedDeleter(CGProxyNamedOperation): @@ -10708,7 +10708,7 @@ class CGDOMJSProxyHandler_setCustom(ClassMethod): args = [Argument('JSContext*', 'cx'), Argument('JS::Handle', 'proxy'), Argument('JS::Handle', 'id'), - Argument('JS::MutableHandle', 'vp'), + Argument('JS::Handle', 'v'), Argument('bool*', 'done')] ClassMethod.__init__(self, "setCustom", "bool", args, virtual=True, override=True, const=True) self.descriptor = descriptor @@ -10733,7 +10733,7 @@ class CGDOMJSProxyHandler_setCustom(ClassMethod): raise ValueError("In interface " + self.descriptor.name + ": " + "Can't cope with [OverrideBuiltins] and unforgeable members") - callSetter = CGProxyNamedSetter(self.descriptor, argumentMutableValue="vp") + callSetter = CGProxyNamedSetter(self.descriptor, argumentHandleValue="v") return (assertion + callSetter.define() + "*done = true;\n" @@ -10758,7 +10758,7 @@ class CGDOMJSProxyHandler_setCustom(ClassMethod): """, callSetter=CGProxyIndexedSetter(self.descriptor, - argumentMutableValue="vp").define()) + argumentHandleValue="v").define()) else: setIndexed = "" diff --git a/dom/bindings/DOMJSProxyHandler.cpp b/dom/bindings/DOMJSProxyHandler.cpp index fd91dba6a5..645cd9d7b6 100644 --- a/dom/bindings/DOMJSProxyHandler.cpp +++ b/dom/bindings/DOMJSProxyHandler.cpp @@ -223,13 +223,14 @@ DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle proxy, JS:: } bool -DOMProxyHandler::set(JSContext *cx, Handle proxy, Handle receiver, - Handle id, MutableHandle vp, ObjectOpResult &result) const +DOMProxyHandler::set(JSContext *cx, Handle proxy, Handle id, + Handle v, Handle receiver, + ObjectOpResult &result) const { MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy), "Should not have a XrayWrapper here"); bool done; - if (!setCustom(cx, proxy, id, vp, &done)) { + if (!setCustom(cx, proxy, id, v, &done)) { return false; } if (done) { @@ -256,7 +257,7 @@ DOMProxyHandler::set(JSContext *cx, Handle proxy, Handle r } } - return js::SetPropertyIgnoringNamedGetter(cx, proxy, id, vp, receiver, desc, result); + return js::SetPropertyIgnoringNamedGetter(cx, proxy, id, v, receiver, desc, result); } bool @@ -354,7 +355,7 @@ IdToInt32(JSContext* cx, JS::Handle id) bool DOMProxyHandler::setCustom(JSContext* cx, JS::Handle proxy, JS::Handle id, - JS::MutableHandle vp, bool *done) const + JS::Handle v, bool *done) const { *done = false; return true; diff --git a/dom/bindings/DOMJSProxyHandler.h b/dom/bindings/DOMJSProxyHandler.h index 6d53cc98e3..c154fe2a64 100644 --- a/dom/bindings/DOMJSProxyHandler.h +++ b/dom/bindings/DOMJSProxyHandler.h @@ -122,8 +122,8 @@ public: const override; bool has(JSContext* cx, JS::Handle proxy, JS::Handle id, bool* bp) const override; - bool set(JSContext *cx, JS::Handle proxy, JS::Handle receiver, - JS::Handle id, JS::MutableHandle vp, JS::ObjectOpResult &result) + bool set(JSContext *cx, JS::Handle proxy, JS::Handle id, + JS::Handle v, JS::Handle receiver, JS::ObjectOpResult &result) const override; /* @@ -132,7 +132,7 @@ public: * *done to false. */ virtual bool setCustom(JSContext* cx, JS::Handle proxy, JS::Handle id, - JS::MutableHandle vp, bool *done) const; + JS::Handle v, bool *done) const; static JSObject* GetExpandoObject(JSObject* obj); diff --git a/js/ipc/JavaScriptBase.h b/js/ipc/JavaScriptBase.h index 8294999184..db399d9136 100644 --- a/js/ipc/JavaScriptBase.h +++ b/js/ipc/JavaScriptBase.h @@ -71,10 +71,9 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base ReturnStatus *rs, JSVariant *result) { return Answer::RecvGet(ObjectId::deserialize(objId), receiverVar, id, rs, result); } - bool RecvSet(const uint64_t &objId, const ObjectVariant &receiverVar, - const JSIDVariant &id, const JSVariant &value, ReturnStatus *rs, - JSVariant *result) { - return Answer::RecvSet(ObjectId::deserialize(objId), receiverVar, id, value, rs, result); + bool RecvSet(const uint64_t &objId, const JSIDVariant &id, const JSVariant &value, + const JSVariant &receiverVar, ReturnStatus *rs) { + return Answer::RecvSet(ObjectId::deserialize(objId), id, value, receiverVar, rs); } bool RecvIsExtensible(const uint64_t &objId, ReturnStatus *rs, @@ -161,10 +160,9 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base ReturnStatus *rs, JSVariant *result) { return Base::SendGet(objId.serialize(), receiverVar, id, rs, result); } - bool SendSet(const ObjectId &objId, const ObjectVariant &receiverVar, - const JSIDVariant &id, const JSVariant &value, ReturnStatus *rs, - JSVariant *result) { - return Base::SendSet(objId.serialize(), receiverVar, id, value, rs, result); + bool SendSet(const ObjectId &objId, const JSIDVariant &id, const JSVariant &value, + const JSVariant &receiverVar, ReturnStatus *rs) { + return Base::SendSet(objId.serialize(), id, value, receiverVar, rs); } bool SendIsExtensible(const ObjectId &objId, ReturnStatus *rs, diff --git a/js/ipc/PJavaScript.ipdl b/js/ipc/PJavaScript.ipdl index 89a6476a8d..4f000fdf28 100644 --- a/js/ipc/PJavaScript.ipdl +++ b/js/ipc/PJavaScript.ipdl @@ -33,7 +33,7 @@ both: prio(high) sync Has(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has); prio(high) sync HasOwn(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has); prio(high) sync Get(uint64_t objId, ObjectVariant receiver, JSIDVariant id) returns (ReturnStatus rs, JSVariant result); - prio(high) sync Set(uint64_t objId, ObjectVariant receiver, JSIDVariant id, JSVariant value) returns (ReturnStatus rs, JSVariant result); + prio(high) sync Set(uint64_t objId, JSIDVariant id, JSVariant value, JSVariant receiver) returns (ReturnStatus rs); prio(high) sync IsExtensible(uint64_t objId) returns (ReturnStatus rs, bool result); prio(high) sync CallOrConstruct(uint64_t objId, JSParam[] argv, bool construct) returns (ReturnStatus rs, JSVariant result, JSParam[] outparams); diff --git a/js/ipc/WrapperAnswer.cpp b/js/ipc/WrapperAnswer.cpp index 64833b4355..e17bbf28b0 100644 --- a/js/ipc/WrapperAnswer.cpp +++ b/js/ipc/WrapperAnswer.cpp @@ -308,26 +308,17 @@ WrapperAnswer::RecvGet(const ObjectId& objId, const ObjectVariant& receiverVar, } bool -WrapperAnswer::RecvSet(const ObjectId &objId, const ObjectVariant &receiverVar, - const JSIDVariant &idVar, const JSVariant &value, ReturnStatus *rs, - JSVariant *resultValue) +WrapperAnswer::RecvSet(const ObjectId &objId, const JSIDVariant &idVar, const JSVariant &value, + const JSVariant &receiverVar, ReturnStatus *rs) { // We may run scripted setters. AutoEntryScript aes(xpc::NativeGlobal(scopeForTargetObjects())); JSContext *cx = aes.cx(); - // The outparam will be written to the buffer, so it must be set even if - // the parent won't read it. - *resultValue = UndefinedVariant(); - RootedObject obj(cx, findObjectById(cx, objId)); if (!obj) return fail(cx, rs); - RootedObject receiver(cx, fromObjectVariant(cx, receiverVar)); - if (!receiver) - return fail(cx, rs); - LOG("set %s[%s] = %s", ReceiverObj(objId), Identifier(idVar), InVariant(value)); RootedId id(cx); @@ -338,12 +329,12 @@ WrapperAnswer::RecvSet(const ObjectId &objId, const ObjectVariant &receiverVar, if (!fromVariant(cx, value, &val)) return fail(cx, rs); - ObjectOpResult result; - RootedValue receiverVal(cx, ObjectValue(*receiver)); - if (!JS_ForwardSetPropertyTo(cx, obj, id, val, receiverVal, result)) + RootedValue receiver(cx); + if (!fromVariant(cx, receiverVar, &receiver)) return fail(cx, rs); - if (!toVariant(cx, val, resultValue)) + ObjectOpResult result; + if (!JS_ForwardSetPropertyTo(cx, obj, id, val, receiver, result)) return fail(cx, rs); return ok(rs, result); diff --git a/js/ipc/WrapperAnswer.h b/js/ipc/WrapperAnswer.h index 87e3ecf2be..30ae809904 100644 --- a/js/ipc/WrapperAnswer.h +++ b/js/ipc/WrapperAnswer.h @@ -37,9 +37,8 @@ class WrapperAnswer : public virtual JavaScriptShared bool RecvGet(const ObjectId &objId, const ObjectVariant &receiverVar, const JSIDVariant &id, ReturnStatus *rs, JSVariant *result); - bool RecvSet(const ObjectId &objId, const ObjectVariant &receiverVar, - const JSIDVariant &id, const JSVariant &value, ReturnStatus *rs, - JSVariant *result); + bool RecvSet(const ObjectId &objId, const JSIDVariant &id, const JSVariant &value, + const JSVariant &receiverVar, ReturnStatus *rs); bool RecvIsExtensible(const ObjectId &objId, ReturnStatus *rs, bool *result); diff --git a/js/ipc/WrapperOwner.cpp b/js/ipc/WrapperOwner.cpp index ff85b3dce4..f6d9ffba18 100644 --- a/js/ipc/WrapperOwner.cpp +++ b/js/ipc/WrapperOwner.cpp @@ -37,7 +37,7 @@ struct AuxCPOWData bool isCallable, bool isConstructor, bool isDOMObject, - const nsACString &objectTag) + const nsACString& objectTag) : id(id), isCallable(isCallable), isConstructor(isConstructor), @@ -110,9 +110,8 @@ class CPOWProxyHandler : public BaseProxyHandler virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const override; virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, MutableHandleValue vp) const override; - virtual bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver, - JS::HandleId id, JS::MutableHandleValue vp, - JS::ObjectOpResult &result) const override; + virtual bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleValue v, + JS::HandleValue receiver, JS::ObjectOpResult &result) const override; virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) const override; virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const override; @@ -182,14 +181,14 @@ WrapperOwner::getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId } bool -CPOWProxyHandler::getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, +CPOWProxyHandler::getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id, MutableHandle desc) const { FORWARD(getOwnPropertyDescriptor, (cx, proxy, id, desc)); } bool -WrapperOwner::getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, +WrapperOwner::getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id, MutableHandle desc) { ObjectId objId = idOf(proxy); @@ -212,17 +211,17 @@ WrapperOwner::getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, Handle } bool -CPOWProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId id, +CPOWProxyHandler::defineProperty(JSContext* cx, HandleObject proxy, HandleId id, Handle desc, - ObjectOpResult &result) const + ObjectOpResult& result) const { FORWARD(defineProperty, (cx, proxy, id, desc, result)); } bool -WrapperOwner::defineProperty(JSContext *cx, HandleObject proxy, HandleId id, +WrapperOwner::defineProperty(JSContext* cx, HandleObject proxy, HandleId id, Handle desc, - ObjectOpResult &result) + ObjectOpResult& result) { ObjectId objId = idOf(proxy); @@ -359,7 +358,7 @@ CPOWDOMQI(JSContext *cx, unsigned argc, Value *vp) } static bool -CPOWToString(JSContext *cx, unsigned argc, Value *vp) +CPOWToString(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject callee(cx, &args.callee()); @@ -413,7 +412,7 @@ WrapperOwner::toString(JSContext* cx, HandleObject cpow, JS::CallArgs& args) } bool -WrapperOwner::DOMQI(JSContext *cx, JS::HandleObject proxy, JS::CallArgs &args) +WrapperOwner::DOMQI(JSContext* cx, JS::HandleObject proxy, JS::CallArgs& args) { // Someone's calling us, handle nsISupports specially to avoid unnecessary // CPOW traffic. @@ -425,7 +424,7 @@ WrapperOwner::DOMQI(JSContext *cx, JS::HandleObject proxy, JS::CallArgs &args) nsresult rv = UnwrapArg(idobj, getter_AddRefs(jsid)); if (NS_SUCCEEDED(rv)) { MOZ_ASSERT(jsid, "bad wrapJS"); - const nsID *idptr = jsid->GetID(); + const nsID* idptr = jsid->GetID(); if (idptr->Equals(NS_GET_IID(nsISupports))) { args.rval().set(args.thisv()); return true; @@ -469,7 +468,7 @@ WrapperOwner::get(JSContext* cx, HandleObject proxy, HandleObject receiver, if (!toJSIDVariant(cx, id, &idVar)) return false; - AuxCPOWData *data = AuxCPOWDataOf(proxy); + AuxCPOWData* data = AuxCPOWDataOf(proxy); if (data->isDOMObject && idVar.type() == JSIDVariant::TnsString && idVar.get_nsString().EqualsLiteral("QueryInterface")) @@ -517,41 +516,37 @@ WrapperOwner::get(JSContext* cx, HandleObject proxy, HandleObject receiver, } bool -CPOWProxyHandler::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver, - JS::HandleId id, JS::MutableHandleValue vp, JS::ObjectOpResult &result) const +CPOWProxyHandler::set(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleValue v, + JS::HandleValue receiver, JS::ObjectOpResult& result) const { - FORWARD(set, (cx, proxy, receiver, id, vp, result)); + FORWARD(set, (cx, proxy, id, v, receiver, result)); } bool -WrapperOwner::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver, - JS::HandleId id, JS::MutableHandleValue vp, JS::ObjectOpResult &result) +WrapperOwner::set(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleValue v, + JS::HandleValue receiver, JS::ObjectOpResult& result) { ObjectId objId = idOf(proxy); - ObjectVariant receiverVar; - if (!toObjectVariant(cx, receiver, &receiverVar)) - return false; - JSIDVariant idVar; if (!toJSIDVariant(cx, id, &idVar)) return false; JSVariant val; - if (!toVariant(cx, vp, &val)) + if (!toVariant(cx, v, &val)) + return false; + + JSVariant receiverVar; + if (!toVariant(cx, receiver, &receiverVar)) return false; ReturnStatus status; - JSVariant resultValue; - if (!SendSet(objId, receiverVar, idVar, val, &status, &resultValue)) + if (!SendSet(objId, idVar, val, receiverVar, &status)) return ipcfail(cx); LOG_STACK(); - if (!ok(cx, status, result)) - return false; - - return fromVariant(cx, resultValue, vp); + return ok(cx, status, result); } bool @@ -767,13 +762,13 @@ WrapperOwner::className(JSContext* cx, HandleObject proxy) } bool -CPOWProxyHandler::getPrototype(JSContext *cx, HandleObject proxy, MutableHandleObject objp) const +CPOWProxyHandler::getPrototype(JSContext* cx, HandleObject proxy, MutableHandleObject objp) const { FORWARD(getPrototype, (cx, proxy, objp)); } bool -WrapperOwner::getPrototype(JSContext *cx, HandleObject proxy, MutableHandleObject objp) +WrapperOwner::getPrototype(JSContext* cx, HandleObject proxy, MutableHandleObject objp) { ObjectId objId = idOf(proxy); @@ -1022,7 +1017,7 @@ WrapperOwner::ok(JSContext* cx, const ReturnStatus& status) } bool -WrapperOwner::ok(JSContext *cx, const ReturnStatus &status, ObjectOpResult &result) +WrapperOwner::ok(JSContext* cx, const ReturnStatus& status, ObjectOpResult& result) { if (status.type() == ReturnStatus::TReturnObjectOpResult) return result.fail(status.get_ReturnObjectOpResult().code()); diff --git a/js/ipc/WrapperOwner.h b/js/ipc/WrapperOwner.h index 0987c0cd02..174aedbd28 100644 --- a/js/ipc/WrapperOwner.h +++ b/js/ipc/WrapperOwner.h @@ -42,8 +42,8 @@ class WrapperOwner : public virtual JavaScriptShared bool has(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp); bool get(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver, JS::HandleId id, JS::MutableHandleValue vp); - bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver, - JS::HandleId id, JS::MutableHandleValue vp, JS::ObjectOpResult &result); + bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleValue v, + JS::HandleValue receiver, JS::ObjectOpResult &result); bool callOrConstruct(JSContext *cx, JS::HandleObject proxy, const JS::CallArgs &args, bool construct); @@ -128,9 +128,8 @@ class WrapperOwner : public virtual JavaScriptShared virtual bool SendGet(const ObjectId &objId, const ObjectVariant &receiverVar, const JSIDVariant &id, ReturnStatus *rs, JSVariant *result) = 0; - virtual bool SendSet(const ObjectId &objId, const ObjectVariant &receiverVar, - const JSIDVariant &id, const JSVariant &value, - ReturnStatus *rs, JSVariant *result) = 0; + virtual bool SendSet(const ObjectId &objId, const JSIDVariant &id, const JSVariant &value, + const JSVariant &receiverVar, ReturnStatus *rs) = 0; virtual bool SendIsExtensible(const ObjectId &objId, ReturnStatus *rs, bool *result) = 0; diff --git a/js/public/Class.h b/js/public/Class.h index 4e8cbf41e1..389255aa00 100644 --- a/js/public/Class.h +++ b/js/public/Class.h @@ -160,7 +160,7 @@ class ObjectOpResult * return true. * - Otherwise, do nothing and return true. */ - bool checkStrictErrorOrWarning(JSContext *cx, HandleObject obj, HandleId id, bool strict) { + bool checkStrictErrorOrWarning(JSContext* cx, HandleObject obj, HandleId id, bool strict) { if (ok()) return true; return reportStrictErrorOrWarning(cx, obj, id, strict); @@ -172,12 +172,12 @@ class ObjectOpResult * used for [[PreventExtensions]] and [[SetPrototypeOf]]. failureCode() * must not be an error that has "{0}" in the error message. */ - bool checkStrictErrorOrWarning(JSContext *cx, HandleObject obj, bool strict) { + bool checkStrictErrorOrWarning(JSContext* cx, HandleObject obj, bool strict) { return ok() || reportStrictErrorOrWarning(cx, obj, strict); } /* Throw a TypeError. Call this only if !ok(). */ - bool reportError(JSContext *cx, HandleObject obj, HandleId id) { + bool reportError(JSContext* cx, HandleObject obj, HandleId id) { return reportStrictErrorOrWarning(cx, obj, id, true); } @@ -185,19 +185,19 @@ class ObjectOpResult * The same as reportError(cx, obj, id), except the operation is not * associated with a particular property id. */ - bool reportError(JSContext *cx, HandleObject obj) { + bool reportError(JSContext* cx, HandleObject obj) { return reportStrictErrorOrWarning(cx, obj, true); } /* Helper function for checkStrictErrorOrWarning's slow path. */ - JS_PUBLIC_API(bool) reportStrictErrorOrWarning(JSContext *cx, HandleObject obj, HandleId id, bool strict); - JS_PUBLIC_API(bool) reportStrictErrorOrWarning(JSContext *cx, HandleObject obj, bool strict); + JS_PUBLIC_API(bool) reportStrictErrorOrWarning(JSContext* cx, HandleObject obj, HandleId id, bool strict); + JS_PUBLIC_API(bool) reportStrictErrorOrWarning(JSContext* cx, HandleObject obj, bool strict); /* * Convenience method. Return true if ok() or if strict is false; otherwise * throw a TypeError and return false. */ - bool checkStrict(JSContext *cx, HandleObject obj, HandleId id) { + bool checkStrict(JSContext* cx, HandleObject obj, HandleId id) { return checkStrictErrorOrWarning(cx, obj, id, true); } @@ -205,7 +205,7 @@ class ObjectOpResult * Convenience method. The same as checkStrict(cx, id), except the * operation is not associated with a particular property id. */ - bool checkStrict(JSContext *cx, HandleObject obj) { + bool checkStrict(JSContext* cx, HandleObject obj) { return checkStrictErrorOrWarning(cx, obj, true); } }; @@ -218,7 +218,7 @@ class ObjectOpResult // be a string (Unicode property identifier) or an int (element index). The // *vp out parameter, on success, is the new property value after the action. typedef bool -(* JSGetterOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, +(* JSGetterOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp); typedef JSGetterOp JSAddPropertyOp; @@ -229,8 +229,8 @@ typedef JSGetterOp JSAddPropertyOp; // parameter, on success, is the new property value after the // set. typedef bool -(* JSSetterOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleValue vp, JS::ObjectOpResult &result); +(* JSSetterOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, + JS::MutableHandleValue vp, JS::ObjectOpResult& result); // Delete a property named by id in obj. // @@ -246,8 +246,8 @@ typedef bool // property, or an inherited property, is allowed -- it's just pointless), // call result.succeed() and return true. typedef bool -(* JSDeletePropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, - JS::ObjectOpResult &result); +(* JSDeletePropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, + JS::ObjectOpResult& result); // The type of ObjectOps::enumerate. This callback overrides a portion of SpiderMonkey's default // [[Enumerate]] internal method. When an ordinary object is enumerated, that object and each object @@ -342,8 +342,8 @@ typedef bool (* GetPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id, JS::MutableHandleValue vp); typedef bool -(* SetPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id, - JS::MutableHandleValue vp, JS::ObjectOpResult &result); +(* SetPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v, + JS::HandleValue receiver, JS::ObjectOpResult &result); typedef bool (* GetOwnPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandle desc); @@ -439,10 +439,10 @@ struct ClassSpec { ClassObjectCreationOp createConstructor; ClassObjectCreationOp createPrototype; - const JSFunctionSpec *constructorFunctions; - const JSPropertySpec *constructorProperties; - const JSFunctionSpec *prototypeFunctions; - const JSPropertySpec *prototypeProperties; + const JSFunctionSpec* constructorFunctions; + const JSPropertySpec* constructorProperties; + const JSFunctionSpec* prototypeFunctions; + const JSPropertySpec* prototypeProperties; FinishClassInitOp finishInit; uintptr_t flags; diff --git a/js/public/Proxy.h b/js/public/Proxy.h index 82bacfd62c..4025fd1299 100644 --- a/js/public/Proxy.h +++ b/js/public/Proxy.h @@ -294,8 +294,8 @@ class JS_FRIEND_API(BaseProxyHandler) virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const; virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, MutableHandleValue vp) const; - virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, - HandleId id, MutableHandleValue vp, ObjectOpResult &result) const; + virtual bool set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) const; /* * [[Call]] and [[Construct]] are standard internal methods but according @@ -395,9 +395,8 @@ class JS_FRIEND_API(DirectProxyHandler) : public BaseProxyHandler bool *bp) const override; virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, MutableHandleValue vp) const override; - virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, - HandleId id, MutableHandleValue vp, - ObjectOpResult &result) const override; + virtual bool set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) const override; virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) const override; virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const override; diff --git a/js/public/TrackedOptimizationInfo.h b/js/public/TrackedOptimizationInfo.h index 5341f5d74f..607fefd5fc 100644 --- a/js/public/TrackedOptimizationInfo.h +++ b/js/public/TrackedOptimizationInfo.h @@ -166,13 +166,13 @@ enum class TrackedTypeSite : uint32_t { Count }; -JS_PUBLIC_API(const char *) +JS_PUBLIC_API(const char*) TrackedStrategyString(TrackedStrategy strategy); -JS_PUBLIC_API(const char *) +JS_PUBLIC_API(const char*) TrackedOutcomeString(TrackedOutcome outcome); -JS_PUBLIC_API(const char *) +JS_PUBLIC_API(const char*) TrackedTypeSiteString(TrackedTypeSite site); struct ForEachTrackedOptimizationAttemptOp @@ -181,9 +181,9 @@ struct ForEachTrackedOptimizationAttemptOp }; JS_PUBLIC_API(void) -ForEachTrackedOptimizationAttempt(JSRuntime *rt, void *addr, uint8_t index, - ForEachTrackedOptimizationAttemptOp &op, - JSScript **scriptOut, jsbytecode **pcOut); +ForEachTrackedOptimizationAttempt(JSRuntime* rt, void* addr, uint8_t index, + ForEachTrackedOptimizationAttemptOp& op, + JSScript** scriptOut, jsbytecode** pcOut); struct ForEachTrackedOptimizationTypeInfoOp { diff --git a/js/src/asmjs/AsmJSValidate.cpp b/js/src/asmjs/AsmJSValidate.cpp index 9169343e94..2f9264cce4 100644 --- a/js/src/asmjs/AsmJSValidate.cpp +++ b/js/src/asmjs/AsmJSValidate.cpp @@ -8245,19 +8245,17 @@ StackDecrementForCall(MacroAssembler& masm, uint32_t alignment, const VectorT& a #if defined(JS_CODEGEN_ARM) // The ARM system ABI also includes d15 & s31 in the non volatile float registers. // Also exclude lr (a.k.a. r14) as we preserve it manually) -static const RegisterSet NonVolatileRegs = - RegisterSet(GeneralRegisterSet(Registers::NonVolatileMask & - ~(uint32_t(1) << Registers::lr)), - FloatRegisterSet(FloatRegisters::NonVolatileMask - | (1ULL << FloatRegisters::d15) - | (1ULL << FloatRegisters::s31))); +static const LiveRegisterSet NonVolatileRegs = + LiveRegisterSet(GeneralRegisterSet(Registers::NonVolatileMask & + ~(uint32_t(1) << Registers::lr)), + FloatRegisterSet(FloatRegisters::NonVolatileMask + | (1ULL << FloatRegisters::d15) + | (1ULL << FloatRegisters::s31))); #else -static const RegisterSet NonVolatileRegs = - RegisterSet(GeneralRegisterSet(Registers::NonVolatileMask), - FloatRegisterSet(FloatRegisters::NonVolatileMask)); +static const LiveRegisterSet NonVolatileRegs = + LiveRegisterSet(GeneralRegisterSet(Registers::NonVolatileMask), + FloatRegisterSet(FloatRegisters::NonVolatileMask)); #endif -static const FloatRegisterSet NonVolatileSimdRegs = SupportsSimd ? NonVolatileRegs.fpus() - : FloatRegisterSet(); #if defined(JS_CODEGEN_MIPS) // Mips is using one more double slot due to stack alignment for double values. @@ -8268,11 +8266,8 @@ static const unsigned FramePushedAfterSave = NonVolatileRegs.gprs().size() * siz #elif defined(JS_CODEGEN_NONE) static const unsigned FramePushedAfterSave = 0; #else -static const unsigned FramePushedAfterSave = - SupportsSimd ? NonVolatileRegs.gprs().size() * sizeof(intptr_t) + - NonVolatileRegs.fpus().size() * Simd128DataSize - : NonVolatileRegs.gprs().size() * sizeof(intptr_t) + - NonVolatileRegs.fpus().getPushSizeInBytes(); +static const unsigned FramePushedAfterSave = NonVolatileRegs.gprs().size() * sizeof(intptr_t) + + NonVolatileRegs.fpus().getPushSizeInBytes(); #endif static const unsigned FramePushedForEntrySP = FramePushedAfterSave + sizeof(void*); @@ -8297,7 +8292,7 @@ GenerateEntry(ModuleCompiler& m, unsigned exportIndex) // Save all caller non-volatile registers before we clobber them here and in // the asm.js callee (which does not preserve non-volatile registers). masm.setFramePushed(0); - masm.PushRegsInMask(NonVolatileRegs, NonVolatileSimdRegs); + masm.PushRegsInMask(NonVolatileRegs); MOZ_ASSERT(masm.framePushed() == FramePushedAfterSave); // ARM and MIPS have a globally-pinned GlobalReg (x64 uses RIP-relative @@ -8444,7 +8439,7 @@ GenerateEntry(ModuleCompiler& m, unsigned exportIndex) } // Restore clobbered non-volatile registers of the caller. - masm.PopRegsInMask(NonVolatileRegs, NonVolatileSimdRegs); + masm.PopRegsInMask(NonVolatileRegs); MOZ_ASSERT(masm.framePushed() == 0); masm.move32(Imm32(true), ReturnReg); @@ -9047,10 +9042,10 @@ GenerateOnOutOfBoundsLabelExit(ModuleCompiler& m, Label* throwLabel) return m.finishGeneratingInlineStub(&m.onOutOfBoundsLabel()) && !masm.oom(); } -static const RegisterSet AllRegsExceptSP = - RegisterSet(GeneralRegisterSet(Registers::AllMask & - ~(uint32_t(1) << Registers::StackPointer)), - FloatRegisterSet(FloatRegisters::AllDoubleMask)); +static const LiveRegisterSet AllRegsExceptSP( + GeneralRegisterSet(Registers::AllMask & + ~(uint32_t(1) << Registers::StackPointer)), + FloatRegisterSet(FloatRegisters::AllMask)); // The async interrupt-callback exit is called from arbitrarily-interrupted asm.js // code. That means we must first save *all* registers and restore *all* @@ -9074,7 +9069,7 @@ GenerateAsyncInterruptExit(ModuleCompiler& m, Label *throwLabel) masm.push(Imm32(0)); // space for resumePC masm.pushFlags(); // after this we are safe to use sub masm.setFramePushed(0); // set to zero so we can use masm.framePushed() below - masm.PushRegsInMask(AllRegsExceptSP, AllRegsExceptSP.fpus()); // save all GP/FP registers (except SP) + masm.PushRegsInMask(AllRegsExceptSP); // save all GP/FP registers (except SP) Register scratch = ABIArgGenerator::NonArgReturnReg0; @@ -9099,7 +9094,7 @@ GenerateAsyncInterruptExit(ModuleCompiler& m, Label *throwLabel) masm.mov(ABIArgGenerator::NonVolatileReg, StackPointer); // Restore the machine state to before the interrupt. - masm.PopRegsInMask(AllRegsExceptSP, AllRegsExceptSP.fpus()); // restore all GP/FP registers (except SP) + masm.PopRegsInMask(AllRegsExceptSP); // restore all GP/FP registers (except SP) masm.popFlags(); // after this, nothing that sets conditions masm.ret(); // pop resumePC into PC #elif defined(JS_CODEGEN_MIPS) @@ -9144,7 +9139,11 @@ GenerateAsyncInterruptExit(ModuleCompiler& m, Label *throwLabel) masm.loadAsmJSHeapRegisterFromGlobalData(); #elif defined(JS_CODEGEN_ARM) masm.setFramePushed(0); // set to zero so we can use masm.framePushed() below - masm.PushRegsInMask(RegisterSet(GeneralRegisterSet(Registers::AllMask & ~(1< typedObj(cx, &obj->as()); @@ -1919,7 +1919,7 @@ TypedObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleObject recei case type::Array: { if (JSID_IS_ATOM(id, cx->names().length)) { - if (obj == receiver) { + if (receiver.isObject() && obj == &receiver.toObject()) { JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_REDEFINE_ARRAY_LENGTH); return false; @@ -1929,8 +1929,8 @@ TypedObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleObject recei uint32_t index; if (IdIsIndex(id, &index)) { - if (obj != receiver) - return SetPropertyByDefining(cx, obj, receiver, id, vp, false, result); + if (!receiver.isObject() || obj != &receiver.toObject()) + return SetPropertyByDefining(cx, obj, id, v, receiver, false, result); if (index >= uint32_t(typedObj->length())) { JS_ReportErrorNumber(cx, GetErrorMessage, @@ -1941,7 +1941,7 @@ TypedObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleObject recei Rooted elementType(cx); elementType = &typedObj->typeDescr().as().elementType(); size_t offset = elementType->size() * index; - if (!ConvertAndCopyTo(cx, elementType, typedObj, offset, NullPtr(), vp)) + if (!ConvertAndCopyTo(cx, elementType, typedObj, offset, NullPtr(), v)) return false; return result.succeed(); } @@ -1955,19 +1955,19 @@ TypedObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleObject recei if (!descr->fieldIndex(id, &fieldIndex)) break; - if (obj != receiver) - return SetPropertyByDefining(cx, obj, receiver, id, vp, false, result); + if (!receiver.isObject() || obj != &receiver.toObject()) + return SetPropertyByDefining(cx, obj, id, v, receiver, false, result); size_t offset = descr->fieldOffset(fieldIndex); Rooted fieldType(cx, &descr->fieldDescr(fieldIndex)); RootedAtom fieldName(cx, &descr->fieldName(fieldIndex)); - if (!ConvertAndCopyTo(cx, fieldType, typedObj, offset, fieldName, vp)) + if (!ConvertAndCopyTo(cx, fieldType, typedObj, offset, fieldName, v)) return false; return result.succeed(); } } - return SetPropertyOnProto(cx, obj, receiver, id, vp, result); + return SetPropertyOnProto(cx, obj, id, v, receiver, result); } bool diff --git a/js/src/builtin/TypedObject.h b/js/src/builtin/TypedObject.h index 8b67ca5ed1..bb878acd7c 100644 --- a/js/src/builtin/TypedObject.h +++ b/js/src/builtin/TypedObject.h @@ -540,8 +540,8 @@ class TypedObject : public JSObject static bool obj_getElement(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t index, MutableHandleValue vp); - static bool obj_setProperty(JSContext *cx, HandleObject obj, HandleObject receiver, - HandleId id, MutableHandleValue vp, ObjectOpResult &result); + static bool obj_setProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result); static bool obj_getOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id, MutableHandle desc); diff --git a/js/src/ds/IdValuePair.h b/js/src/ds/IdValuePair.h index e486239c05..b77c307919 100644 --- a/js/src/ds/IdValuePair.h +++ b/js/src/ds/IdValuePair.h @@ -32,7 +32,7 @@ struct IdValuePair class MOZ_STACK_CLASS AutoIdValueVector : public AutoVectorRooter { public: - explicit AutoIdValueVector(ContextFriendFields *cx + explicit AutoIdValueVector(ContextFriendFields* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : AutoVectorRooter(cx, IDVALVECTOR) { diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index f717a323cb..9125857685 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -55,15 +55,15 @@ using mozilla::UniquePtr; struct frontend::StmtInfoBCE : public StmtInfoBase { - StmtInfoBCE *down; /* info for enclosing statement */ - StmtInfoBCE *downScope; /* next enclosing lexical scope */ + StmtInfoBCE* down; /* info for enclosing statement */ + StmtInfoBCE* downScope; /* next enclosing lexical scope */ ptrdiff_t update; /* loop update offset (top if none) */ ptrdiff_t breaks; /* offset of last break in loop */ ptrdiff_t continues; /* offset of last continue in loop */ uint32_t blockScopeIndex; /* index of scope in BlockScopeArray */ - explicit StmtInfoBCE(ExclusiveContext *cx) : StmtInfoBase(cx) {} + explicit StmtInfoBCE(ExclusiveContext* cx) : StmtInfoBase(cx) {} /* * To reuse space, alias two of the ptrdiff_t fields for use during @@ -214,9 +214,9 @@ BytecodeEmitter::emitCheck(ptrdiff_t delta) void BytecodeEmitter::updateDepth(ptrdiff_t target) { - jsbytecode *pc = code(target); + jsbytecode* pc = code(target); JSOp op = (JSOp) *pc; - const JSCodeSpec *cs = &js_CodeSpec[op]; + const JSCodeSpec* cs = &js_CodeSpec[op]; if (cs->format & JOF_TMPSLOT_MASK) { /* @@ -259,7 +259,7 @@ BytecodeEmitter::emit1(JSOp op) if (offset < 0) return false; - jsbytecode *code = this->code(offset); + jsbytecode* code = this->code(offset); code[0] = jsbytecode(op); updateDepth(offset); return true; @@ -273,7 +273,7 @@ BytecodeEmitter::emit2(JSOp op, jsbytecode op1) if (offset < 0) return false; - jsbytecode *code = this->code(offset); + jsbytecode* code = this->code(offset); code[0] = jsbytecode(op); code[1] = op1; updateDepth(offset); @@ -293,7 +293,7 @@ BytecodeEmitter::emit3(JSOp op, jsbytecode op1, jsbytecode op2) if (offset < 0) return false; - jsbytecode *code = this->code(offset); + jsbytecode* code = this->code(offset); code[0] = jsbytecode(op); code[1] = op1; code[2] = op2; @@ -339,7 +339,7 @@ BytecodeEmitter::emitJump(JSOp op, ptrdiff_t off) } bool -BytecodeEmitter::emitCall(JSOp op, uint16_t argc, ParseNode *pn) +BytecodeEmitter::emitCall(JSOp op, uint16_t argc, ParseNode* pn) { if (pn && !updateSourceCoordNotes(pn->pn_pos.begin)) return false; @@ -362,7 +362,7 @@ BytecodeEmitter::emitDupAt(unsigned slot) if (off < 0) return false; - jsbytecode *pc = code(off); + jsbytecode* pc = code(off); SET_UINT24(pc, slotFromTop); return true; } @@ -414,7 +414,7 @@ ReportStatementTooLarge(TokenStream& ts, StmtInfoBCE *topStmt) * so that we can walk back up the chain fixing up the op and jump offset. */ bool -BytecodeEmitter::emitBackPatchOp(ptrdiff_t *lastp) +BytecodeEmitter::emitBackPatchOp(ptrdiff_t* lastp) { ptrdiff_t delta = offset() - *lastp; *lastp = offset(); @@ -491,7 +491,7 @@ BytecodeEmitter::updateSourceCoordNotes(uint32_t offset) } bool -BytecodeEmitter::emitLoopHead(ParseNode *nextpn) +BytecodeEmitter::emitLoopHead(ParseNode* nextpn) { if (nextpn) { /* @@ -510,7 +510,7 @@ BytecodeEmitter::emitLoopHead(ParseNode *nextpn) } bool -BytecodeEmitter::emitLoopEntry(ParseNode *nextpn) +BytecodeEmitter::emitLoopEntry(ParseNode* nextpn) { if (nextpn) { /* Update the line number, as for LOOPHEAD. */ @@ -521,7 +521,7 @@ BytecodeEmitter::emitLoopEntry(ParseNode *nextpn) return false; } - LoopStmtInfo *loop = LoopStmtInfo::fromStmtInfo(topStmt); + LoopStmtInfo* loop = LoopStmtInfo::fromStmtInfo(topStmt); MOZ_ASSERT(loop->loopDepth > 0); uint8_t loopDepthAndFlags = PackLoopEntryDepthHintAndFlags(loop->loopDepth, loop->canIonOsr); @@ -548,7 +548,7 @@ BytecodeEmitter::emitUint16Operand(JSOp op, uint32_t i) } bool -BytecodeEmitter::flushPops(int *npops) +BytecodeEmitter::flushPops(int* npops) { MOZ_ASSERT(*npops != 0); if (!emitUint16Operand(JSOP_POPN, *npops)) @@ -669,7 +669,7 @@ NonLocalExitScope::prepareForNonLocalJump(StmtInfoBCE* toStmt) if (stmt->isBlockScope) { MOZ_ASSERT(stmt->isNestedScope); - StaticBlockObject &blockObj = stmt->staticBlock(); + StaticBlockObject& blockObj = stmt->staticBlock(); if (!bce->emit1(JSOP_DEBUGLEAVEBLOCK)) return false; if (!popScopeForNonLocalExit(stmt->blockScopeIndex)) @@ -708,10 +708,10 @@ BytecodeEmitter::emitGoto(StmtInfoBCE *toStmt, ptrdiff_t *lastp, SrcNoteType not } void -BytecodeEmitter::backPatch(ptrdiff_t last, jsbytecode *target, jsbytecode op) +BytecodeEmitter::backPatch(ptrdiff_t last, jsbytecode* target, jsbytecode op) { - jsbytecode *pc = code(last); - jsbytecode *stop = code(-1); + jsbytecode* pc = code(last); + jsbytecode* stop = code(-1); while (pc != stop) { ptrdiff_t delta = GET_JUMP_OFFSET(pc); ptrdiff_t span = target - pc; @@ -1022,7 +1022,7 @@ BytecodeEmitter::emitIndex32(JSOp op, uint32_t index) if (offset < 0) return false; - jsbytecode *code = this->code(offset); + jsbytecode* code = this->code(offset); code[0] = jsbytecode(op); SET_UINT32_INDEX(code, index); updateDepth(offset); @@ -1042,7 +1042,7 @@ BytecodeEmitter::emitIndexOp(JSOp op, uint32_t index) if (offset < 0) return false; - jsbytecode *code = this->code(offset); + jsbytecode* code = this->code(offset); code[0] = jsbytecode(op); SET_UINT32_INDEX(code, index); updateDepth(offset); @@ -1051,7 +1051,7 @@ BytecodeEmitter::emitIndexOp(JSOp op, uint32_t index) } bool -BytecodeEmitter::emitAtomOp(JSAtom *atom, JSOp op) +BytecodeEmitter::emitAtomOp(JSAtom* atom, JSOp op) { MOZ_ASSERT(JOF_OPTYPE(op) == JOF_ATOM); @@ -1072,7 +1072,7 @@ BytecodeEmitter::emitAtomOp(JSAtom *atom, JSOp op) } bool -BytecodeEmitter::emitAtomOp(ParseNode *pn, JSOp op) +BytecodeEmitter::emitAtomOp(ParseNode* pn, JSOp op) { MOZ_ASSERT(pn->pn_atom != nullptr); return emitAtomOp(pn->pn_atom, op); @@ -1087,13 +1087,13 @@ BytecodeEmitter::emitInternedObjectOp(uint32_t index, JSOp op) } bool -BytecodeEmitter::emitObjectOp(ObjectBox *objbox, JSOp op) +BytecodeEmitter::emitObjectOp(ObjectBox* objbox, JSOp op) { return emitInternedObjectOp(objectList.add(objbox), op); } bool -BytecodeEmitter::emitObjectPairOp(ObjectBox *objbox1, ObjectBox *objbox2, JSOp op) +BytecodeEmitter::emitObjectPairOp(ObjectBox* objbox1, ObjectBox* objbox2, JSOp op) { uint32_t index = objectList.add(objbox1); objectList.add(objbox2); @@ -1162,7 +1162,7 @@ BytecodeEmitter::emitScopeCoordOp(JSOp op, ScopeCoordinate sc) if (off < 0) return false; - jsbytecode *pc = code(off); + jsbytecode* pc = code(off); SET_SCOPECOORD_HOPS(pc, sc.hops()); pc += SCOPECOORD_HOPS_LEN; SET_SCOPECOORD_SLOT(pc, sc.slot()); @@ -1293,7 +1293,7 @@ BytecodeEmitter::emitAliasedVarOp(JSOp op, ParseNode *pn) * - all the intervening let/catch blocks must be counted. */ unsigned skippedScopes = 0; - BytecodeEmitter *bceOfDef = this; + BytecodeEmitter* bceOfDef = this; if (pn->isUsed()) { /* * As explained in bindNameToSlot, the 'level' of a use indicates how @@ -1354,7 +1354,7 @@ BytecodeEmitter::emitAliasedVarOp(JSOp op, ParseNode *pn) } bool -BytecodeEmitter::emitVarOp(ParseNode *pn, JSOp op) +BytecodeEmitter::emitVarOp(ParseNode* pn, JSOp op) { MOZ_ASSERT(pn->isKind(PNK_FUNCTION) || pn->isKind(PNK_NAME)); MOZ_ASSERT(!pn->pn_cookie.isFree()); @@ -1386,7 +1386,7 @@ BytecodeEmitter::emitVarOp(ParseNode *pn, JSOp op) } static JSOp -GetIncDecInfo(ParseNodeKind kind, bool *post) +GetIncDecInfo(ParseNodeKind kind, bool* post) { MOZ_ASSERT(kind == PNK_POSTINCREMENT || kind == PNK_PREINCREMENT || kind == PNK_POSTDECREMENT || kind == PNK_PREDECREMENT); @@ -1395,7 +1395,7 @@ GetIncDecInfo(ParseNodeKind kind, bool *post) } bool -BytecodeEmitter::emitVarIncDec(ParseNode *pn) +BytecodeEmitter::emitVarIncDec(ParseNode* pn) { JSOp op = pn->pn_kid->getOp(); MOZ_ASSERT(IsArgOp(op) || IsLocalOp(op) || IsAliasedVarOp(op)); @@ -1903,7 +1903,7 @@ BindNameToSlotHelper(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn) * and we do not want to allow self-hosted code to use the dynamic scope. */ bool -BytecodeEmitter::bindNameToSlot(ParseNode *pn) +BytecodeEmitter::bindNameToSlot(ParseNode* pn) { if (!BindNameToSlotHelper(cx, this, pn)) return false; @@ -2138,7 +2138,7 @@ BytecodeEmitter::needsImplicitThis() if (sc->isFunctionBox() && sc->asFunctionBox()->inWith) return true; - for (StmtInfoBCE *stmt = topStmt; stmt; stmt = stmt->down) { + for (StmtInfoBCE* stmt = topStmt; stmt; stmt = stmt->down) { if (stmt->type == STMT_WITH) return true; } @@ -2212,7 +2212,7 @@ BytecodeEmitter::emitNewInit(JSProtoKey key) if (offset < 0) return false; - jsbytecode *code = this->code(offset); + jsbytecode* code = this->code(offset); code[0] = JSOP_NEWINIT; code[1] = jsbytecode(key); code[2] = 0; @@ -7309,7 +7309,7 @@ BytecodeEmitter::emitTree(ParseNode *pn) if (!ObjectElements::MakeElementsCopyOnWrite(cx, obj)) return false; - ObjectBox *objbox = parser->newObjectBox(obj); + ObjectBox* objbox = parser->newObjectBox(obj); if (!objbox) return false; @@ -7609,7 +7609,7 @@ frontend::CopySrcNotes(BytecodeEmitter* bce, jssrcnote* destination, uint32_t ns } void -CGConstList::finish(ConstArray *array) +CGConstList::finish(ConstArray* array) { MOZ_ASSERT(length() == array->length); @@ -7660,7 +7660,7 @@ CGConstList::finish(ConstArray *array) * the pre-compilation prototype, a pigeon-hole problem for instanceof tests. */ unsigned -CGObjectList::add(ObjectBox *objbox) +CGObjectList::add(ObjectBox* objbox) { MOZ_ASSERT(!objbox->emitLink); objbox->emitLink = lastbox; @@ -7669,23 +7669,23 @@ CGObjectList::add(ObjectBox *objbox) } unsigned -CGObjectList::indexOf(JSObject *obj) +CGObjectList::indexOf(JSObject* obj) { MOZ_ASSERT(length > 0); unsigned index = length - 1; - for (ObjectBox *box = lastbox; box->object != obj; box = box->emitLink) + for (ObjectBox* box = lastbox; box->object != obj; box = box->emitLink) index--; return index; } void -CGObjectList::finish(ObjectArray *array) +CGObjectList::finish(ObjectArray* array) { MOZ_ASSERT(length <= INDEX_LIMIT); MOZ_ASSERT(length == array->length); - js::HeapPtrObject *cursor = array->vector + array->length; - ObjectBox *objbox = lastbox; + js::HeapPtrObject* cursor = array->vector + array->length; + ObjectBox* objbox = lastbox; do { --cursor; MOZ_ASSERT(!*cursor); @@ -7698,7 +7698,7 @@ ObjectBox* CGObjectList::find(uint32_t index) { MOZ_ASSERT(index < length); - ObjectBox *box = lastbox; + ObjectBox* box = lastbox; for (unsigned n = length - 1; n > index; n--) box = box->emitLink; return box; @@ -7721,7 +7721,7 @@ CGTryNoteList::append(JSTryNoteKind kind, uint32_t stackDepth, size_t start, siz } void -CGTryNoteList::finish(TryNoteArray *array) +CGTryNoteList::finish(TryNoteArray* array) { MOZ_ASSERT(length() == array->length); @@ -7826,7 +7826,7 @@ js::SrcNoteLength(jssrcnote *sn) } JS_FRIEND_API(ptrdiff_t) -js::GetSrcNoteOffset(jssrcnote *sn, unsigned which) +js::GetSrcNoteOffset(jssrcnote* sn, unsigned which) { /* Find the offset numbered which (i.e., skip exactly which offsets). */ MOZ_ASSERT(SN_TYPE(sn) != SRC_XDELTA); diff --git a/js/src/gc/Allocator.cpp b/js/src/gc/Allocator.cpp index 8405dff0de..f9699feea2 100644 --- a/js/src/gc/Allocator.cpp +++ b/js/src/gc/Allocator.cpp @@ -21,7 +21,7 @@ using namespace js; using namespace gc; bool -GCRuntime::gcIfNeededPerAllocation(JSContext *cx) +GCRuntime::gcIfNeededPerAllocation(JSContext* cx) { #ifdef JS_GC_ZEAL if (needZealousGC()) @@ -49,7 +49,7 @@ GCRuntime::gcIfNeededPerAllocation(JSContext *cx) template bool -GCRuntime::checkAllocatorState(JSContext *cx, AllocKind kind) +GCRuntime::checkAllocatorState(JSContext* cx, AllocKind kind) { if (allowGC) { if (!gcIfNeededPerAllocation(cx)) @@ -81,24 +81,24 @@ GCRuntime::checkAllocatorState(JSContext *cx, AllocKind kind) template /* static */ void -GCRuntime::checkIncrementalZoneState(ExclusiveContext *cx, T *t) +GCRuntime::checkIncrementalZoneState(ExclusiveContext* cx, T* t) { #ifdef DEBUG if (!cx->isJSContext()) return; - Zone *zone = cx->asJSContext()->zone(); + Zone* zone = cx->asJSContext()->zone(); MOZ_ASSERT_IF(t && zone->wasGCStarted() && (zone->isGCMarking() || zone->isGCSweeping()), t->asTenured().arenaHeader()->allocatedDuringIncremental); #endif } template -JSObject * -js::Allocate(ExclusiveContext *cx, AllocKind kind, size_t nDynamicSlots, InitialHeap heap, - const Class *clasp) +JSObject* +js::Allocate(ExclusiveContext* cx, AllocKind kind, size_t nDynamicSlots, InitialHeap heap, + const Class* clasp) { - static_assert(mozilla::IsConvertible::value, "must be JSObject derived"); + static_assert(mozilla::IsConvertible::value, "must be JSObject derived"); MOZ_ASSERT(IsObjectAllocKind(kind)); size_t thingSize = Arena::thingSize(kind); @@ -111,13 +111,13 @@ js::Allocate(ExclusiveContext *cx, AllocKind kind, size_t nDynamicSlots, Initial if (!cx->isJSContext()) return GCRuntime::tryNewTenuredObject(cx, kind, thingSize, nDynamicSlots); - JSContext *ncx = cx->asJSContext(); - JSRuntime *rt = ncx->runtime(); + JSContext* ncx = cx->asJSContext(); + JSRuntime* rt = ncx->runtime(); if (!rt->gc.checkAllocatorState(ncx, kind)) return nullptr; if (ncx->nursery().isEnabled() && heap != TenuredHeap) { - JSObject *obj = rt->gc.tryNewNurseryObject(ncx, thingSize, nDynamicSlots, clasp); + JSObject* obj = rt->gc.tryNewNurseryObject(ncx, thingSize, nDynamicSlots, clasp); if (obj) return obj; @@ -132,21 +132,21 @@ js::Allocate(ExclusiveContext *cx, AllocKind kind, size_t nDynamicSlots, Initial return GCRuntime::tryNewTenuredObject(cx, kind, thingSize, nDynamicSlots); } -template JSObject *js::Allocate(ExclusiveContext *cx, gc::AllocKind kind, +template JSObject* js::Allocate(ExclusiveContext* cx, gc::AllocKind kind, size_t nDynamicSlots, gc::InitialHeap heap, - const Class *clasp); -template JSObject *js::Allocate(ExclusiveContext *cx, gc::AllocKind kind, + const Class* clasp); +template JSObject* js::Allocate(ExclusiveContext* cx, gc::AllocKind kind, size_t nDynamicSlots, gc::InitialHeap heap, - const Class *clasp); + const Class* clasp); // Attempt to allocate a new GC thing out of the nursery. If there is not enough // room in the nursery or there is an OOM, this method will return nullptr. template -JSObject * -GCRuntime::tryNewNurseryObject(JSContext *cx, size_t thingSize, size_t nDynamicSlots, const Class *clasp) +JSObject* +GCRuntime::tryNewNurseryObject(JSContext* cx, size_t thingSize, size_t nDynamicSlots, const Class* clasp) { MOZ_ASSERT(!IsAtomsCompartment(cx->compartment())); - JSObject *obj = nursery.allocateObject(cx, thingSize, nDynamicSlots, clasp); + JSObject* obj = nursery.allocateObject(cx, thingSize, nDynamicSlots, clasp); if (obj) return obj; @@ -155,7 +155,7 @@ GCRuntime::tryNewNurseryObject(JSContext *cx, size_t thingSize, size_t nDynamicS // Exceeding gcMaxBytes while tenuring can disable the Nursery. if (nursery.isEnabled()) { - JSObject *obj = nursery.allocateObject(cx, thingSize, nDynamicSlots, clasp); + JSObject* obj = nursery.allocateObject(cx, thingSize, nDynamicSlots, clasp); MOZ_ASSERT(obj); return obj; } @@ -164,11 +164,11 @@ GCRuntime::tryNewNurseryObject(JSContext *cx, size_t thingSize, size_t nDynamicS } template -JSObject * -GCRuntime::tryNewTenuredObject(ExclusiveContext *cx, AllocKind kind, size_t thingSize, +JSObject* +GCRuntime::tryNewTenuredObject(ExclusiveContext* cx, AllocKind kind, size_t thingSize, size_t nDynamicSlots) { - HeapSlot *slots = nullptr; + HeapSlot* slots = nullptr; if (nDynamicSlots) { slots = cx->zone()->pod_malloc(nDynamicSlots); if (MOZ_UNLIKELY(!slots)) @@ -176,7 +176,7 @@ GCRuntime::tryNewTenuredObject(ExclusiveContext *cx, AllocKind kind, size_t thin Debug_SetSlotRangeToCrashOnTouch(slots, nDynamicSlots); } - JSObject *obj = tryNewTenuredThing(cx, kind, thingSize); + JSObject* obj = tryNewTenuredThing(cx, kind, thingSize); if (obj) obj->setInitialSlotsMaybeNonNative(slots); @@ -187,8 +187,8 @@ GCRuntime::tryNewTenuredObject(ExclusiveContext *cx, AllocKind kind, size_t thin } template -T * -js::Allocate(ExclusiveContext *cx) +T* +js::Allocate(ExclusiveContext* cx) { static_assert(!mozilla::IsConvertible::value, "must not be JSObject derived"); static_assert(sizeof(T) >= CellSize, @@ -199,7 +199,7 @@ js::Allocate(ExclusiveContext *cx) MOZ_ASSERT(thingSize == Arena::thingSize(kind)); if (cx->isJSContext()) { - JSContext *ncx = cx->asJSContext(); + JSContext* ncx = cx->asJSContext(); if (!ncx->runtime()->gc.checkAllocatorState(ncx, kind)) return nullptr; } @@ -326,7 +326,7 @@ ArenaLists::allocateFromArena(JS::Zone* zone, AllocKind thingKind, if (maybeLock.isNothing()) maybeLock.emplace(rt); - Chunk *chunk = rt->gc.pickChunk(maybeLock.ref(), maybeStartBGAlloc); + Chunk* chunk = rt->gc.pickChunk(maybeLock.ref(), maybeStartBGAlloc); if (!chunk) return nullptr; @@ -344,8 +344,8 @@ ArenaLists::allocateFromArena(JS::Zone* zone, AllocKind thingKind, } template -TenuredCell * -ArenaLists::allocateFromArenaInner(JS::Zone *zone, ArenaHeader *aheader, AllocKind kind) +TenuredCell* +ArenaLists::allocateFromArenaInner(JS::Zone* zone, ArenaHeader* aheader, AllocKind kind) { size_t thingSize = Arena::thingSize(kind); @@ -356,20 +356,20 @@ ArenaLists::allocateFromArenaInner(JS::Zone *zone, ArenaHeader *aheader, AllocKi aheader->setAsFullyUsed(); } else { MOZ_ASSERT(!aheader->hasFreeThings()); - Arena *arena = aheader->getArena(); + Arena* arena = aheader->getArena(); span.initFinal(arena->thingsStart(kind), arena->thingsEnd() - thingSize, thingSize); } freeLists[kind].setHead(&span); if (MOZ_UNLIKELY(zone->wasGCStarted())) zone->runtimeFromAnyThread()->gc.arenaAllocatedDuringGC(zone, aheader); - TenuredCell *thing = freeLists[kind].allocate(thingSize); + TenuredCell* thing = freeLists[kind].allocate(thingSize); MOZ_ASSERT(thing); // This allocation is infallible. return thing; } void -GCRuntime::arenaAllocatedDuringGC(JS::Zone *zone, ArenaHeader *arena) +GCRuntime::arenaAllocatedDuringGC(JS::Zone* zone, ArenaHeader* arena) { if (zone->needsIncrementalBarrier()) { arena->allocatedDuringIncremental = true; diff --git a/js/src/gc/Allocator.h b/js/src/gc/Allocator.h index f697e85d09..fd530cadf1 100644 --- a/js/src/gc/Allocator.h +++ b/js/src/gc/Allocator.h @@ -22,13 +22,13 @@ struct Class; // includes slot, heap, and finalizer information in support of various // object-specific optimizations. template -T * -Allocate(ExclusiveContext *cx); +T* +Allocate(ExclusiveContext* cx); template -JSObject * -Allocate(ExclusiveContext *cx, gc::AllocKind kind, size_t nDynamicSlots, gc::InitialHeap heap, - const Class *clasp); +JSObject* +Allocate(ExclusiveContext* cx, gc::AllocKind kind, size_t nDynamicSlots, gc::InitialHeap heap, + const Class* clasp); } // namespace js diff --git a/js/src/gc/Iteration.cpp b/js/src/gc/Iteration.cpp index 4f38bf660a..5f72fd5a15 100644 --- a/js/src/gc/Iteration.cpp +++ b/js/src/gc/Iteration.cpp @@ -30,7 +30,7 @@ js::TraceRuntime(JSTracer* trc) } static void -IterateCompartmentsArenasCells(JSRuntime *rt, Zone *zone, void *data, +IterateCompartmentsArenasCells(JSRuntime* rt, Zone* zone, void* data, JSIterateCompartmentCallback compartmentCallback, IterateArenaCallback arenaCallback, IterateCellCallback cellCallback) @@ -43,7 +43,7 @@ IterateCompartmentsArenasCells(JSRuntime *rt, Zone *zone, void *data, size_t thingSize = Arena::thingSize(thingKind); for (ArenaIter aiter(zone, thingKind); !aiter.done(); aiter.next()) { - ArenaHeader *aheader = aiter.get(); + ArenaHeader* aheader = aiter.get(); (*arenaCallback)(rt, data, aheader->getArena(), traceKind, thingSize); for (ArenaCellIterUnderGC iter(aheader); !iter.done(); iter.next()) (*cellCallback)(rt, data, iter.getCell(), traceKind, thingSize); diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 0df52f3d35..99ed92b440 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -68,43 +68,43 @@ JS_PUBLIC_DATA(void * const) JS::NullPtr::constNullValue = nullptr; */ static inline void -PushMarkStack(GCMarker *gcmarker, JSObject *thing) { +PushMarkStack(GCMarker* gcmarker, JSObject* thing) { gcmarker->traverse(thing); } static inline void -PushMarkStack(GCMarker *gcmarker, JSFunction *thing) { - gcmarker->traverse(static_cast(thing)); +PushMarkStack(GCMarker* gcmarker, JSFunction* thing) { + gcmarker->traverse(static_cast(thing)); } static inline void -PushMarkStack(GCMarker *gcmarker, ObjectGroup *thing) { +PushMarkStack(GCMarker* gcmarker, ObjectGroup* thing) { gcmarker->traverse(thing); } static void -PushMarkStack(GCMarker *gcmarker, jit::JitCode *thing) { +PushMarkStack(GCMarker* gcmarker, jit::JitCode* thing) { gcmarker->traverse(thing); } static inline void -PushMarkStack(GCMarker *gcmarker, JSScript *thing) { +PushMarkStack(GCMarker* gcmarker, JSScript* thing) { gcmarker->traverse(thing); } static inline void -PushMarkStack(GCMarker *gcmarker, LazyScript *thing) { +PushMarkStack(GCMarker* gcmarker, LazyScript* thing) { gcmarker->traverse(thing); } static inline void -PushMarkStack(GCMarker *gcmarker, Shape *thing); +PushMarkStack(GCMarker* gcmarker, Shape* thing); static inline void -PushMarkStack(GCMarker *gcmarker, BaseShape *thing); +PushMarkStack(GCMarker* gcmarker, BaseShape* thing); static inline void -PushMarkStack(GCMarker *gcmarker, JSString *thing); +PushMarkStack(GCMarker* gcmarker, JSString* thing); static inline void -PushMarkStack(GCMarker *gcmarker, JS::Symbol *thing); +PushMarkStack(GCMarker* gcmarker, JS::Symbol* thing); namespace js { namespace gc { -static void MarkChildren(JSTracer *trc, ObjectGroup *group); +static void MarkChildren(JSTracer* trc, ObjectGroup* group); } /* namespace gc */ } /* namespace js */ @@ -114,7 +114,7 @@ static void MarkChildren(JSTracer *trc, ObjectGroup *group); #if defined(DEBUG) template static inline bool -IsThingPoisoned(T *thing) +IsThingPoisoned(T* thing) { const uint8_t poisonBytes[] = { JS_FRESH_NURSERY_PATTERN, @@ -215,7 +215,7 @@ CheckMarkedThing(JSTracer* trc, T** thingp) MOZ_ASSERT_IF(zone->requireGCTracer(), isGcMarkingTracer || IsBufferingGrayRoots(trc)); if (isGcMarkingTracer) { - GCMarker *gcMarker = static_cast(trc); + GCMarker* gcMarker = static_cast(trc); MOZ_ASSERT_IF(gcMarker->shouldCheckCompartments(), zone->isCollecting() || rt->isAtomsZone(zone)); @@ -686,19 +686,19 @@ gc::MarkGCThingUnbarriered(JSTracer* trc, void** thingp, const char* name) /*** ID Marking ***/ static inline void -MarkIdInternal(JSTracer *trc, jsid *id) +MarkIdInternal(JSTracer* trc, jsid* id) { if (JSID_IS_STRING(*id)) { - JSString *str = JSID_TO_STRING(*id); - JSString *prior = str; - trc->setTracingLocation((void *)id); + JSString* str = JSID_TO_STRING(*id); + JSString* prior = str; + trc->setTracingLocation((void*)id); MarkInternal(trc, &str); if (str != prior) - *id = NON_INTEGER_ATOM_TO_JSID(reinterpret_cast(str)); + *id = NON_INTEGER_ATOM_TO_JSID(reinterpret_cast(str)); } else if (JSID_IS_SYMBOL(*id)) { - JS::Symbol *sym = JSID_TO_SYMBOL(*id); - JS::Symbol *prior = sym; - trc->setTracingLocation((void *)id); + JS::Symbol* sym = JSID_TO_SYMBOL(*id); + JS::Symbol* prior = sym; + trc->setTracingLocation((void*)id); MarkInternal(trc, &sym); if (sym != prior) *id = SYMBOL_TO_JSID(sym); @@ -752,25 +752,25 @@ gc::MarkIdRootRange(JSTracer* trc, size_t len, jsid* vec, const char* name) /*** Value Marking ***/ static inline void -MarkValueInternal(JSTracer *trc, Value *v) +MarkValueInternal(JSTracer* trc, Value* v) { if (v->isMarkable()) { MOZ_ASSERT(v->toGCThing()); - void *thing = v->toGCThing(); - trc->setTracingLocation((void *)v); + void* thing = v->toGCThing(); + trc->setTracingLocation((void*)v); if (v->isString()) { - JSString *str = static_cast(thing); + JSString* str = static_cast(thing); MarkInternal(trc, &str); if (str != thing) v->setString(str); } else if (v->isObject()) { - JSObject *obj = static_cast(thing); + JSObject* obj = static_cast(thing); MarkInternal(trc, &obj); if (obj != thing) v->setObjectOrNull(obj); } else { MOZ_ASSERT(v->isSymbol()); - JS::Symbol *sym = static_cast(thing); + JS::Symbol* sym = static_cast(thing); MarkInternal(trc, &sym); if (sym != thing) v->setSymbol(sym); @@ -797,7 +797,7 @@ gc::MarkValueRoot(JSTracer* trc, Value* v, const char* name) } void -gc::MarkValueRange(JSTracer *trc, size_t len, BarrieredBase *vec, const char *name) +gc::MarkValueRange(JSTracer* trc, size_t len, BarrieredBase* vec, const char* name) { for (size_t i = 0; i < len; ++i) { trc->setTracingIndex(name, i); @@ -862,22 +862,22 @@ gc::IsValueAboutToBeFinalized(Value* v) /*** Type Marking ***/ void -TypeSet::MarkTypeRoot(JSTracer *trc, TypeSet::Type *v, const char *name) +TypeSet::MarkTypeRoot(JSTracer* trc, TypeSet::Type* v, const char* name) { JS_ROOT_MARKING_ASSERT(trc); MarkTypeUnbarriered(trc, v, name); } void -TypeSet::MarkTypeUnbarriered(JSTracer *trc, TypeSet::Type *v, const char *name) +TypeSet::MarkTypeUnbarriered(JSTracer* trc, TypeSet::Type* v, const char* name) { trc->setTracingName(name); if (v->isSingletonUnchecked()) { - JSObject *obj = v->singleton(); + JSObject* obj = v->singleton(); MarkInternal(trc, &obj); *v = TypeSet::ObjectType(obj); } else if (v->isGroupUnchecked()) { - ObjectGroup *group = v->group(); + ObjectGroup* group = v->group(); MarkInternal(trc, &group); *v = TypeSet::ObjectType(group); } @@ -918,7 +918,7 @@ gc::MarkObjectSlots(JSTracer* trc, NativeObject* obj, uint32_t start, uint32_t n } static bool -ShouldMarkCrossCompartment(JSTracer *trc, JSObject *src, Cell *cell) +ShouldMarkCrossCompartment(JSTracer* trc, JSObject* src, Cell* cell) { if (!IsMarkingTracer(trc)) return true; @@ -930,9 +930,9 @@ ShouldMarkCrossCompartment(JSTracer *trc, JSObject *src, Cell *cell) MOZ_ASSERT(color == BLACK); return false; } - TenuredCell &tenured = cell->asTenured(); + TenuredCell& tenured = cell->asTenured(); - JS::Zone *zone = tenured.zone(); + JS::Zone* zone = tenured.zone(); if (color == BLACK) { /* * Having black->gray edges violates our promise to the cycle @@ -1002,7 +1002,7 @@ gc::MarkValueUnbarriered(JSTracer* trc, Value* v, const char* name) * post-barrier during the minor GC at the start of each incremental slice. */ static void -MaybePushMarkStackBetweenSlices(GCMarker *gcmarker, JSObject *thing) +MaybePushMarkStackBetweenSlices(GCMarker* gcmarker, JSObject* thing) { MOZ_ASSERT_IF(gcmarker->runtime()->isHeapBusy(), !IsInsideNursery(thing)); @@ -1011,10 +1011,10 @@ MaybePushMarkStackBetweenSlices(GCMarker *gcmarker, JSObject *thing) } static void -ScanShape(GCMarker *gcmarker, Shape *shape); +ScanShape(GCMarker* gcmarker, Shape* shape); static void -PushMarkStack(GCMarker *gcmarker, Shape *thing) +PushMarkStack(GCMarker* gcmarker, Shape* thing) { JS_COMPARTMENT_ASSERT(gcmarker->runtime(), thing); MOZ_ASSERT(!IsInsideNursery(thing)); @@ -1025,10 +1025,10 @@ PushMarkStack(GCMarker *gcmarker, Shape *thing) } static inline void -ScanBaseShape(GCMarker *gcmarker, BaseShape *base); +ScanBaseShape(GCMarker* gcmarker, BaseShape* base); void -BaseShape::markChildren(JSTracer *trc) +BaseShape::markChildren(JSTracer* trc) { if (isOwned()) gc::MarkBaseShape(trc, &unowned_, "base"); @@ -1039,7 +1039,7 @@ BaseShape::markChildren(JSTracer *trc) } static void -PushMarkStack(GCMarker *gcmarker, BaseShape *thing) +PushMarkStack(GCMarker* gcmarker, BaseShape* thing) { JS_COMPARTMENT_ASSERT(gcmarker->runtime(), thing); MOZ_ASSERT(!IsInsideNursery(thing)); @@ -1050,12 +1050,12 @@ PushMarkStack(GCMarker *gcmarker, BaseShape *thing) } static void -ScanShape(GCMarker *gcmarker, Shape *shape) +ScanShape(GCMarker* gcmarker, Shape* shape) { restart: PushMarkStack(gcmarker, shape->base()); - const BarrieredBase &id = shape->propidRef(); + const BarrieredBase& id = shape->propidRef(); if (JSID_IS_STRING(id)) PushMarkStack(gcmarker, JSID_TO_STRING(id)); else if (JSID_IS_SYMBOL(id)) @@ -1088,14 +1088,14 @@ ScanBaseShape(GCMarker *gcmarker, BaseShape* base) * unowned base shape. */ if (base->isOwned()) { - UnownedBaseShape *unowned = base->baseUnowned(); + UnownedBaseShape* unowned = base->baseUnowned(); MOZ_ASSERT(base->compartment() == unowned->compartment()); unowned->markIfUnmarked(gcmarker->markColor()); } } static inline void -ScanLinearString(GCMarker *gcmarker, JSLinearString *str) +ScanLinearString(GCMarker* gcmarker, JSLinearString* str) { JS_COMPARTMENT_ASSERT(gcmarker->runtime(), str); MOZ_ASSERT(str->isMarked()); @@ -1126,7 +1126,7 @@ ScanLinearString(GCMarker *gcmarker, JSLinearString *str) * linear strings, it cannot refer to GC things of other types. */ static void -ScanRope(GCMarker *gcmarker, JSRope *rope) +ScanRope(GCMarker* gcmarker, JSRope* rope) { ptrdiff_t savedPos = gcmarker->stack.position(); JS_DIAGNOSTICS_ASSERT(GetGCThingTraceKind(rope) == JSTRACE_STRING); @@ -1135,9 +1135,9 @@ ScanRope(GCMarker *gcmarker, JSRope *rope) JS_DIAGNOSTICS_ASSERT(rope->JSString::isRope()); JS_COMPARTMENT_ASSERT(gcmarker->runtime(), rope); MOZ_ASSERT(rope->isMarked()); - JSRope *next = nullptr; + JSRope* next = nullptr; - JSString *right = rope->rightChild(); + JSString* right = rope->rightChild(); if (!right->isPermanentAtom() && right->markIfUnmarked()) { if (right->isLinear()) ScanLinearString(gcmarker, &right->asLinear()); @@ -1145,7 +1145,7 @@ ScanRope(GCMarker *gcmarker, JSRope *rope) next = &right->asRope(); } - JSString *left = rope->leftChild(); + JSString* left = rope->leftChild(); if (!left->isPermanentAtom() && left->markIfUnmarked()) { if (left->isLinear()) { ScanLinearString(gcmarker, &left->asLinear()); @@ -1172,7 +1172,7 @@ ScanRope(GCMarker *gcmarker, JSRope *rope) } static inline void -ScanString(GCMarker *gcmarker, JSString *str) +ScanString(GCMarker* gcmarker, JSString* str) { if (str->isLinear()) ScanLinearString(gcmarker, &str->asLinear()); @@ -1181,7 +1181,7 @@ ScanString(GCMarker *gcmarker, JSString *str) } static inline void -PushMarkStack(GCMarker *gcmarker, JSString *str) +PushMarkStack(GCMarker* gcmarker, JSString* str) { // Permanent atoms might not be associated with this runtime. if (str->isPermanentAtom()) @@ -1199,14 +1199,14 @@ PushMarkStack(GCMarker *gcmarker, JSString *str) } static inline void -ScanSymbol(GCMarker *gcmarker, JS::Symbol *sym) +ScanSymbol(GCMarker* gcmarker, JS::Symbol* sym) { - if (JSString *desc = sym->description()) + if (JSString* desc = sym->description()) PushMarkStack(gcmarker, desc); } static inline void -PushMarkStack(GCMarker *gcmarker, JS::Symbol *sym) +PushMarkStack(GCMarker* gcmarker, JS::Symbol* sym) { // Well-known symbols might not be associated with this runtime. if (sym->isWellKnownSymbol()) @@ -1227,14 +1227,14 @@ PushMarkStack(GCMarker *gcmarker, JS::Symbol *sym) * bounded. */ void -gc::MarkCycleCollectorChildren(JSTracer *trc, Shape *shape) +gc::MarkCycleCollectorChildren(JSTracer* trc, Shape* shape) { /* * We need to mark the global, but it's OK to only do this once instead of * doing it for every Shape in our lineage, since it's always the same * global. */ - JSObject *global = shape->compartment()->unsafeUnbarrieredMaybeGlobal(); + JSObject* global = shape->compartment()->unsafeUnbarrieredMaybeGlobal(); MOZ_ASSERT(global); MarkObjectUnbarriered(trc, &global, "global"); @@ -1247,13 +1247,13 @@ gc::MarkCycleCollectorChildren(JSTracer *trc, Shape *shape) MarkId(trc, &shape->propidRef(), "propid"); if (shape->hasGetterObject()) { - JSObject *tmp = shape->getterObject(); + JSObject* tmp = shape->getterObject(); MarkObjectUnbarriered(trc, &tmp, "getter"); MOZ_ASSERT(tmp == shape->getterObject()); } if (shape->hasSetterObject()) { - JSObject *tmp = shape->setterObject(); + JSObject* tmp = shape->setterObject(); MarkObjectUnbarriered(trc, &tmp, "setter"); MOZ_ASSERT(tmp == shape->setterObject()); } @@ -1263,11 +1263,11 @@ gc::MarkCycleCollectorChildren(JSTracer *trc, Shape *shape) } static void -ScanObjectGroup(GCMarker *gcmarker, ObjectGroup *group) +ScanObjectGroup(GCMarker* gcmarker, ObjectGroup* group) { unsigned count = group->getPropertyCount(); for (unsigned i = 0; i < count; i++) { - if (ObjectGroup::Property *prop = group->getProperty(i)) + if (ObjectGroup::Property* prop = group->getProperty(i)) MarkId(gcmarker, &prop->id, "ObjectGroup property id"); } @@ -1276,7 +1276,7 @@ ScanObjectGroup(GCMarker *gcmarker, ObjectGroup *group) group->compartment()->mark(); - if (GlobalObject *global = group->compartment()->unsafeUnbarrieredMaybeGlobal()) + if (GlobalObject* global = group->compartment()->unsafeUnbarrieredMaybeGlobal()) PushMarkStack(gcmarker, global); if (group->newScript()) @@ -1288,22 +1288,22 @@ ScanObjectGroup(GCMarker *gcmarker, ObjectGroup *group) if (group->maybeUnboxedLayout()) group->unboxedLayout().trace(gcmarker); - if (ObjectGroup *unboxedGroup = group->maybeOriginalUnboxedGroup()) + if (ObjectGroup* unboxedGroup = group->maybeOriginalUnboxedGroup()) PushMarkStack(gcmarker, unboxedGroup); - if (TypeDescr *descr = group->maybeTypeDescr()) + if (TypeDescr* descr = group->maybeTypeDescr()) gcmarker->traverse(descr); - if (JSFunction *fun = group->maybeInterpretedFunction()) + if (JSFunction* fun = group->maybeInterpretedFunction()) gcmarker->traverse(fun); } static void -gc::MarkChildren(JSTracer *trc, ObjectGroup *group) +gc::MarkChildren(JSTracer* trc, ObjectGroup* group) { unsigned count = group->getPropertyCount(); for (unsigned i = 0; i < count; i++) { - if (ObjectGroup::Property *prop = group->getProperty(i)) + if (ObjectGroup::Property* prop = group->getProperty(i)) MarkId(trc, &prop->id, "group_property"); } @@ -1319,17 +1319,17 @@ gc::MarkChildren(JSTracer *trc, ObjectGroup *group) if (group->maybeUnboxedLayout()) group->unboxedLayout().trace(trc); - if (ObjectGroup *unboxedGroup = group->maybeOriginalUnboxedGroup()) { + if (ObjectGroup* unboxedGroup = group->maybeOriginalUnboxedGroup()) { MarkObjectGroupUnbarriered(trc, &unboxedGroup, "group_original_unboxed_group"); group->setOriginalUnboxedGroup(unboxedGroup); } - if (JSObject *descr = group->maybeTypeDescr()) { + if (JSObject* descr = group->maybeTypeDescr()) { MarkObjectUnbarriered(trc, &descr, "group_type_descr"); group->setTypeDescr(&descr->as()); } - if (JSObject *fun = group->maybeInterpretedFunction()) { + if (JSObject* fun = group->maybeInterpretedFunction()) { MarkObjectUnbarriered(trc, &fun, "group_function"); group->setInterpretedFunction(&fun->as()); } @@ -1337,14 +1337,14 @@ gc::MarkChildren(JSTracer *trc, ObjectGroup *group) template static void -PushArenaTyped(GCMarker *gcmarker, ArenaHeader *aheader) +PushArenaTyped(GCMarker* gcmarker, ArenaHeader* aheader) { for (ArenaCellIterUnderGC i(aheader); !i.done(); i.next()) PushMarkStack(gcmarker, i.get()); } void -gc::PushArena(GCMarker *gcmarker, ArenaHeader *aheader) +gc::PushArena(GCMarker* gcmarker, ArenaHeader* aheader) { switch (MapAllocToTraceKind(aheader->getAllocKind())) { case JSTRACE_OBJECT: @@ -1391,14 +1391,14 @@ gc::PushArena(GCMarker *gcmarker, ArenaHeader *aheader) struct SlotArrayLayout { union { - HeapSlot *end; + HeapSlot* end; uintptr_t kind; }; union { - HeapSlot *start; + HeapSlot* start; uintptr_t index; }; - NativeObject *obj; + NativeObject* obj; static void staticAsserts() { /* This should have the same layout as three mark stack items. */ @@ -1454,7 +1454,7 @@ GCMarker::saveValueRanges() } bool -GCMarker::restoreValueArray(NativeObject *obj, void **vpp, void **endp) +GCMarker::restoreValueArray(NativeObject* obj, void** vpp, void** endp) { uintptr_t start = stack.pop(); HeapSlot::Kind kind = (HeapSlot::Kind) stack.pop(); @@ -1464,7 +1464,7 @@ GCMarker::restoreValueArray(NativeObject *obj, void **vpp, void **endp) return false; uint32_t initlen = obj->getDenseInitializedLength(); - HeapSlot *vp = obj->getDenseElementsAllowCopyOnWrite(); + HeapSlot* vp = obj->getDenseElementsAllowCopyOnWrite(); if (start < initlen) { *vpp = vp + start; *endp = vp + initlen; @@ -1474,7 +1474,7 @@ GCMarker::restoreValueArray(NativeObject *obj, void **vpp, void **endp) } } else { MOZ_ASSERT(kind == HeapSlot::Slot); - HeapSlot *vp = obj->fixedSlots(); + HeapSlot* vp = obj->fixedSlots(); unsigned nfixed = obj->numFixedSlots(); unsigned nslots = obj->slotSpan(); if (start < nslots) { @@ -1499,22 +1499,22 @@ void GCMarker::processMarkStackOther(uintptr_t tag, uintptr_t addr) { if (tag == GroupTag) { - ScanObjectGroup(this, reinterpret_cast(addr)); + ScanObjectGroup(this, reinterpret_cast(addr)); } else if (tag == SavedValueArrayTag) { MOZ_ASSERT(!(addr & CellMask)); - NativeObject *obj = reinterpret_cast(addr); - HeapValue *vp, *end; - if (restoreValueArray(obj, (void **)&vp, (void **)&end)) + NativeObject* obj = reinterpret_cast(addr); + HeapValue* vp, *end; + if (restoreValueArray(obj, (void**)&vp, (void**)&end)) pushValueArray(obj, vp, end); else repush(obj); } else if (tag == JitCodeTag) { - reinterpret_cast(addr)->trace(this); + reinterpret_cast(addr)->trace(this); } } MOZ_ALWAYS_INLINE void -GCMarker::markAndScanString(JSObject *source, JSString *str) +GCMarker::markAndScanString(JSObject* source, JSString* str) { if (!str->isPermanentAtom()) { JS_COMPARTMENT_ASSERT(runtime(), str); @@ -1525,7 +1525,7 @@ GCMarker::markAndScanString(JSObject *source, JSString *str) } MOZ_ALWAYS_INLINE void -GCMarker::markAndScanSymbol(JSObject *source, JS::Symbol *sym) +GCMarker::markAndScanSymbol(JSObject* source, JS::Symbol* sym) { if (!sym->isWellKnownSymbol()) { JS_COMPARTMENT_ASSERT(runtime(), sym); @@ -1536,18 +1536,18 @@ GCMarker::markAndScanSymbol(JSObject *source, JS::Symbol *sym) } inline void -GCMarker::processMarkStackTop(SliceBudget &budget) +GCMarker::processMarkStackTop(SliceBudget& budget) { /* * The function uses explicit goto and implements the scanning of the * object directly. It allows to eliminate the tail recursion and * significantly improve the marking performance, see bug 641025. */ - HeapSlot *vp, *end; - JSObject *obj; + HeapSlot* vp, *end; + JSObject* obj; - const int32_t *unboxedTraceList; - uint8_t *unboxedMemory; + const int32_t* unboxedTraceList; + uint8_t* unboxedMemory; uintptr_t addr = stack.pop(); uintptr_t tag = addr & StackTagMask; @@ -1584,11 +1584,11 @@ GCMarker::processMarkStackTop(SliceBudget &budget) return; } - const Value &v = *vp++; + const Value& v = *vp++; if (v.isString()) { markAndScanString(obj, v.toString()); } else if (v.isObject()) { - JSObject *obj2 = &v.toObject(); + JSObject* obj2 = &v.toObject(); MOZ_ASSERT(obj->compartment() == obj2->compartment()); if (mark(obj2)) { // Save the rest of this value array for later and start scanning obj2's children.N @@ -1605,13 +1605,13 @@ GCMarker::processMarkStackTop(SliceBudget &budget) scan_unboxed: { while (*unboxedTraceList != -1) { - JSString *str = *reinterpret_cast(unboxedMemory + *unboxedTraceList); + JSString* str = *reinterpret_cast(unboxedMemory + *unboxedTraceList); markAndScanString(obj, str); unboxedTraceList++; } unboxedTraceList++; while (*unboxedTraceList != -1) { - JSObject *obj2 = *reinterpret_cast(unboxedMemory + *unboxedTraceList); + JSObject* obj2 = *reinterpret_cast(unboxedMemory + *unboxedTraceList); MOZ_ASSERT_IF(obj2, obj->compartment() == obj2->compartment()); if (obj2 && mark(obj2)) repush(obj2); @@ -1619,11 +1619,11 @@ GCMarker::processMarkStackTop(SliceBudget &budget) } unboxedTraceList++; while (*unboxedTraceList != -1) { - const Value &v = *reinterpret_cast(unboxedMemory + *unboxedTraceList); + const Value& v = *reinterpret_cast(unboxedMemory + *unboxedTraceList); if (v.isString()) { markAndScanString(obj, v.toString()); } else if (v.isObject()) { - JSObject *obj2 = &v.toObject(); + JSObject* obj2 = &v.toObject(); MOZ_ASSERT(obj->compartment() == obj2->compartment()); if (mark(obj2)) repush(obj2); @@ -1645,11 +1645,11 @@ GCMarker::processMarkStackTop(SliceBudget &budget) return; } - ObjectGroup *group = obj->groupFromGC(); + ObjectGroup* group = obj->groupFromGC(); traverse(group); /* Call the trace hook if necessary. */ - const Class *clasp = group->clasp(); + const Class* clasp = group->clasp(); if (clasp->trace) { // Global objects all have the same trace hook. That hook is safe without barriers // if the global has no custom trace hook of its own, or has been moved to a different @@ -1658,9 +1658,9 @@ GCMarker::processMarkStackTop(SliceBudget &budget) (!obj->compartment()->options().getTrace() || !obj->isOwnGlobal())), clasp->flags & JSCLASS_IMPLEMENTS_BARRIERS); if (clasp->trace == InlineTypedObject::obj_trace) { - Shape *shape = obj->as().shapeFromGC(); + Shape* shape = obj->as().shapeFromGC(); PushMarkStack(this, shape); - TypeDescr *descr = &obj->as().typeDescr(); + TypeDescr* descr = &obj->as().typeDescr(); if (!descr->hasTraceList()) return; unboxedTraceList = descr->traceList(); @@ -1668,10 +1668,10 @@ GCMarker::processMarkStackTop(SliceBudget &budget) goto scan_unboxed; } if (clasp == &UnboxedPlainObject::class_) { - JSObject *expando = obj->as().maybeExpando(); + JSObject* expando = obj->as().maybeExpando(); if (expando && mark(expando)) repush(expando); - const UnboxedLayout &layout = obj->as().layout(); + const UnboxedLayout& layout = obj->as().layout(); unboxedTraceList = layout.traceList(); if (!unboxedTraceList) return; @@ -1684,9 +1684,9 @@ GCMarker::processMarkStackTop(SliceBudget &budget) if (!clasp->isNative()) return; - NativeObject *nobj = &obj->as(); + NativeObject* nobj = &obj->as(); - Shape *shape = nobj->lastProperty(); + Shape* shape = nobj->lastProperty(); PushMarkStack(this, shape); unsigned nslots = nobj->slotSpan(); @@ -1696,7 +1696,7 @@ GCMarker::processMarkStackTop(SliceBudget &budget) break; if (nobj->denseElementsAreCopyOnWrite()) { - JSObject *owner = nobj->getElementsHeader()->ownerObject(); + JSObject* owner = nobj->getElementsHeader()->ownerObject(); if (owner != nobj) { traverse(owner); break; @@ -1771,49 +1771,49 @@ GCMarker::drainMarkStack(SliceBudget &budget) template void -GCMarker::markChildren(T *thing) +GCMarker::markChildren(T* thing) { thing->markChildren(this); } void -js::TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind) +js::TraceChildren(JSTracer* trc, void* thing, JSGCTraceKind kind) { switch (kind) { case JSTRACE_OBJECT: - static_cast(thing)->markChildren(trc); + static_cast(thing)->markChildren(trc); break; case JSTRACE_SCRIPT: - static_cast(thing)->markChildren(trc); + static_cast(thing)->markChildren(trc); break; case JSTRACE_STRING: - static_cast(thing)->markChildren(trc); + static_cast(thing)->markChildren(trc); break; case JSTRACE_SYMBOL: - static_cast(thing)->markChildren(trc); + static_cast(thing)->markChildren(trc); break; case JSTRACE_BASE_SHAPE: - static_cast(thing)->markChildren(trc); + static_cast(thing)->markChildren(trc); break; case JSTRACE_JITCODE: - static_cast(thing)->trace(trc); + static_cast(thing)->trace(trc); break; case JSTRACE_LAZY_SCRIPT: - static_cast(thing)->markChildren(trc); + static_cast(thing)->markChildren(trc); break; case JSTRACE_SHAPE: - static_cast(thing)->markChildren(trc); + static_cast(thing)->markChildren(trc); break; case JSTRACE_OBJECT_GROUP: - MarkChildren(trc, (ObjectGroup *)thing); + MarkChildren(trc, (ObjectGroup*)thing); break; default: diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp index 471e4745d1..c2fb6b1026 100644 --- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -669,7 +669,7 @@ js::Nursery::moveObjectToTenured(MinorCollectionTracer *trc, js_memcpy(dst, src, srcSize); if (src->isNative()) { - NativeObject *ndst = &dst->as(), *nsrc = &src->as(); + NativeObject* ndst = &dst->as(), *nsrc = &src->as(); tenuredSize += moveSlotsToTenured(ndst, nsrc, dstKind); tenuredSize += moveElementsToTenured(ndst, nsrc, dstKind); @@ -686,7 +686,7 @@ js::Nursery::moveObjectToTenured(MinorCollectionTracer *trc, } MOZ_ALWAYS_INLINE size_t -js::Nursery::moveSlotsToTenured(NativeObject *dst, NativeObject *src, AllocKind dstKind) +js::Nursery::moveSlotsToTenured(NativeObject* dst, NativeObject* src, AllocKind dstKind) { /* Fixed slots have already been copied over. */ if (!src->hasDynamicSlots()) diff --git a/js/src/gc/Statistics.h b/js/src/gc/Statistics.h index 4fdd86cadc..9e6fb3ad3a 100644 --- a/js/src/gc/Statistics.h +++ b/js/src/gc/Statistics.h @@ -216,7 +216,7 @@ struct Statistics } JS::gcreason::Reason reason; - const char *resetReason; + const char* resetReason; int64_t start, end; size_t startFaults, endFaults; int64_t phaseTimes[MAX_MULTIPARENT_PHASES + 1][PHASE_LIMIT]; @@ -248,7 +248,7 @@ struct Statistics JSGCInvocationKind gckind; - const char *nonincrementalReason_; + const char* nonincrementalReason_; SliceDataVector slices; diff --git a/js/src/gc/StoreBuffer.cpp b/js/src/gc/StoreBuffer.cpp index b1947e3ee5..e98570dc1d 100644 --- a/js/src/gc/StoreBuffer.cpp +++ b/js/src/gc/StoreBuffer.cpp @@ -21,9 +21,9 @@ using mozilla::ReentrancyGuard; /*** Edges ***/ void -StoreBuffer::SlotsEdge::mark(JSTracer *trc) const +StoreBuffer::SlotsEdge::mark(JSTracer* trc) const { - NativeObject *obj = object(); + NativeObject* obj = object(); // Beware JSObject::swap exchanging a native object for a non-native one. if (!obj->isNative()) diff --git a/js/src/irregexp/NativeRegExpMacroAssembler.cpp b/js/src/irregexp/NativeRegExpMacroAssembler.cpp index a5df6eb573..9396d9a130 100644 --- a/js/src/irregexp/NativeRegExpMacroAssembler.cpp +++ b/js/src/irregexp/NativeRegExpMacroAssembler.cpp @@ -68,7 +68,7 @@ NativeRegExpMacroAssembler::NativeRegExpMacroAssembler(LifoAlloc* alloc, RegExpS runtime(rt), mode_(mode) { // Find physical registers for each compiler register. - GeneralRegisterSet regs(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); input_end_pointer = regs.takeAny(); current_character = regs.takeAny(); @@ -382,7 +382,7 @@ NativeRegExpMacroAssembler::GenerateCode(JSContext* cx, bool match_only) masm.movePtr(ImmPtr(runtime), temp1); // Save registers before calling C function - GeneralRegisterSet volatileRegs = GeneralRegisterSet::Volatile(); + LiveGeneralRegisterSet volatileRegs(GeneralRegisterSet::Volatile()); #if defined(JS_CODEGEN_ARM) volatileRegs.add(Register::FromCode(Registers::lr)); #elif defined(JS_CODEGEN_MIPS) @@ -784,7 +784,7 @@ NativeRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase(int start_reg, Label MOZ_ASSERT(mode_ == CHAR16); // Note: temp1 needs to be saved/restored if it is volatile, as it is used after the call. - GeneralRegisterSet volatileRegs = GeneralRegisterSet::Volatile(); + LiveGeneralRegisterSet volatileRegs(GeneralRegisterSet::Volatile()); volatileRegs.takeUnchecked(temp0); volatileRegs.takeUnchecked(temp2); masm.PushRegsInMask(volatileRegs); diff --git a/js/src/irregexp/NativeRegExpMacroAssembler.h b/js/src/irregexp/NativeRegExpMacroAssembler.h index 8b0ee91812..7993dd6659 100644 --- a/js/src/irregexp/NativeRegExpMacroAssembler.h +++ b/js/src/irregexp/NativeRegExpMacroAssembler.h @@ -181,7 +181,9 @@ class MOZ_STACK_CLASS NativeRegExpMacroAssembler : public RegExpMacroAssembler jit::Label stack_overflow_label_; jit::Label exit_with_exception_label_; - jit::GeneralRegisterSet savedNonVolatileRegisters; + // Set of registers which are used by the code generator, and as such which + // are saved. + jit::LiveGeneralRegisterSet savedNonVolatileRegisters; struct LabelPatch { // Once it is bound via BindBacktrack, |label| becomes null and diff --git a/js/src/jit/AlignmentMaskAnalysis.cpp b/js/src/jit/AlignmentMaskAnalysis.cpp index e2f0764c64..255c7e9fb2 100644 --- a/js/src/jit/AlignmentMaskAnalysis.cpp +++ b/js/src/jit/AlignmentMaskAnalysis.cpp @@ -19,7 +19,7 @@ IsAlignmentMask(uint32_t m) } static void -AnalyzeAsmHeapAddress(MDefinition *ptr, MIRGraph &graph) +AnalyzeAsmHeapAddress(MDefinition* ptr, MIRGraph& graph) { // Fold (a+i)&m to (a&m)+i, since the users of the BitAnd include heap // accesses. This will expose the redundancy for GVN when expressions diff --git a/js/src/jit/AlignmentMaskAnalysis.h b/js/src/jit/AlignmentMaskAnalysis.h index 3a6f17e983..4cec1104c5 100644 --- a/js/src/jit/AlignmentMaskAnalysis.h +++ b/js/src/jit/AlignmentMaskAnalysis.h @@ -14,10 +14,10 @@ class MIRGraph; class AlignmentMaskAnalysis { - MIRGraph &graph_; + MIRGraph& graph_; public: - explicit AlignmentMaskAnalysis(MIRGraph &graph) + explicit AlignmentMaskAnalysis(MIRGraph& graph) : graph_(graph) {} diff --git a/js/src/jit/BacktrackingAllocator.cpp b/js/src/jit/BacktrackingAllocator.cpp index e5cccb0b76..e77c61c997 100644 --- a/js/src/jit/BacktrackingAllocator.cpp +++ b/js/src/jit/BacktrackingAllocator.cpp @@ -15,13 +15,13 @@ using mozilla::DebugOnly; bool BacktrackingAllocator::init() { - RegisterSet remainingRegisters(allRegisters_); - while (!remainingRegisters.empty(/* float = */ false)) { - AnyRegister reg = AnyRegister(remainingRegisters.takeUnaliasedGeneral()); + LiveRegisterSet remainingRegisters(allRegisters_.asLiveSet()); + while (!remainingRegisters.emptyGeneral()) { + AnyRegister reg = AnyRegister(remainingRegisters.takeAnyGeneral()); registers[reg.code()].allocatable = true; } - while (!remainingRegisters.empty(/* float = */ true)) { - AnyRegister reg = AnyRegister(remainingRegisters.takeUnaliasedFloat()); + while (!remainingRegisters.emptyFloat()) { + AnyRegister reg = AnyRegister(remainingRegisters.takeAnyFloat()); registers[reg.code()].allocatable = true; } diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index c563f45ddd..1035dbce15 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -467,7 +467,7 @@ BaselineCompiler::emitOutOfLinePostBarrierSlot() masm.bind(&postBarrierSlot_); Register objReg = R2.scratchReg(); - GeneralRegisterSet regs(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); regs.take(R0); regs.take(objReg); regs.take(BaselineFrameReg); @@ -799,9 +799,9 @@ bool BaselineCompiler::emitTraceLoggerEnter() { TraceLoggerThread *logger = TraceLoggerForMainThread(cx->runtime()); - RegisterSet regs = RegisterSet::Volatile(); - Register loggerReg = regs.takeGeneral(); - Register scriptReg = regs.takeGeneral(); + AllocatableRegisterSet regs(RegisterSet::Volatile()); + Register loggerReg = regs.takeAnyGeneral(); + Register scriptReg = regs.takeAnyGeneral(); Label noTraceLogger; traceLoggerEnterToggleOffset_ = masm.toggledJump(&noTraceLogger); @@ -833,7 +833,8 @@ bool BaselineCompiler::emitTraceLoggerExit() { TraceLoggerThread *logger = TraceLoggerForMainThread(cx->runtime()); - Register loggerReg = RegisterSet::Volatile().takeGeneral(); + AllocatableRegisterSet regs(RegisterSet::Volatile()); + Register loggerReg = regs.takeAnyGeneral(); Label noTraceLogger; traceLoggerExitToggleOffset_ = masm.toggledJump(&noTraceLogger); @@ -3588,7 +3589,7 @@ BaselineCompiler::emit_JSOP_RESUME() frame.syncStack(0); masm.checkStackAlignment(); - GeneralRegisterSet regs(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); regs.take(BaselineFrameReg); // Load generator object. diff --git a/js/src/jit/BaselineDebugModeOSR.cpp b/js/src/jit/BaselineDebugModeOSR.cpp index 50b4e400fe..a935a3d53c 100644 --- a/js/src/jit/BaselineDebugModeOSR.cpp +++ b/js/src/jit/BaselineDebugModeOSR.cpp @@ -1072,7 +1072,7 @@ EmitBaselineDebugModeOSRHandlerTail(MacroAssembler& masm, Register temp, bool re masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, FinishBaselineDebugModeOSR)); // Restore saved values. - GeneralRegisterSet jumpRegs(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet jumpRegs(GeneralRegisterSet::All()); if (returnFromCallVM) { jumpRegs.take(ReturnReg); } else { @@ -1099,7 +1099,7 @@ JitRuntime::generateBaselineDebugModeOSRHandler(JSContext* cx, uint32_t* noFrame { MacroAssembler masm(cx); - GeneralRegisterSet regs(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); regs.take(BaselineFrameReg); regs.take(ReturnReg); Register temp = regs.takeAny(); diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 40b127c0df..c99960618f 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -425,12 +425,13 @@ ICStub::trace(JSTracer* trc) } case ICStub::SetProp_Native: { ICSetProp_Native *propStub = toSetProp_Native(); - propStub->receiverGuard().trace(trc); + MarkShape(trc, &propStub->shape(), "baseline-setpropnative-stub-shape"); + MarkObjectGroup(trc, &propStub->group(), "baseline-setpropnative-stub-group"); break; } case ICStub::SetProp_NativeAdd: { ICSetProp_NativeAdd *propStub = toSetProp_NativeAdd(); - propStub->receiverGuard().trace(trc); + MarkObjectGroup(trc, &propStub->group(), "baseline-setpropnativeadd-stub-group"); MarkShape(trc, &propStub->newShape(), "baseline-setpropnativeadd-stub-newshape"); if (propStub->newGroup()) MarkObjectGroup(trc, &propStub->newGroup(), "baseline-setpropnativeadd-stub-new-group"); @@ -735,7 +736,7 @@ ICStubCompiler::leaveStubFrame(MacroAssembler& masm, bool calledIntoIon) inline bool ICStubCompiler::emitPostWriteBarrierSlot(MacroAssembler &masm, Register obj, ValueOperand val, - Register scratch, GeneralRegisterSet saveRegs) + Register scratch, LiveGeneralRegisterSet saveRegs) { Label skipBarrier; masm.branchPtrInNurseryRange(Assembler::Equal, obj, scratch, &skipBarrier); @@ -745,7 +746,7 @@ ICStubCompiler::emitPostWriteBarrierSlot(MacroAssembler &masm, Register obj, Val #if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS) saveRegs.add(BaselineTailCallReg); #endif - saveRegs = GeneralRegisterSet::Intersect(saveRegs, GeneralRegisterSet::Volatile()); + saveRegs.set() = GeneralRegisterSet::Intersect(saveRegs.set(), GeneralRegisterSet::Volatile()); masm.PushRegsInMask(saveRegs); masm.setupUnalignedABICall(2, scratch); masm.movePtr(ImmPtr(cx->runtime()), scratch); @@ -999,7 +1000,7 @@ ICWarmUpCounter_Fallback::Compiler::generateStubCode(MacroAssembler& masm) } // Get a scratch register. - GeneralRegisterSet regs(availableGeneralRegs(0)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(0)); Register osrDataReg = R0.scratchReg(); regs.take(osrDataReg); regs.takeUnchecked(OsrFrameReg); @@ -1994,7 +1995,7 @@ ICCompare_String::Compiler::generateStubCode(MacroAssembler& masm) Register left = masm.extractString(R0, ExtractTemp0); Register right = masm.extractString(R1, ExtractTemp1); - GeneralRegisterSet regs(availableGeneralRegs(2)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); Register scratchReg = regs.takeAny(); masm.compareStrings(op, left, right, scratchReg, &failure); @@ -3192,7 +3193,7 @@ CheckDOMProxyExpandoDoesNotShadow(JSContext *cx, MacroAssembler &masm, Register Address *expandoAndGenerationAddr, Address *generationAddr, Register scratch, - GeneralRegisterSet &domProxyRegSet, + AllocatableGeneralRegisterSet &domProxyRegSet, Label *checkFailed) { // Guard that the object does not have expando properties, or has an expando @@ -3461,18 +3462,12 @@ IsCacheableSetPropAddSlot(JSContext *cx, JSObject *obj, Shape *oldShape, jsid id, JSObject *holder, Shape *shape, size_t *protoChainDepth) { - if (!shape || obj != holder) + if (!shape) return false; // Property must be set directly on object, and be last added property of object. - if (obj->isNative()) { - if (shape != obj->as().lastProperty()) - return false; - } else if (obj->is()) { - UnboxedExpandoObject *expando = obj->as().maybeExpando(); - if (!expando || shape != expando->lastProperty()) - return false; - } + if (!obj->isNative() || obj != holder || shape != obj->as().lastProperty()) + return false; // Object must be extensible, oldShape must be immediate parent of curShape. if (!obj->nonProxyIsExtensible() || shape->previous() != oldShape) @@ -4148,7 +4143,7 @@ static const VMFunction DoAtomizeStringInfo = FunctionInfo(Do bool ICGetElemNativeCompiler::emitCallNative(MacroAssembler &masm, Register objReg) { - GeneralRegisterSet regs = availableGeneralRegs(0); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(0)); regs.takeUnchecked(objReg); regs.takeUnchecked(BaselineTailCallReg); @@ -4175,7 +4170,7 @@ ICGetElemNativeCompiler::emitCallNative(MacroAssembler &masm, Register objReg) bool ICGetElemNativeCompiler::emitCallScripted(MacroAssembler &masm, Register objReg) { - GeneralRegisterSet regs = availableGeneralRegs(0); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(0)); regs.takeUnchecked(objReg); regs.takeUnchecked(BaselineTailCallReg); @@ -4249,7 +4244,7 @@ ICGetElemNativeCompiler::generateStubCode(MacroAssembler &masm) masm.branchTestObject(Assembler::NotEqual, R0, &failure); masm.branchTestString(Assembler::NotEqual, R1, &failure); - GeneralRegisterSet regs(availableGeneralRegs(2)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); Register scratchReg = regs.takeAny(); // Unbox object. @@ -4366,7 +4361,7 @@ ICGetElemNativeCompiler::generateStubCode(MacroAssembler &masm) masm.branchTestUndefined(Assembler::NotEqual, valAddr, &skipNoSuchMethod); - GeneralRegisterSet regs = availableGeneralRegs(0); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(0)); regs.take(R1); regs.take(R0); regs.takeUnchecked(objReg); @@ -4469,7 +4464,7 @@ ICGetElem_String::Compiler::generateStubCode(MacroAssembler& masm) masm.branchTestString(Assembler::NotEqual, R0, &failure); masm.branchTestInt32(Assembler::NotEqual, R1, &failure); - GeneralRegisterSet regs(availableGeneralRegs(2)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); Register scratchReg = regs.takeAny(); // Unbox string in R0. @@ -4517,7 +4512,7 @@ ICGetElem_Dense::Compiler::generateStubCode(MacroAssembler& masm) masm.branchTestObject(Assembler::NotEqual, R0, &failure); masm.branchTestInt32(Assembler::NotEqual, R1, &failure); - GeneralRegisterSet regs(availableGeneralRegs(2)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); Register scratchReg = regs.takeAny(); // Unbox R0 and shape guard. @@ -4551,7 +4546,7 @@ ICGetElem_Dense::Compiler::generateStubCode(MacroAssembler& masm) regs.takeUnchecked(obj); regs.takeUnchecked(key); regs.takeUnchecked(BaselineTailCallReg); - ValueOperand val = regs.takeValueOperand(); + ValueOperand val = regs.takeAnyValue(); masm.loadValue(element, val); masm.branchTestUndefined(Assembler::NotEqual, val, &skipNoSuchMethod); @@ -4665,7 +4660,7 @@ ICGetElem_TypedArray::Compiler::generateStubCode(MacroAssembler& masm) masm.branchTestObject(Assembler::NotEqual, R0, &failure); - GeneralRegisterSet regs(availableGeneralRegs(2)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); Register scratchReg = regs.takeAny(); // Unbox R0 and shape guard. @@ -4745,7 +4740,7 @@ ICGetElem_Arguments::Compiler::generateStubCode(MacroAssembler& masm) masm.branchTestInt32(Assembler::NotEqual, R1, &failure); Register idx = masm.extractInt32(R1, ExtractTemp1); - GeneralRegisterSet regs(availableGeneralRegs(2)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); Register scratch = regs.takeAny(); // Load num actual arguments @@ -4775,7 +4770,7 @@ ICGetElem_Arguments::Compiler::generateStubCode(MacroAssembler& masm) bool isStrict = which_ == ICGetElem_Arguments::Strict; const Class* clasp = isStrict ? &StrictArgumentsObject::class_ : &NormalArgumentsObject::class_; - GeneralRegisterSet regs(availableGeneralRegs(2)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); Register scratchReg = regs.takeAny(); // Guard on input being an arguments object. @@ -4849,7 +4844,7 @@ ICGetElem_Arguments::Compiler::generateStubCode(MacroAssembler& masm) regs.takeUnchecked(objReg); regs.takeUnchecked(idxReg); regs.takeUnchecked(BaselineTailCallReg); - ValueOperand val = regs.takeValueOperand(); + ValueOperand val = regs.takeAnyValue(); // Box and push obj and key onto baseline frame stack for decompiler. EmitRestoreTailCallReg(masm); @@ -5283,7 +5278,7 @@ ICSetElem_Dense::Compiler::generateStubCode(MacroAssembler& masm) masm.branchTestObject(Assembler::NotEqual, R0, &failure); masm.branchTestInt32(Assembler::NotEqual, R1, &failure); - GeneralRegisterSet regs(availableGeneralRegs(2)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); Register scratchReg = regs.takeAny(); // Unbox R0 and guard on its shape. @@ -5378,7 +5373,7 @@ ICSetElem_Dense::Compiler::generateStubCode(MacroAssembler& masm) regs.add(key); if (cx->runtime()->gc.nursery.exists()) { Register r = regs.takeAny(); - GeneralRegisterSet saveRegs; + LiveGeneralRegisterSet saveRegs; emitPostWriteBarrierSlot(masm, obj, tmpVal, r, saveRegs); regs.add(r); } @@ -5449,7 +5444,7 @@ ICSetElemDenseAddCompiler::generateStubCode(MacroAssembler& masm) masm.branchTestObject(Assembler::NotEqual, R0, &failure); masm.branchTestInt32(Assembler::NotEqual, R1, &failure); - GeneralRegisterSet regs(availableGeneralRegs(2)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); Register scratchReg = regs.takeAny(); // Unbox R0 and guard on its shape. @@ -5563,7 +5558,7 @@ ICSetElemDenseAddCompiler::generateStubCode(MacroAssembler& masm) regs.add(key); if (cx->runtime()->gc.nursery.exists()) { Register r = regs.takeAny(); - GeneralRegisterSet saveRegs; + LiveGeneralRegisterSet saveRegs; emitPostWriteBarrierSlot(masm, obj, tmpVal, r, saveRegs); regs.add(r); } @@ -5659,7 +5654,7 @@ ICSetElem_TypedArray::Compiler::generateStubCode(MacroAssembler& masm) masm.branchTestObject(Assembler::NotEqual, R0, &failure); - GeneralRegisterSet regs(availableGeneralRegs(2)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); Register scratchReg = regs.takeAny(); // Unbox R0 and shape guard. @@ -6178,7 +6173,7 @@ bool ICGetName_Scope::Compiler::generateStubCode(MacroAssembler& masm) { Label failure; - GeneralRegisterSet regs(availableGeneralRegs(1)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(1)); Register obj = R0.scratchReg(); Register walker = regs.takeAny(); Register scratch = regs.takeAny(); @@ -7187,7 +7182,7 @@ ICGetProp_Primitive::Compiler::generateStubCode(MacroAssembler& masm) MOZ_CRASH("unexpected type"); } - GeneralRegisterSet regs(availableGeneralRegs(1)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(1)); Register holderReg = regs.takeAny(); Register scratchReg = regs.takeAny(); @@ -7278,7 +7273,7 @@ bool ICGetPropNativeCompiler::generateStubCode(MacroAssembler& masm) { Label failure; - GeneralRegisterSet regs(availableGeneralRegs(0)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(0)); Register objReg = InvalidReg; if (inputDefinitelyObject_) { @@ -7346,7 +7341,7 @@ ICGetPropNativeCompiler::generateStubCode(MacroAssembler& masm) regs = availableGeneralRegs(0); regs.takeUnchecked(objReg); regs.takeUnchecked(BaselineTailCallReg); - ValueOperand val = regs.takeValueOperand(); + ValueOperand val = regs.takeAnyValue(); // Box and push obj onto baseline frame stack for decompiler. EmitRestoreTailCallReg(masm); @@ -7423,7 +7418,7 @@ ICGetPropNativeDoesNotExistCompiler::generateStubCode(MacroAssembler& masm) { Label failure; - GeneralRegisterSet regs(availableGeneralRegs(1)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(1)); Register scratch = regs.takeAny(); #ifdef DEBUG @@ -7473,7 +7468,7 @@ ICGetProp_CallScripted::Compiler::generateStubCode(MacroAssembler &masm) { Label failure; Label failureLeaveStubFrame; - GeneralRegisterSet regs(availableGeneralRegs(1)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(1)); Register scratch = regs.takeAnyExcluding(BaselineTailCallReg); // Guard input is an object. @@ -7562,7 +7557,7 @@ ICGetProp_CallNative::Compiler::generateStubCode(MacroAssembler &masm) { Label failure; - GeneralRegisterSet regs(availableGeneralRegs(0)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(0)); Register objReg = InvalidReg; MOZ_ASSERT(!(inputDefinitelyObject_ && outerClass_)); @@ -7635,7 +7630,7 @@ ICGetPropCallDOMProxyNativeCompiler::generateStubCode(MacroAssembler& masm, Address* generationAddr) { Label failure; - GeneralRegisterSet regs(availableGeneralRegs(1)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(1)); Register scratch = regs.takeAnyExcluding(BaselineTailCallReg); // Guard input is an object. @@ -7653,7 +7648,7 @@ ICGetPropCallDOMProxyNativeCompiler::generateStubCode(MacroAssembler& masm, // Guard that our expando object hasn't started shadowing this property. { - GeneralRegisterSet domProxyRegSet(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet domProxyRegSet(GeneralRegisterSet::All()); domProxyRegSet.take(BaselineStubReg); domProxyRegSet.take(objReg); domProxyRegSet.take(scratch); @@ -7776,7 +7771,7 @@ ICGetProp_DOMProxyShadowed::Compiler::generateStubCode(MacroAssembler& masm) { Label failure; - GeneralRegisterSet regs(availableGeneralRegs(1)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(1)); // Need to reserve a scratch register, but the scratch register should not be // BaselineTailCallReg, because it's used for |enterStubFrame| which needs a // non-BaselineTailCallReg scratch reg. @@ -7928,7 +7923,7 @@ static const VMFunction DoGetPropGenericInfo = FunctionInfo( bool ICGetProp_Generic::Compiler::generateStubCode(MacroAssembler &masm) { - GeneralRegisterSet regs(availableGeneralRegs(1)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(1)); Register scratch = regs.takeAnyExcluding(BaselineTailCallReg); @@ -7957,7 +7952,7 @@ ICGetProp_Unboxed::Compiler::generateStubCode(MacroAssembler &masm) { Label failure; - GeneralRegisterSet regs(availableGeneralRegs(1)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(1)); Register scratch = regs.takeAnyExcluding(BaselineTailCallReg); @@ -7992,7 +7987,7 @@ ICGetProp_TypedObject::Compiler::generateStubCode(MacroAssembler &masm) CheckForNeuteredTypedObject(cx, masm, &failure); - GeneralRegisterSet regs(availableGeneralRegs(1)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(1)); Register scratch1 = regs.takeAnyExcluding(BaselineTailCallReg); Register scratch2 = regs.takeAnyExcluding(BaselineTailCallReg); @@ -8079,34 +8074,21 @@ BaselineScript::noteAccessedGetter(uint32_t pcOffset) // value property. static bool TryAttachSetValuePropStub(JSContext *cx, HandleScript script, jsbytecode *pc, ICSetProp_Fallback *stub, - HandleObject obj, const ReceiverGuard::RootedStackGuard &oldGuard, + HandleObject obj, HandleShape oldShape, HandleObjectGroup oldGroup, HandlePropertyName name, HandleId id, HandleValue rhs, bool *attached) { MOZ_ASSERT(!*attached); - if (obj->watched()) + if (!obj->isNative() || obj->watched()) return true; RootedShape shape(cx); RootedObject holder(cx); if (!EffectlesslyLookupProperty(cx, obj, name, &holder, &shape)) return false; - if (!holder) - return true; - - if (holder->is()) { - UnboxedExpandoObject *expando = holder->as().maybeExpando(); - if (expando) { - shape = expando->lookup(cx, name); - if (!shape) - return true; - } else { - return true; - } - } size_t chainDepth; - if (IsCacheableSetPropAddSlot(cx, obj, oldGuard.shape, id, holder, shape, &chainDepth)) { + if (IsCacheableSetPropAddSlot(cx, obj, oldShape, id, holder, shape, &chainDepth)) { // Don't attach if proto chain depth is too high. if (chainDepth > ICSetProp_NativeAdd::MAX_PROTO_CHAIN_DEPTH) return true; @@ -8115,22 +8097,18 @@ TryAttachSetValuePropStub(JSContext *cx, HandleScript script, jsbytecode *pc, IC // script properties analysis hasn't been performed for yet, as there // may be a shape change required here afterwards. Pretend we attached // a stub, though, so the access is not marked as unoptimizable. - if (oldGuard.group->newScript() && !oldGuard.group->newScript()->analyzed()) { + if (oldGroup->newScript() && !oldGroup->newScript()->analyzed()) { *attached = true; return true; } bool isFixedSlot; uint32_t offset; - if (obj->is()) { - GetFixedOrDynamicSlotOffset(&obj->as(), shape->slot(), &isFixedSlot, &offset); - } else { - GetFixedOrDynamicSlotOffset(obj->as().maybeExpando(), - shape->slot(), &isFixedSlot, &offset); - } + GetFixedOrDynamicSlotOffset(&obj->as(), shape->slot(), &isFixedSlot, &offset); JitSpew(JitSpew_BaselineIC, " Generating SetProp(NativeObject.ADD) stub"); - ICSetPropNativeAddCompiler compiler(cx, obj, oldGuard, chainDepth, isFixedSlot, offset); + ICSetPropNativeAddCompiler compiler(cx, obj, oldShape, oldGroup, + chainDepth, isFixedSlot, offset); ICUpdatedStub *newStub = compiler.getStub(compiler.getStubSpace(script)); if (!newStub) return false; @@ -8142,10 +8120,7 @@ TryAttachSetValuePropStub(JSContext *cx, HandleScript script, jsbytecode *pc, IC return true; } - if (!obj->isNative()) - return true; - - if (IsCacheableSetPropWriteSlot(obj, oldGuard.shape, holder, shape)) { + if (IsCacheableSetPropWriteSlot(obj, oldShape, holder, shape)) { // For some property writes, such as the initial overwrite of global // properties, TI will not mark the property as having been // overwritten. Don't attach a stub in this case, so that we don't @@ -8161,7 +8136,7 @@ TryAttachSetValuePropStub(JSContext *cx, HandleScript script, jsbytecode *pc, IC GetFixedOrDynamicSlotOffset(&obj->as(), shape->slot(), &isFixedSlot, &offset); JitSpew(JitSpew_BaselineIC, " Generating SetProp(NativeObject.PROP) stub"); - MOZ_ASSERT(obj->as().lastProperty() == oldGuard.shape, + MOZ_ASSERT(obj->as().lastProperty() == oldShape, "Should this really be a SetPropWriteSlot?"); ICSetProp_Native::Compiler compiler(cx, obj, isFixedSlot, offset); ICSetProp_Native* newStub = compiler.getStub(compiler.getStubSpace(script)); @@ -8295,41 +8270,6 @@ TryAttachUnboxedSetPropStub(JSContext *cx, HandleScript script, return true; } -static bool -TryAttachUnboxedExpandoSetPropStub(JSContext *cx, HandleScript script, - ICSetProp_Fallback *stub, HandleId id, - HandleObject obj, Shape *oldShape, HandleValue rhs, bool *attached) -{ - MOZ_ASSERT(!*attached); - - if (!obj->is()) - return true; - - UnboxedExpandoObject *expando = obj->as().maybeExpando(); - if (!expando || expando->lastProperty() != oldShape) - return true; - - Shape *shape = expando->lookup(cx, id); - if (!shape || !shape->hasDefaultSetter() || !shape->hasSlot() || !shape->writable()) - return true; - - bool isFixedSlot; - uint32_t offset; - GetFixedOrDynamicSlotOffset(expando, shape->slot(), &isFixedSlot, &offset); - - ICSetProp_Native::Compiler compiler(cx, obj, isFixedSlot, offset); - ICSetProp_Native *newStub = compiler.getStub(compiler.getStubSpace(script)); - if (!newStub || !newStub->addUpdateStubForValue(cx, script, obj, id, rhs)) - return false; - - stub->addNewStub(newStub); - - StripPreliminaryObjectStubs(cx, stub); - - *attached = true; - return true; -} - static bool TryAttachTypedObjectSetPropStub(JSContext* cx, HandleScript script, ICSetProp_Fallback* stub, HandleId id, @@ -8404,9 +8344,13 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_ RootedId id(cx, NameToId(name)); RootedObject obj(cx, ToObjectFromStack(cx, lhs)); - if (!obj || !obj->getGroup(cx)) + if (!obj) return false; - ReceiverGuard::RootedStackGuard oldGuard(cx, ReceiverGuard::StackGuard(obj, true)); + RootedShape oldShape(cx, obj->maybeShape()); + RootedObjectGroup oldGroup(cx, obj->getGroup(cx)); + if (!oldGroup) + return false; + ReceiverGuard::RootedStackGuard oldGuard(cx, ReceiverGuard::StackGuard(obj)); bool attached = false; // There are some reasons we can fail to attach a stub that are temporary. @@ -8441,7 +8385,7 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_ MOZ_ASSERT(op == JSOP_SETPROP || op == JSOP_STRICTSETPROP); RootedValue v(cx, rhs); - if (!PutProperty(cx, obj, id, &v, op == JSOP_STRICTSETPROP)) + if (!PutProperty(cx, obj, id, v, op == JSOP_STRICTSETPROP)) return false; } @@ -8459,7 +8403,7 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_ if (!attached && lhs.isObject() && - !TryAttachSetValuePropStub(cx, script, pc, stub, obj, oldGuard, + !TryAttachSetValuePropStub(cx, script, pc, stub, obj, oldShape, oldGroup, name, id, rhs, &attached)) { return false; @@ -8476,15 +8420,6 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_ if (attached) return true; - if (!attached && - lhs.isObject() && - !TryAttachUnboxedExpandoSetPropStub(cx, script, stub, id, obj, oldGuard.shape, rhs, &attached)) - { - return false; - } - if (attached) - return true; - if (!attached && lhs.isObject() && !TryAttachTypedObjectSetPropStub(cx, script, stub, id, obj, rhs, &attached)) @@ -8557,17 +8492,23 @@ ICSetProp_Fallback::Compiler::postGenerateStubCode(MacroAssembler& masm, Handle< bool ICSetProp_Native::Compiler::generateStubCode(MacroAssembler &masm) { - Label failure, failurePopObject; + Label failure; // Guard input is an object. masm.branchTestObject(Assembler::NotEqual, R0, &failure); - Register objReg = masm.extractObject(R0, ExtractTemp0); - GeneralRegisterSet regs(availableGeneralRegs(2)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); Register scratch = regs.takeAny(); - GuardNativeOrUnboxedReceiver(masm, ReceiverGuard::StackGuard(obj_, true), objReg, scratch, - ICSetProp_Native::offsetOfReceiverGuard(), &failure); + // Unbox and shape guard. + Register objReg = masm.extractObject(R0, ExtractTemp0); + masm.loadPtr(Address(BaselineStubReg, ICSetProp_Native::offsetOfShape()), scratch); + masm.branchTestObjShape(Assembler::NotEqual, objReg, scratch, &failure); + + // Guard that the object group matches. + masm.loadPtr(Address(BaselineStubReg, ICSetProp_Native::offsetOfGroup()), scratch); + masm.branchPtr(Assembler::NotEqual, Address(objReg, JSObject::offsetOfGroup()), scratch, + &failure); // Stow both R0 and R1 (object and value). EmitStowICValues(masm, 2); @@ -8586,13 +8527,7 @@ ICSetProp_Native::Compiler::generateStubCode(MacroAssembler &masm) regs.takeUnchecked(objReg); Register holderReg; - if (obj_->is()) { - // We are loading off the expando object, so use that for the holder. - holderReg = regs.takeAny(); - masm.loadPtr(Address(objReg, UnboxedPlainObject::offsetOfExpando()), holderReg); - if (!isFixedSlot_) - masm.loadPtr(Address(holderReg, NativeObject::offsetOfSlots()), holderReg); - } else if (isFixedSlot_) { + if (isFixedSlot_) { holderReg = objReg; } else { holderReg = regs.takeAny(); @@ -8607,7 +8542,7 @@ ICSetProp_Native::Compiler::generateStubCode(MacroAssembler &masm) regs.add(holderReg); if (cx->runtime()->gc.nursery.exists()) { Register scr = regs.takeAny(); - GeneralRegisterSet saveRegs; + LiveGeneralRegisterSet saveRegs; saveRegs.add(R1); emitPostWriteBarrierSlot(masm, objReg, R1, scr, saveRegs); regs.add(scr); @@ -8617,11 +8552,6 @@ ICSetProp_Native::Compiler::generateStubCode(MacroAssembler &masm) masm.moveValue(R1, R0); EmitReturnFromIC(masm); - if (failurePopObject.used()) { - masm.bind(&failurePopObject); - masm.pop(objReg); - } - // Failure case - jump to next stub masm.bind(&failure); EmitStubGuardFailure(masm); @@ -8632,6 +8562,8 @@ ICUpdatedStub * ICSetPropNativeAddCompiler::getStub(ICStubSpace *space) { AutoShapeVector shapes(cx); + if (!shapes.append(oldShape_)) + return nullptr; if (!GetProtoShapes(obj_, protoChainDepth_, &shapes)) return nullptr; @@ -8655,18 +8587,24 @@ ICSetPropNativeAddCompiler::getStub(ICStubSpace *space) bool ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler &masm) { - Label failure, failurePopObject, failureUnstow; + Label failure; + Label failureUnstow; // Guard input is an object. masm.branchTestObject(Assembler::NotEqual, R0, &failure); - GeneralRegisterSet regs(availableGeneralRegs(2)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); Register scratch = regs.takeAny(); - // Unbox and guard that the object group matches. + // Unbox and guard against old shape. Register objReg = masm.extractObject(R0, ExtractTemp0); - GuardNativeOrUnboxedReceiver(masm, ReceiverGuard::StackGuard(obj_, true), objReg, scratch, - ICSetProp_NativeAdd::offsetOfReceiverGuard(), &failure); + masm.loadPtr(Address(BaselineStubReg, ICSetProp_NativeAddImpl<0>::offsetOfShape(0)), scratch); + masm.branchTestObjShape(Assembler::NotEqual, objReg, scratch, &failure); + + // Guard that the object group matches. + masm.loadPtr(Address(BaselineStubReg, ICSetProp_NativeAdd::offsetOfGroup()), scratch); + masm.branchPtr(Assembler::NotEqual, Address(objReg, JSObject::offsetOfGroup()), scratch, + &failure); // Stow both R0 and R1 (object and value). EmitStowICValues(masm, 2); @@ -8678,7 +8616,7 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler &masm) for (size_t i = 0; i < protoChainDepth_; i++) { masm.loadObjProto(i == 0 ? objReg : protoReg, protoReg); masm.branchTestPtr(Assembler::Zero, protoReg, protoReg, &failureUnstow); - masm.loadPtr(Address(BaselineStubReg, ICSetProp_NativeAddImpl<1>::offsetOfShape(i)), + masm.loadPtr(Address(BaselineStubReg, ICSetProp_NativeAddImpl<0>::offsetOfShape(i + 1)), scratch); masm.branchTestObjShape(Assembler::NotEqual, protoReg, scratch, &failureUnstow); } @@ -8698,60 +8636,44 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler &masm) regs = availableGeneralRegs(2); scratch = regs.takeAny(); - if (obj_->is()) { - // Try to change the object's group. - Label noGroupChange; + // Changing object shape. Write the object's new shape. + Address shapeAddr(objReg, JSObject::offsetOfShape()); + EmitPreBarrier(masm, shapeAddr, MIRType_Shape); + masm.loadPtr(Address(BaselineStubReg, ICSetProp_NativeAdd::offsetOfNewShape()), scratch); + masm.storePtr(scratch, shapeAddr); - // Check if the cache has a new group to change to. - masm.loadPtr(Address(BaselineStubReg, ICSetProp_NativeAdd::offsetOfNewGroup()), scratch); - masm.branchTestPtr(Assembler::Zero, scratch, scratch, &noGroupChange); + // Try to change the object's group. + Label noGroupChange; - // Check if the old group still has a newScript. - masm.loadPtr(Address(objReg, JSObject::offsetOfGroup()), scratch); - masm.branchPtr(Assembler::Equal, - Address(scratch, ObjectGroup::offsetOfAddendum()), - ImmWord(0), - &noGroupChange); + // Check if the cache has a new group to change to. + masm.loadPtr(Address(BaselineStubReg, ICSetProp_NativeAdd::offsetOfNewGroup()), scratch); + masm.branchTestPtr(Assembler::Zero, scratch, scratch, &noGroupChange); - // Reload the new group from the cache. - masm.loadPtr(Address(BaselineStubReg, ICSetProp_NativeAdd::offsetOfNewGroup()), scratch); + // Check if the old group still has a newScript. + masm.loadPtr(Address(objReg, JSObject::offsetOfGroup()), scratch); + masm.branchPtr(Assembler::Equal, + Address(scratch, ObjectGroup::offsetOfAddendum()), + ImmWord(0), + &noGroupChange); - // Change the object's group. - Address groupAddr(objReg, JSObject::offsetOfGroup()); - EmitPreBarrier(masm, groupAddr, MIRType_ObjectGroup); - masm.storePtr(scratch, groupAddr); + // Reload the new group from the cache. + masm.loadPtr(Address(BaselineStubReg, ICSetProp_NativeAdd::offsetOfNewGroup()), scratch); - masm.bind(&noGroupChange); - } + // Change the object's group. + Address groupAddr(objReg, JSObject::offsetOfGroup()); + EmitPreBarrier(masm, groupAddr, MIRType_ObjectGroup); + masm.storePtr(scratch, groupAddr); + + masm.bind(&noGroupChange); Register holderReg; regs.add(R0); regs.takeUnchecked(objReg); - if (obj_->is()) { - holderReg = regs.takeAny(); - masm.loadPtr(Address(objReg, UnboxedPlainObject::offsetOfExpando()), holderReg); - - // Write the expando object's new shape. - Address shapeAddr(holderReg, JSObject::offsetOfShape()); - EmitPreBarrier(masm, shapeAddr, MIRType_Shape); - masm.loadPtr(Address(BaselineStubReg, ICSetProp_NativeAdd::offsetOfNewShape()), scratch); - masm.storePtr(scratch, shapeAddr); - - if (!isFixedSlot_) - masm.loadPtr(Address(holderReg, NativeObject::offsetOfSlots()), holderReg); + if (isFixedSlot_) { + holderReg = objReg; } else { - // Write the object's new shape. - Address shapeAddr(objReg, JSObject::offsetOfShape()); - EmitPreBarrier(masm, shapeAddr, MIRType_Shape); - masm.loadPtr(Address(BaselineStubReg, ICSetProp_NativeAdd::offsetOfNewShape()), scratch); - masm.storePtr(scratch, shapeAddr); - - if (isFixedSlot_) { - holderReg = objReg; - } else { - holderReg = regs.takeAny(); - masm.loadPtr(Address(objReg, NativeObject::offsetOfSlots()), holderReg); - } + holderReg = regs.takeAny(); + masm.loadPtr(Address(objReg, NativeObject::offsetOfSlots()), holderReg); } // Perform the store. No write barrier required since this is a new @@ -8764,7 +8686,7 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler &masm) if (cx->runtime()->gc.nursery.exists()) { Register scr = regs.takeAny(); - GeneralRegisterSet saveRegs; + LiveGeneralRegisterSet saveRegs; saveRegs.add(R1); emitPostWriteBarrierSlot(masm, objReg, R1, scr, saveRegs); } @@ -8773,12 +8695,6 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler &masm) masm.moveValue(R1, R0); EmitReturnFromIC(masm); - if (failurePopObject.used()) { - masm.bind(&failurePopObject); - masm.pop(objReg); - masm.jump(&failure); - } - // Failure case - jump to next stub masm.bind(&failureUnstow); EmitUnstowICValues(masm, 2); @@ -8796,7 +8712,7 @@ ICSetProp_Unboxed::Compiler::generateStubCode(MacroAssembler &masm) // Guard input is an object. masm.branchTestObject(Assembler::NotEqual, R0, &failure); - GeneralRegisterSet regs(availableGeneralRegs(2)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); Register scratch = regs.takeAny(); // Unbox and group guard. @@ -8825,7 +8741,7 @@ ICSetProp_Unboxed::Compiler::generateStubCode(MacroAssembler &masm) // Trigger post barriers here on the values being written. Fields which // objects can be written to also need update stubs. - GeneralRegisterSet saveRegs; + LiveGeneralRegisterSet saveRegs; saveRegs.add(R0); saveRegs.add(R1); saveRegs.addUnchecked(object); @@ -8867,7 +8783,7 @@ ICSetProp_TypedObject::Compiler::generateStubCode(MacroAssembler &masm) // Guard input is an object. masm.branchTestObject(Assembler::NotEqual, R0, &failure); - GeneralRegisterSet regs(availableGeneralRegs(2)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); Register scratch = regs.takeAny(); // Unbox and shape guard. @@ -8900,7 +8816,7 @@ ICSetProp_TypedObject::Compiler::generateStubCode(MacroAssembler &masm) // Trigger post barriers here on the values being written. Descriptors // which can write objects also need update stubs. - GeneralRegisterSet saveRegs; + LiveGeneralRegisterSet saveRegs; saveRegs.add(R0); saveRegs.add(R1); saveRegs.addUnchecked(object); @@ -8992,7 +8908,7 @@ ICSetProp_CallScripted::Compiler::generateStubCode(MacroAssembler &masm) // Stow R0 and R1 to free up registers. EmitStowICValues(masm, 2); - GeneralRegisterSet regs(availableGeneralRegs(1)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(1)); Register scratch = regs.takeAnyExcluding(BaselineTailCallReg); // Unbox and shape guard. @@ -9111,7 +9027,7 @@ ICSetProp_CallNative::Compiler::generateStubCode(MacroAssembler &masm) // Stow R0 and R1 to free up registers. EmitStowICValues(masm, 2); - GeneralRegisterSet regs(availableGeneralRegs(1)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(1)); Register scratch = regs.takeAnyExcluding(BaselineTailCallReg); // Unbox and shape guard. @@ -9830,7 +9746,7 @@ DoSpreadCallFallback(JSContext* cx, BaselineFrame* frame, ICCall_Fallback* stub_ } void -ICCallStubCompiler::pushCallArguments(MacroAssembler &masm, GeneralRegisterSet regs, +ICCallStubCompiler::pushCallArguments(MacroAssembler &masm, AllocatableGeneralRegisterSet regs, Register argcReg, bool isJitCall) { MOZ_ASSERT(!regs.has(argcReg)); @@ -9883,7 +9799,8 @@ ICCallStubCompiler::guardSpreadCall(MacroAssembler& masm, Register argcReg, Labe } void -ICCallStubCompiler::pushSpreadCallArguments(MacroAssembler &masm, GeneralRegisterSet regs, +ICCallStubCompiler::pushSpreadCallArguments(MacroAssembler &masm, + AllocatableGeneralRegisterSet regs, Register argcReg, bool isJitCall) { // Push arguments @@ -9919,9 +9836,15 @@ ICCallStubCompiler::pushSpreadCallArguments(MacroAssembler &masm, GeneralRegiste masm.pushValue(Address(BaselineFrameReg, STUB_FRAME_SIZE + 2 * sizeof(Value))); } +// (see Bug 1149377 comment 31) MSVC 2013 PGO miss-compiles branchTestObjClass +// calls from this function. +#if defined(_MSC_VER) && _MSC_VER == 1800 +# pragma optimize("g", off) +#endif Register -ICCallStubCompiler::guardFunApply(MacroAssembler &masm, GeneralRegisterSet regs, Register argcReg, - bool checkNative, FunApplyThing applyThing, Label *failure) +ICCallStubCompiler::guardFunApply(MacroAssembler &masm, AllocatableGeneralRegisterSet regs, + Register argcReg, bool checkNative, FunApplyThing applyThing, + Label *failure) { // Ensure argc == 2 masm.branch32(Assembler::NotEqual, argcReg, Imm32(2), failure); @@ -9948,7 +9871,7 @@ ICCallStubCompiler::guardFunApply(MacroAssembler &masm, GeneralRegisterSet regs, } else { MOZ_ASSERT(applyThing == FunApply_Array); - GeneralRegisterSet regsx = regs; + AllocatableGeneralRegisterSet regsx = regs; // Ensure that the second arg is an array. ValueOperand secondArgVal = regsx.takeAnyValue(); @@ -10038,9 +9961,12 @@ ICCallStubCompiler::guardFunApply(MacroAssembler &masm, GeneralRegisterSet regs, } return target; } +#if defined(_MSC_VER) && _MSC_VER == 1800 +# pragma optimize("", on) +#endif void -ICCallStubCompiler::pushCallerArguments(MacroAssembler &masm, GeneralRegisterSet regs) +ICCallStubCompiler::pushCallerArguments(MacroAssembler &masm, AllocatableGeneralRegisterSet regs) { // Initialize copyReg to point to start caller arguments vector. // Initialize argcReg to poitn to the end of it. @@ -10066,7 +9992,7 @@ ICCallStubCompiler::pushCallerArguments(MacroAssembler &masm, GeneralRegisterSet void ICCallStubCompiler::pushArrayArguments(MacroAssembler &masm, Address arrayVal, - GeneralRegisterSet regs) + AllocatableGeneralRegisterSet regs) { // Load start and end address of values to copy. // guardFunApply has already gauranteed that the array is packed and contains @@ -10112,7 +10038,7 @@ ICCall_Fallback::Compiler::generateStubCode(MacroAssembler &masm) // right-to-left so duplicate them on the stack in reverse order. // |this| and callee are pushed last. - GeneralRegisterSet regs(availableGeneralRegs(0)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(0)); if (MOZ_UNLIKELY(isSpread_)) { // Use BaselineFrameReg instead of BaselineStackReg, because @@ -10218,7 +10144,7 @@ bool ICCallScriptedCompiler::generateStubCode(MacroAssembler &masm) { Label failure; - GeneralRegisterSet regs(availableGeneralRegs(0)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(0)); bool canUseTailCallReg = regs.has(BaselineTailCallReg); Register argcReg = R0.scratchReg(); @@ -10483,7 +10409,7 @@ bool ICCall_StringSplit::Compiler::generateStubCode(MacroAssembler &masm) { // Stack Layout: [ ..., CalleeVal, ThisVal, Arg0Val, +ICStackValueOffset+ ] - GeneralRegisterSet regs = availableGeneralRegs(0); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(0)); Label failureRestoreArgc; #ifdef DEBUG Label oneArg; @@ -10577,7 +10503,7 @@ ICCall_IsSuspendedStarGenerator::Compiler::generateStubCode(MacroAssembler &masm // code, so it's safe to assume we have a single argument and the callee // is our intrinsic. - GeneralRegisterSet regs = availableGeneralRegs(0); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(0)); // Load the argument. Address argAddr(BaselineStackReg, ICStackValueOffset); @@ -10616,7 +10542,7 @@ bool ICCall_Native::Compiler::generateStubCode(MacroAssembler &masm) { Label failure; - GeneralRegisterSet regs(availableGeneralRegs(0)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(0)); Register argcReg = R0.scratchReg(); regs.take(argcReg); @@ -10720,7 +10646,7 @@ bool ICCall_ClassHook::Compiler::generateStubCode(MacroAssembler &masm) { Label failure; - GeneralRegisterSet regs(availableGeneralRegs(0)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(0)); Register argcReg = R0.scratchReg(); regs.take(argcReg); @@ -10807,7 +10733,7 @@ bool ICCall_ScriptedApplyArray::Compiler::generateStubCode(MacroAssembler &masm) { Label failure; - GeneralRegisterSet regs(availableGeneralRegs(0)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(0)); Register argcReg = R0.scratchReg(); regs.take(argcReg); @@ -10909,7 +10835,7 @@ bool ICCall_ScriptedApplyArguments::Compiler::generateStubCode(MacroAssembler &masm) { Label failure; - GeneralRegisterSet regs(availableGeneralRegs(0)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(0)); Register argcReg = R0.scratchReg(); regs.take(argcReg); @@ -11005,7 +10931,7 @@ bool ICCall_ScriptedFunCall::Compiler::generateStubCode(MacroAssembler& masm) { Label failure; - GeneralRegisterSet regs(availableGeneralRegs(0)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(0)); bool canUseTailCallReg = regs.has(BaselineTailCallReg); Register argcReg = R0.scratchReg(); @@ -11339,7 +11265,7 @@ ICIteratorMore_Native::Compiler::generateStubCode(MacroAssembler& masm) Register obj = masm.extractObject(R0, ExtractTemp0); - GeneralRegisterSet regs(availableGeneralRegs(1)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(1)); Register nativeIterator = regs.takeAny(); Register scratch = regs.takeAny(); @@ -11525,7 +11451,7 @@ ICInstanceOf_Function::Compiler::generateStubCode(MacroAssembler& masm) // Allow using R1's type register as scratch. We have to restore it when // we want to jump to the next stub. Label failureRestoreR1; - GeneralRegisterSet regs(availableGeneralRegs(1)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(1)); regs.takeUnchecked(rhsObj); Register scratch1 = regs.takeAny(); @@ -11719,7 +11645,7 @@ ICRetSub_Fallback::Compiler::generateStubCode(MacroAssembler& masm) masm.branchTestBooleanTruthy(true, R0, &rethrow); { // Call a stub to get the native code address for the pc offset in R1. - GeneralRegisterSet regs(availableGeneralRegs(0)); + AllocatableGeneralRegisterSet regs(availableGeneralRegs(0)); regs.take(R1); regs.takeUnchecked(BaselineTailCallReg); @@ -12086,30 +12012,35 @@ ICGetProp_CallNative::Clone(ICStubSpace *space, ICStub *firstMonitorStub, other.holderShape_, other.getter_, other.pcOffset_); } -ICSetProp_Native::ICSetProp_Native(JitCode *stubCode, ReceiverGuard::StackGuard guard, +ICSetProp_Native::ICSetProp_Native(JitCode *stubCode, ObjectGroup *group, Shape *shape, uint32_t offset) : ICUpdatedStub(SetProp_Native, stubCode), - receiverGuard_(guard), + group_(group), + shape_(shape), offset_(offset) { } ICSetProp_Native * ICSetProp_Native::Compiler::getStub(ICStubSpace *space) { - ReceiverGuard::StackGuard guard(obj_, true); - ICSetProp_Native *stub = ICStub::New(space, getStubCode(), guard, offset_); + RootedObjectGroup group(cx, obj_->getGroup(cx)); + if (!group) + return nullptr; + + RootedShape shape(cx, obj_->as().lastProperty()); + ICSetProp_Native *stub = ICStub::New(space, getStubCode(), group, shape, offset_); if (!stub || !stub->initUpdatingChain(cx, space)) return nullptr; return stub; } -ICSetProp_NativeAdd::ICSetProp_NativeAdd(JitCode *stubCode, ReceiverGuard::StackGuard guard, +ICSetProp_NativeAdd::ICSetProp_NativeAdd(JitCode *stubCode, ObjectGroup *group, size_t protoChainDepth, Shape *newShape, ObjectGroup *newGroup, uint32_t offset) : ICUpdatedStub(SetProp_NativeAdd, stubCode), - receiverGuard_(guard), + group_(group), newShape_(newShape), newGroup_(newGroup), offset_(offset) @@ -12120,26 +12051,28 @@ ICSetProp_NativeAdd::ICSetProp_NativeAdd(JitCode *stubCode, ReceiverGuard::Stack template ICSetProp_NativeAddImpl::ICSetProp_NativeAddImpl(JitCode *stubCode, - ReceiverGuard::StackGuard guard, + ObjectGroup *group, const AutoShapeVector *shapes, Shape *newShape, ObjectGroup *newGroup, uint32_t offset) - : ICSetProp_NativeAdd(stubCode, guard, ProtoChainDepth, newShape, newGroup, offset) + : ICSetProp_NativeAdd(stubCode, group, ProtoChainDepth, newShape, newGroup, offset) { MOZ_ASSERT(shapes->length() == NumShapes); - for (int i = 0; i < int(NumShapes); i++) // Use an int here to avoid compiler warnings. + for (size_t i = 0; i < NumShapes; i++) shapes_[i].init((*shapes)[i]); } ICSetPropNativeAddCompiler::ICSetPropNativeAddCompiler(JSContext *cx, HandleObject obj, - ReceiverGuard::StackGuard oldGuard, + HandleShape oldShape, + HandleObjectGroup oldGroup, size_t protoChainDepth, bool isFixedSlot, uint32_t offset) : ICStubCompiler(cx, ICStub::SetProp_NativeAdd), obj_(cx, obj), - oldGuard_(cx, oldGuard), + oldShape_(cx, oldShape), + oldGroup_(cx, oldGroup), protoChainDepth_(protoChainDepth), isFixedSlot_(isFixedSlot), offset_(offset) diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index 3c6f68fea8..079500729d 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -1127,8 +1127,8 @@ class ICStubCompiler // given label. void guardProfilingEnabled(MacroAssembler &masm, Register scratch, Label *skip); - inline GeneralRegisterSet availableGeneralRegs(size_t numInputs) const { - GeneralRegisterSet regs(GeneralRegisterSet::All()); + inline AllocatableGeneralRegisterSet availableGeneralRegs(size_t numInputs) const { + AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); MOZ_ASSERT(!regs.has(BaselineStackReg)); #if defined(JS_CODEGEN_ARM) MOZ_ASSERT(!regs.has(BaselineTailCallReg)); @@ -1162,7 +1162,7 @@ class ICStubCompiler } inline bool emitPostWriteBarrierSlot(MacroAssembler &masm, Register obj, ValueOperand val, - Register scratch, GeneralRegisterSet saveRegs); + Register scratch, LiveGeneralRegisterSet saveRegs); public: virtual ICStub *getStub(ICStubSpace *space) = 0; @@ -3881,15 +3881,12 @@ class ReceiverGuard : group(guard.group), shape(guard.shape) {} - explicit StackGuard(JSObject *obj, bool guardGroup = false) + explicit StackGuard(JSObject *obj) : group(nullptr), shape(nullptr) { if (obj) { shape = obj->maybeShape(); - if (shape) { - if (guardGroup) - group = obj->group(); - } else { + if (!shape) { group = obj->group(); if (UnboxedExpandoObject *expando = obj->as().maybeExpando()) shape = expando->lastProperty(); @@ -4763,14 +4760,18 @@ class ICSetProp_Native : public ICUpdatedStub friend class ICStubSpace; protected: // Protected to silence Clang warning. - ReceiverGuard receiverGuard_; + HeapPtrObjectGroup group_; + HeapPtrShape shape_; uint32_t offset_; - ICSetProp_Native(JitCode *stubCode, ReceiverGuard::StackGuard guard, uint32_t offset); + ICSetProp_Native(JitCode *stubCode, ObjectGroup *group, Shape *shape, uint32_t offset); public: - ReceiverGuard &receiverGuard() { - return receiverGuard_; + HeapPtrObjectGroup &group() { + return group_; + } + HeapPtrShape &shape() { + return shape_; } void notePreliminaryObject() { extra_ = 1; @@ -4778,8 +4779,11 @@ class ICSetProp_Native : public ICUpdatedStub bool hasPreliminaryObject() const { return extra_; } - static size_t offsetOfReceiverGuard() { - return offsetof(ICSetProp_Native, receiverGuard_); + static size_t offsetOfGroup() { + return offsetof(ICSetProp_Native, group_); + } + static size_t offsetOfShape() { + return offsetof(ICSetProp_Native, shape_); } static size_t offsetOfOffset() { return offsetof(ICSetProp_Native, offset_); @@ -4792,9 +4796,7 @@ class ICSetProp_Native : public ICUpdatedStub protected: virtual int32_t getKey() const { - return static_cast(kind) | - (static_cast(isFixedSlot_) << 16) | - (ReceiverGuard::keyBits(obj_) << 17); + return static_cast(kind) | (static_cast(isFixedSlot_) << 16); } bool generateStubCode(MacroAssembler &masm); @@ -4820,20 +4822,20 @@ class ICSetProp_NativeAdd : public ICUpdatedStub static const size_t MAX_PROTO_CHAIN_DEPTH = 4; protected: // Protected to silence Clang warning. - ReceiverGuard receiverGuard_; + HeapPtrObjectGroup group_; HeapPtrShape newShape_; HeapPtrObjectGroup newGroup_; uint32_t offset_; - ICSetProp_NativeAdd(JitCode *stubCode, ReceiverGuard::StackGuard guard, size_t protoChainDepth, + ICSetProp_NativeAdd(JitCode *stubCode, ObjectGroup *group, size_t protoChainDepth, Shape *newShape, ObjectGroup *newGroup, uint32_t offset); public: size_t protoChainDepth() const { return extra_; } - ReceiverGuard &receiverGuard() { - return receiverGuard_; + HeapPtrObjectGroup &group() { + return group_; } HeapPtrShape &newShape() { return newShape_; @@ -4848,8 +4850,8 @@ class ICSetProp_NativeAdd : public ICUpdatedStub return static_cast *>(this); } - static size_t offsetOfReceiverGuard() { - return offsetof(ICSetProp_NativeAdd, receiverGuard_); + static size_t offsetOfGroup() { + return offsetof(ICSetProp_NativeAdd, group_); } static size_t offsetOfNewShape() { return offsetof(ICSetProp_NativeAdd, newShape_); @@ -4867,23 +4869,20 @@ class ICSetProp_NativeAddImpl : public ICSetProp_NativeAdd { friend class ICStubSpace; - static const size_t NumShapes = ProtoChainDepth; + static const size_t NumShapes = ProtoChainDepth + 1; mozilla::Array shapes_; - ICSetProp_NativeAddImpl(JitCode *stubCode, ReceiverGuard::StackGuard guard, + ICSetProp_NativeAddImpl(JitCode *stubCode, ObjectGroup *group, const AutoShapeVector *shapes, Shape *newShape, ObjectGroup *newGroup, uint32_t offset); public: void traceShapes(JSTracer *trc) { - // Note: using int32_t here to avoid gcc warning. - for (int32_t i = 0; i < int32_t(NumShapes); i++) + for (size_t i = 0; i < NumShapes; i++) MarkShape(trc, &shapes_[i], "baseline-setpropnativeadd-stub-shape"); } static size_t offsetOfShape(size_t idx) { - // The shape array might be aligned differently if its length is zero. - JS_STATIC_ASSERT(NumShapes != 0); return offsetof(ICSetProp_NativeAddImpl, shapes_) + (idx * sizeof(HeapPtrShape)); } }; @@ -4891,24 +4890,23 @@ class ICSetProp_NativeAddImpl : public ICSetProp_NativeAdd class ICSetPropNativeAddCompiler : public ICStubCompiler { RootedObject obj_; - ReceiverGuard::RootedStackGuard oldGuard_; + RootedShape oldShape_; + RootedObjectGroup oldGroup_; size_t protoChainDepth_; bool isFixedSlot_; uint32_t offset_; protected: virtual int32_t getKey() const { - return static_cast(kind) | - (static_cast(isFixedSlot_) << 16) | - (static_cast(ReceiverGuard::keyBits(obj_)) << 17) | - (static_cast(protoChainDepth_) << 19); + return static_cast(kind) | (static_cast(isFixedSlot_) << 16) | + (static_cast(protoChainDepth_) << 20); } bool generateStubCode(MacroAssembler &masm); public: ICSetPropNativeAddCompiler(JSContext *cx, HandleObject obj, - ReceiverGuard::StackGuard oldGuard, + HandleShape oldShape, HandleObjectGroup oldGroup, size_t protoChainDepth, bool isFixedSlot, uint32_t offset); template @@ -4921,17 +4919,13 @@ class ICSetPropNativeAddCompiler : public ICStubCompiler // Only specify newGroup when the object's group changes due to the // object becoming fully initialized per the acquired properties // analysis. - if (newGroup == oldGuard_.group) + if (newGroup == oldGroup_) newGroup = nullptr; - RootedShape newShape(cx); - if (obj_->is()) - newShape = obj_->as().maybeExpando()->lastProperty(); - else - newShape = obj_->as().lastProperty(); + RootedShape newShape(cx, obj_->as().lastProperty()); return ICStub::New>( - space, getStubCode(), oldGuard_, shapes, newShape, newGroup, offset_); + space, getStubCode(), oldGroup_, shapes, newShape, newGroup, offset_); } ICUpdatedStub *getStub(ICStubSpace *space); @@ -5259,15 +5253,17 @@ class ICCallStubCompiler : public ICStubCompiler FunApply_Array }; - void pushCallArguments(MacroAssembler &masm, GeneralRegisterSet regs, Register argcReg, - bool isJitCall); - void pushSpreadCallArguments(MacroAssembler &masm, GeneralRegisterSet regs, Register argcReg, - bool isJitCall); + void pushCallArguments(MacroAssembler &masm, AllocatableGeneralRegisterSet regs, + Register argcReg, bool isJitCall); + void pushSpreadCallArguments(MacroAssembler &masm, AllocatableGeneralRegisterSet regs, + Register argcReg, bool isJitCall); void guardSpreadCall(MacroAssembler &masm, Register argcReg, Label *failure); - Register guardFunApply(MacroAssembler &masm, GeneralRegisterSet regs, Register argcReg, - bool checkNative, FunApplyThing applyThing, Label *failure); - void pushCallerArguments(MacroAssembler &masm, GeneralRegisterSet regs); - void pushArrayArguments(MacroAssembler &masm, Address arrayVal, GeneralRegisterSet regs); + Register guardFunApply(MacroAssembler &masm, AllocatableGeneralRegisterSet regs, + Register argcReg, bool checkNative, FunApplyThing applyThing, + Label *failure); + void pushCallerArguments(MacroAssembler &masm, AllocatableGeneralRegisterSet regs); + void pushArrayArguments(MacroAssembler &masm, Address arrayVal, + AllocatableGeneralRegisterSet regs); }; class ICCall_Fallback : public ICMonitoredFallbackStub diff --git a/js/src/jit/BaselineInspector.cpp b/js/src/jit/BaselineInspector.cpp index 2d71c7f8c3..3f78f10080 100644 --- a/js/src/jit/BaselineInspector.cpp +++ b/js/src/jit/BaselineInspector.cpp @@ -118,7 +118,7 @@ BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, if (stub->isGetProp_Native()) { shape = stub->toGetProp_Native()->receiverGuard().ownShape(); } else if (stub->isSetProp_Native()) { - shape = stub->toSetProp_Native()->receiverGuard().ownShape(); + shape = stub->toSetProp_Native()->shape(); } else if (stub->isGetProp_Unboxed()) { group = stub->toGetProp_Unboxed()->group(); } else if (stub->isSetProp_Unboxed()) { diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index b2698cc6b7..a3156ef8d6 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -1125,7 +1125,7 @@ PrepareAndExecuteRegExp(JSContext* cx, MacroAssembler& masm, Register regexp, Re masm.store32(Imm32(0), matchResultAddress); // Save any volatile inputs. - GeneralRegisterSet volatileRegs; + LiveGeneralRegisterSet volatileRegs; if (input.volatile_()) volatileRegs.add(input); if (regexp.volatile_()) @@ -1300,7 +1300,7 @@ JitCompartment::generateRegExpExecStub(JSContext* cx) ValueOperand result = JSReturnOperand; // We are free to clobber all registers, as LRegExpExec is a call instruction. - GeneralRegisterSet regs = GeneralRegisterSet::All(); + AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); regs.take(input); regs.take(regexp); @@ -1309,7 +1309,7 @@ JitCompartment::generateRegExpExecStub(JSContext* cx) // platforms. Register temp5; { - GeneralRegisterSet oregs = regs; + AllocatableGeneralRegisterSet oregs = regs; do { temp5 = oregs.takeAny(); } while (!MacroAssembler::canUseInSingleByteInstruction(temp5)); @@ -1468,7 +1468,7 @@ CodeGenerator::visitOutOfLineRegExpExec(OutOfLineRegExpExec* ool) Register input = ToRegister(lir->string()); Register regexp = ToRegister(lir->regexp()); - GeneralRegisterSet regs = GeneralRegisterSet::All(); + AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); regs.take(input); regs.take(regexp); Register temp = regs.takeAny(); @@ -1517,7 +1517,7 @@ JitCompartment::generateRegExpTestStub(JSContext* cx) MOZ_ASSERT(regexp != result && input != result); // We are free to clobber all registers, as LRegExpTest is a call instruction. - GeneralRegisterSet regs = GeneralRegisterSet::All(); + AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); regs.take(input); regs.take(regexp); Register temp1 = regs.takeAny(); @@ -2649,7 +2649,7 @@ CodeGenerator::visitOutOfLineCallPostWriteBarrier(OutOfLineCallPostWriteBarrier* const LAllocation* obj = ool->object(); - GeneralRegisterSet regs = GeneralRegisterSet::Volatile(); + AllocatableGeneralRegisterSet regs(GeneralRegisterSet::Volatile()); Register objreg; bool isGlobal = false; @@ -3718,7 +3718,7 @@ CodeGenerator::emitAssertObjectOrStringResult(Register input, MIRType type, Temp MOZ_ASSERT(type == MIRType_Object || type == MIRType_ObjectOrNull || type == MIRType_String || type == MIRType_Symbol); - GeneralRegisterSet regs(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); regs.take(input); Register temp = regs.takeAny(); @@ -3785,7 +3785,7 @@ CodeGenerator::emitAssertObjectOrStringResult(Register input, MIRType type, Temp void CodeGenerator::emitAssertResultV(const ValueOperand input, TemporaryTypeSet *typeset) { - GeneralRegisterSet regs(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); regs.take(input); Register temp1 = regs.takeAny(); @@ -6044,16 +6044,16 @@ JitRuntime::generateMallocStub(JSContext* cx) MacroAssembler masm(cx); - RegisterSet regs = RegisterSet::Volatile(); + AllocatableRegisterSet regs(RegisterSet::Volatile()); #ifdef JS_USE_LINK_REGISTER masm.pushReturnAddress(); #endif regs.takeUnchecked(regNBytes); - masm.PushRegsInMask(regs); + LiveRegisterSet save(regs.asLiveSet()); + masm.PushRegsInMask(save); - const Register regTemp = regs.takeGeneral(); + const Register regTemp = regs.takeAnyGeneral(); const Register regRuntime = regTemp; - regs.add(regTemp); MOZ_ASSERT(regTemp != regNBytes); masm.setupUnalignedABICall(2, regTemp); @@ -6063,7 +6063,7 @@ JitRuntime::generateMallocStub(JSContext* cx) masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, MallocWrapper)); masm.storeCallResult(regReturn); - masm.PopRegsInMask(regs); + masm.PopRegsInMask(save); masm.ret(); Linker linker(masm); @@ -6086,19 +6086,19 @@ JitRuntime::generateFreeStub(JSContext* cx) #ifdef JS_USE_LINK_REGISTER masm.pushReturnAddress(); #endif - RegisterSet regs = RegisterSet::Volatile(); + AllocatableRegisterSet regs(RegisterSet::Volatile()); regs.takeUnchecked(regSlots); - masm.PushRegsInMask(regs); + LiveRegisterSet save(regs.asLiveSet()); + masm.PushRegsInMask(save); - const Register regTemp = regs.takeGeneral(); - regs.add(regTemp); + const Register regTemp = regs.takeAnyGeneral(); MOZ_ASSERT(regTemp != regSlots); masm.setupUnalignedABICall(1, regTemp); masm.passABIArg(regSlots); masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js_free)); - masm.PopRegsInMask(regs); + masm.PopRegsInMask(save); masm.ret(); @@ -6122,7 +6122,7 @@ JitRuntime::generateLazyLinkStub(JSContext* cx) masm.pushReturnAddress(); #endif - GeneralRegisterSet regs = GeneralRegisterSet::Volatile(); + AllocatableGeneralRegisterSet regs(GeneralRegisterSet::Volatile()); Register temp0 = regs.takeAny(); // The caller did not push an exit frame on the stack, it pushed a @@ -6770,7 +6770,7 @@ CodeGenerator::emitArrayPopShift(LInstruction* lir, const MArrayPopShift* mir, R if (mir->mode() == MArrayPopShift::Shift) { // Don't save the temp registers. - RegisterSet temps; + LiveRegisterSet temps; temps.add(elementsTemp); temps.add(lengthTemp); @@ -7849,7 +7849,7 @@ CodeGenerator::visitStoreFixedSlotT(LStoreFixedSlotT* ins) void CodeGenerator::visitGetNameCache(LGetNameCache *ins) { - RegisterSet liveRegs = ins->safepoint()->liveRegs(); + LiveRegisterSet liveRegs = ins->safepoint()->liveRegs(); Register scopeChain = ToRegister(ins->scopeObj()); TypedOrValueRegister output(GetValueOutput(ins)); bool isTypeOf = ins->mir()->accessKind() != MGetNameCache::NAME; @@ -7879,7 +7879,7 @@ CodeGenerator::visitNameIC(OutOfLineUpdateCache* ool, DataPtr& ic) } void -CodeGenerator::addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg, +CodeGenerator::addGetPropertyCache(LInstruction *ins, LiveRegisterSet liveRegs, Register objReg, PropertyName *name, TypedOrValueRegister output, bool monitoredResult, jsbytecode *profilerLeavePc) { @@ -7889,7 +7889,7 @@ CodeGenerator::addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Regi } void -CodeGenerator::addSetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg, +CodeGenerator::addSetPropertyCache(LInstruction *ins, LiveRegisterSet liveRegs, Register objReg, PropertyName *name, ConstantOrRegister value, bool strict, bool needsTypeBarrier, jsbytecode *profilerLeavePc) { @@ -7914,7 +7914,7 @@ CodeGenerator::addSetElementCache(LInstruction* ins, Register obj, Register unbo void CodeGenerator::visitGetPropertyCacheV(LGetPropertyCacheV *ins) { - RegisterSet liveRegs = ins->safepoint()->liveRegs(); + LiveRegisterSet liveRegs = ins->safepoint()->liveRegs(); Register objReg = ToRegister(ins->getOperand(0)); PropertyName* name = ins->mir()->name(); bool monitoredResult = ins->mir()->monitoredResult(); @@ -7927,7 +7927,7 @@ CodeGenerator::visitGetPropertyCacheV(LGetPropertyCacheV *ins) void CodeGenerator::visitGetPropertyCacheT(LGetPropertyCacheT *ins) { - RegisterSet liveRegs = ins->safepoint()->liveRegs(); + LiveRegisterSet liveRegs = ins->safepoint()->liveRegs(); Register objReg = ToRegister(ins->getOperand(0)); PropertyName* name = ins->mir()->name(); bool monitoredResult = ins->mir()->monitoredResult(); @@ -7972,7 +7972,7 @@ CodeGenerator::addGetElementCache(LInstruction* ins, Register obj, ConstantOrReg TypedOrValueRegister output, bool monitoredResult, bool allowDoubleResult, jsbytecode* profilerLeavePc) { - RegisterSet liveRegs = ins->safepoint()->liveRegs(); + LiveRegisterSet liveRegs = ins->safepoint()->liveRegs(); GetElementIC cache(liveRegs, obj, index, output, monitoredResult, allowDoubleResult); cache.setProfilerLeavePC(profilerLeavePc); addCache(ins, allocateCache(cache)); @@ -8171,7 +8171,7 @@ CodeGenerator::visitCallDeleteElement(LCallDeleteElement* lir) void CodeGenerator::visitSetPropertyCacheV(LSetPropertyCacheV *ins) { - RegisterSet liveRegs = ins->safepoint()->liveRegs(); + LiveRegisterSet liveRegs = ins->safepoint()->liveRegs(); Register objReg = ToRegister(ins->getOperand(0)); ConstantOrRegister value = TypedOrValueRegister(ToValue(ins, LSetPropertyCacheV::Value)); @@ -8183,7 +8183,7 @@ CodeGenerator::visitSetPropertyCacheV(LSetPropertyCacheV *ins) void CodeGenerator::visitSetPropertyCacheT(LSetPropertyCacheT *ins) { - RegisterSet liveRegs = ins->safepoint()->liveRegs(); + LiveRegisterSet liveRegs = ins->safepoint()->liveRegs(); Register objReg = ToRegister(ins->getOperand(0)); ConstantOrRegister value; diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index b8ca33923c..e8b049f83b 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -370,13 +370,13 @@ class CodeGenerator : public CodeGeneratorSpecific } private: - void addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg, + void addGetPropertyCache(LInstruction *ins, LiveRegisterSet liveRegs, Register objReg, PropertyName *name, TypedOrValueRegister output, bool monitoredResult, jsbytecode *profilerLeavePc); void addGetElementCache(LInstruction *ins, Register obj, ConstantOrRegister index, TypedOrValueRegister output, bool monitoredResult, bool allowDoubleResult, jsbytecode *profilerLeavePc); - void addSetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg, + void addSetPropertyCache(LInstruction *ins, LiveRegisterSet liveRegs, Register objReg, PropertyName *name, ConstantOrRegister value, bool strict, bool needsTypeBarrier, jsbytecode* profilerLeavePc); void addSetElementCache(LInstruction *ins, Register obj, Register unboxIndex, Register temp, @@ -491,8 +491,8 @@ class CodeGenerator : public CodeGeneratorSpecific // Barriered objects in a bit mask. uint32_t simdRefreshTemplatesDuringLink_; - void registerSimdTemplate(InlineTypedObject *templateObject); - void captureSimdTemplate(JSContext *cx); + void registerSimdTemplate(InlineTypedObject* templateObject); + void captureSimdTemplate(JSContext* cx); }; } // namespace jit diff --git a/js/src/jit/EagerSimdUnbox.cpp b/js/src/jit/EagerSimdUnbox.cpp index beaf54b761..14094682d3 100644 --- a/js/src/jit/EagerSimdUnbox.cpp +++ b/js/src/jit/EagerSimdUnbox.cpp @@ -28,7 +28,7 @@ MIRTypeToSimdTypeDescr(MIRType type) // Do not optimize any Phi instruction which has conflicting Unbox operations, // as this might imply some intended polymorphism. static bool -CanUnboxSimdPhi(const JitCompartment *jitCompartment, MPhi *phi, MIRType unboxType) +CanUnboxSimdPhi(const JitCompartment* jitCompartment, MPhi* phi, MIRType unboxType) { MOZ_ASSERT(phi->type() == MIRType_Object); @@ -38,7 +38,7 @@ CanUnboxSimdPhi(const JitCompartment *jitCompartment, MPhi *phi, MIRType unboxTy if (!jitCompartment->maybeGetSimdTemplateObjectFor(MIRTypeToSimdTypeDescr(unboxType))) return false; - MResumePoint *entry = phi->block()->entryResumePoint(); + MResumePoint* entry = phi->block()->entryResumePoint(); for (MUseIterator i(phi->usesBegin()), e(phi->usesEnd()); i != e; i++) { // If we cannot recover the Simd object at the entry of the basic block, // then we would have to box the content anyways. @@ -48,7 +48,7 @@ CanUnboxSimdPhi(const JitCompartment *jitCompartment, MPhi *phi, MIRType unboxTy if (!(*i)->consumer()->isDefinition()) continue; - MDefinition *def = (*i)->consumer()->toDefinition(); + MDefinition* def = (*i)->consumer()->toDefinition(); if (def->isSimdUnbox() && def->toSimdUnbox()->type() != unboxType) return false; } @@ -57,14 +57,14 @@ CanUnboxSimdPhi(const JitCompartment *jitCompartment, MPhi *phi, MIRType unboxTy } static void -UnboxSimdPhi(const JitCompartment *jitCompartment, MIRGraph &graph, MPhi *phi, MIRType unboxType) +UnboxSimdPhi(const JitCompartment* jitCompartment, MIRGraph& graph, MPhi* phi, MIRType unboxType) { - TempAllocator &alloc = graph.alloc(); + TempAllocator& alloc = graph.alloc(); // Unbox and replace all operands. for (size_t i = 0, e = phi->numOperands(); i < e; i++) { - MDefinition *op = phi->getOperand(i); - MSimdUnbox *unbox = MSimdUnbox::New(alloc, op, unboxType); + MDefinition* op = phi->getOperand(i); + MSimdUnbox* unbox = MSimdUnbox::New(alloc, op, unboxType); op->block()->insertAtEnd(unbox); phi->replaceOperand(i, unbox); } @@ -72,25 +72,25 @@ UnboxSimdPhi(const JitCompartment *jitCompartment, MIRGraph &graph, MPhi *phi, M // Change the MIRType of the Phi. phi->setResultType(unboxType); - MBasicBlock *phiBlock = phi->block(); - MInstruction *atRecover = phiBlock->safeInsertTop(nullptr, MBasicBlock::IgnoreRecover); - MInstruction *at = phiBlock->safeInsertTop(atRecover); + MBasicBlock* phiBlock = phi->block(); + MInstruction* atRecover = phiBlock->safeInsertTop(nullptr, MBasicBlock::IgnoreRecover); + MInstruction* at = phiBlock->safeInsertTop(atRecover); // Note, we capture the uses-list now, as new instructions are not visited. MUseIterator i(phi->usesBegin()), e(phi->usesEnd()); // Add a MSimdBox, and replace all the Phi uses with it. - JSObject *templateObject = + JSObject* templateObject = jitCompartment->maybeGetSimdTemplateObjectFor(MIRTypeToSimdTypeDescr(unboxType)); - InlineTypedObject *inlineTypedObject = &templateObject->as(); - MSimdBox *recoverBox = MSimdBox::New(alloc, nullptr, phi, inlineTypedObject, gc::DefaultHeap); + InlineTypedObject* inlineTypedObject = &templateObject->as(); + MSimdBox* recoverBox = MSimdBox::New(alloc, nullptr, phi, inlineTypedObject, gc::DefaultHeap); recoverBox->setRecoveredOnBailout(); phiBlock->insertBefore(atRecover, recoverBox); - MSimdBox *box = nullptr; + MSimdBox* box = nullptr; while (i != e) { - MUse *use = *i++; - MNode *ins = use->consumer(); + MUse* use = *i++; + MNode* ins = use->consumer(); if ((ins->isDefinition() && ins->toDefinition()->isRecoveredOnBailout()) || (ins->isResumePoint() && ins->toResumePoint()->isRecoverableOperand(use))) @@ -109,9 +109,9 @@ UnboxSimdPhi(const JitCompartment *jitCompartment, MIRGraph &graph, MPhi *phi, M } bool -EagerSimdUnbox(MIRGenerator *mir, MIRGraph &graph) +EagerSimdUnbox(MIRGenerator* mir, MIRGraph& graph) { - const JitCompartment *jitCompartment = GetJitContext()->compartment->jitCompartment(); + const JitCompartment* jitCompartment = GetJitContext()->compartment->jitCompartment(); for (PostorderIterator block = graph.poBegin(); block != graph.poEnd(); block++) { if (mir->shouldCancel("Eager Simd Unbox")) return false; @@ -120,11 +120,11 @@ EagerSimdUnbox(MIRGenerator *mir, MIRGraph &graph) if (!ins->isSimdUnbox()) continue; - MSimdUnbox *unbox = ins->toSimdUnbox(); + MSimdUnbox* unbox = ins->toSimdUnbox(); if (!unbox->input()->isPhi()) continue; - MPhi *phi = unbox->input()->toPhi(); + MPhi* phi = unbox->input()->toPhi(); if (!CanUnboxSimdPhi(jitCompartment, phi, unbox->type())) continue; diff --git a/js/src/jit/EagerSimdUnbox.h b/js/src/jit/EagerSimdUnbox.h index 2ccb4eb47e..2adc60d877 100644 --- a/js/src/jit/EagerSimdUnbox.h +++ b/js/src/jit/EagerSimdUnbox.h @@ -15,7 +15,7 @@ class MIRGenerator; class MIRGraph; bool -EagerSimdUnbox(MIRGenerator *mir, MIRGraph &graph); +EagerSimdUnbox(MIRGenerator* mir, MIRGraph& graph); } // namespace jit } // namespace js diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index 899c99a4a5..78ab87af88 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -764,9 +764,9 @@ CheckDOMProxyExpandoDoesNotShadow(JSContext* cx, MacroAssembler& masm, JSObject* // For the remaining code, we need to reserve some registers to load a value. // This is ugly, but unvaoidable. - RegisterSet domProxyRegSet(RegisterSet::All()); + AllocatableRegisterSet domProxyRegSet(RegisterSet::All()); domProxyRegSet.take(AnyRegister(object)); - ValueOperand tempVal = domProxyRegSet.takeValueOperand(); + ValueOperand tempVal = domProxyRegSet.takeAnyValue(); masm.pushValue(tempVal); Label failDOMProxyCheck; @@ -963,7 +963,7 @@ static bool EmitGetterCall(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher, JSObject *obj, JSObject *holder, HandleShape shape, - RegisterSet liveRegs, Register object, + LiveRegisterSet liveRegs, Register object, TypedOrValueRegister output, void *returnAddr) { @@ -972,20 +972,20 @@ EmitGetterCall(JSContext *cx, MacroAssembler &masm, // Remaining registers should basically be free, but we need to use |object| still // so leave it alone. - RegisterSet regSet(RegisterSet::All()); + AllocatableRegisterSet regSet(RegisterSet::All()); regSet.take(AnyRegister(object)); // This is a slower stub path, and we're going to be doing a call anyway. Don't need // to try so hard to not use the stack. Scratch regs are just taken from the register // set not including the input, current value saved on the stack, and restored when // we're done with it. - Register scratchReg = regSet.takeGeneral(); + Register scratchReg = regSet.takeAnyGeneral(); // Shape has a JSNative, PropertyOp or scripted getter function. if (IsCacheableGetPropCallNative(obj, holder, shape)) { - Register argJSContextReg = regSet.takeGeneral(); - Register argUintNReg = regSet.takeGeneral(); - Register argVpReg = regSet.takeGeneral(); + Register argJSContextReg = regSet.takeAnyGeneral(); + Register argUintNReg = regSet.takeAnyGeneral(); + Register argVpReg = regSet.takeAnyGeneral(); JSFunction *target = &shape->getterValue().toObject().as(); MOZ_ASSERT(target); @@ -1032,11 +1032,11 @@ EmitGetterCall(JSContext *cx, MacroAssembler &masm, // masm.leaveExitFrame & pop locals masm.adjustStack(IonOOLNativeExitFrameLayout::Size(0)); } else if (IsCacheableGetPropCallPropertyOp(obj, holder, shape)) { - Register argJSContextReg = regSet.takeGeneral(); - Register argUintNReg = regSet.takeGeneral(); - Register argVpReg = regSet.takeGeneral(); + Register argJSContextReg = regSet.takeAnyGeneral(); + Register argUintNReg = regSet.takeAnyGeneral(); + Register argVpReg = regSet.takeAnyGeneral(); Register argObjReg = argUintNReg; - Register argIdReg = regSet.takeGeneral(); + Register argIdReg = regSet.takeAnyGeneral(); GetterOp target = shape->getterOp(); MOZ_ASSERT(target); @@ -1134,7 +1134,7 @@ EmitGetterCall(JSContext *cx, MacroAssembler &masm, static bool GenerateCallGetter(JSContext *cx, IonScript *ion, MacroAssembler &masm, IonCache::StubAttacher &attacher, JSObject *obj, PropertyName *name, - JSObject *holder, HandleShape shape, RegisterSet &liveRegs, Register object, + JSObject *holder, HandleShape shape, LiveRegisterSet &liveRegs, Register object, TypedOrValueRegister output, void *returnAddr, Label *failures = nullptr) { MOZ_ASSERT(output.hasValue()); @@ -1526,7 +1526,7 @@ PushObjectOpResult(MacroAssembler &masm) static bool EmitCallProxyGet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher, - PropertyName *name, RegisterSet liveRegs, Register object, + PropertyName *name, LiveRegisterSet liveRegs, Register object, TypedOrValueRegister output, jsbytecode *pc, void *returnAddr) { MOZ_ASSERT(output.hasValue()); @@ -1534,17 +1534,17 @@ EmitCallProxyGet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at // Remaining registers should be free, but we need to use |object| still // so leave it alone. - RegisterSet regSet(RegisterSet::All()); + AllocatableRegisterSet regSet(RegisterSet::All()); regSet.take(AnyRegister(object)); // Proxy::get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, // MutableHandleValue vp) - Register argJSContextReg = regSet.takeGeneral(); - Register argProxyReg = regSet.takeGeneral(); - Register argIdReg = regSet.takeGeneral(); - Register argVpReg = regSet.takeGeneral(); + Register argJSContextReg = regSet.takeAnyGeneral(); + Register argProxyReg = regSet.takeAnyGeneral(); + Register argIdReg = regSet.takeAnyGeneral(); + Register argVpReg = regSet.takeAnyGeneral(); - Register scratch = regSet.takeGeneral(); + Register scratch = regSet.takeAnyGeneral(); void *getFunction = JSOp(*pc) == JSOP_CALLPROP ? JS_FUNC_TO_DATA_PTR(void *, Proxy::callProp) : @@ -2232,17 +2232,17 @@ EmitObjectOpResultCheck(MacroAssembler &masm, Label *failure, bool strict, } static bool -ProxySetProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHandleValue vp, - bool strict) +ProxySetProperty(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, bool strict) { + RootedValue receiver(cx, ObjectValue(*proxy)); ObjectOpResult result; - return Proxy::set(cx, proxy, proxy, id, vp, result) + return Proxy::set(cx, proxy, id, v, receiver, result) && result.checkStrictErrorOrWarning(cx, proxy, id, strict); } static bool EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher, - HandleId propId, RegisterSet liveRegs, Register object, + HandleId propId, LiveRegisterSet liveRegs, Register object, ConstantOrRegister value, void *returnAddr, bool strict) { MacroAssembler::AfterICSaveLive aic = masm.icSaveLive(liveRegs); @@ -2254,18 +2254,18 @@ EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at // regSet is going to re-allocate it. Hence the emitted code must not touch // any of the registers allocated from regSet until after the last use of // |value|. (We can't afford to take it, either, because x86.) - RegisterSet regSet(RegisterSet::All()); + AllocatableRegisterSet regSet(RegisterSet::All()); regSet.take(AnyRegister(object)); - // ProxySetProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHandleValue vp, + // ProxySetProperty(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, // bool strict); - Register argJSContextReg = regSet.takeGeneral(); - Register argProxyReg = regSet.takeGeneral(); - Register argIdReg = regSet.takeGeneral(); - Register argVpReg = regSet.takeGeneral(); - Register argStrictReg = regSet.takeGeneral(); + Register argJSContextReg = regSet.takeAnyGeneral(); + Register argProxyReg = regSet.takeAnyGeneral(); + Register argIdReg = regSet.takeAnyGeneral(); + Register argValueReg = regSet.takeAnyGeneral(); + Register argStrictReg = regSet.takeAnyGeneral(); - Register scratch = regSet.takeGeneral(); + Register scratch = regSet.takeAnyGeneral(); // Push stubCode for marking. attacher.pushStubCodePointer(masm); @@ -2273,7 +2273,7 @@ EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at // Push args on stack so we can take pointers to make handles. // Push value before touching any other registers (see WARNING above). masm.Push(value); - masm.movePtr(StackPointer, argVpReg); + masm.movePtr(StackPointer, argValueReg); masm.move32(Imm32(strict), argStrictReg); @@ -2297,7 +2297,7 @@ EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at masm.passABIArg(argJSContextReg); masm.passABIArg(argProxyReg); masm.passABIArg(argIdReg); - masm.passABIArg(argVpReg); + masm.passABIArg(argValueReg); masm.passABIArg(argStrictReg); masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ProxySetProperty)); @@ -2325,12 +2325,12 @@ SetPropertyIC::attachGenericProxy(JSContext* cx, HandleScript outerScript, IonSc Label proxyFailures; Label proxySuccess; - RegisterSet regSet(RegisterSet::All()); + AllocatableRegisterSet regSet(RegisterSet::All()); regSet.take(AnyRegister(object())); if (!value().constant()) regSet.takeUnchecked(value().reg()); - Register scratch = regSet.takeGeneral(); + Register scratch = regSet.takeAnyGeneral(); masm.push(scratch); masm.branchTestObjectIsProxy(false, object(), scratch, &proxyFailures); @@ -2407,17 +2407,17 @@ static bool GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler& masm, IonCache::StubAttacher &attacher, HandleObject obj, HandleObject holder, HandleShape shape, bool strict, Register object, - ConstantOrRegister value, Label *failure, RegisterSet liveRegs, + ConstantOrRegister value, Label *failure, LiveRegisterSet liveRegs, void *returnAddr) { // Generate prototype guards if needed. // Take a scratch register for use, save on stack. { - RegisterSet regSet(RegisterSet::All()); + AllocatableRegisterSet regSet(RegisterSet::All()); regSet.take(AnyRegister(object)); if (!value.constant()) regSet.takeUnchecked(value.reg()); - Register scratchReg = regSet.takeGeneral(); + Register scratchReg = regSet.takeAnyGeneral(); masm.push(scratchReg); Label protoFailure; @@ -2449,7 +2449,7 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler& masm, // Remaining registers should basically be free, but we need to use |object| still // so leave it alone. And of course we need our value, if it's not a constant. - RegisterSet regSet(RegisterSet::All()); + AllocatableRegisterSet regSet(RegisterSet::All()); regSet.take(AnyRegister(object)); if (!value.constant()) regSet.takeUnchecked(value.reg()); @@ -2461,11 +2461,11 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler& masm, // // Be very careful not to use any of these before value is pushed, since they // might shadow. - Register scratchReg = regSet.takeGeneral(); + Register scratchReg = regSet.takeAnyGeneral(); if (IsCacheableSetPropCallNative(obj, holder, shape)) { - Register argJSContextReg = regSet.takeGeneral(); - Register argVpReg = regSet.takeGeneral(); + Register argJSContextReg = regSet.takeAnyGeneral(); + Register argVpReg = regSet.takeAnyGeneral(); MOZ_ASSERT(shape->hasSetterValue() && shape->setterObject() && shape->setterObject()->is()); @@ -2473,7 +2473,7 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler& masm, MOZ_ASSERT(target->isNative()); - Register argUintNReg = regSet.takeGeneral(); + Register argUintNReg = regSet.takeAnyGeneral(); // Set up the call: // bool (*)(JSContext*, unsigned, Value* vp) @@ -2516,13 +2516,14 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler& masm, // for the value, one for scratch, 5 for the arguments, which makes 8, // but we only have 7 to work with. So only grab the ones we need // before we push value and release its reg back into the set. - Register argResultReg = regSet.takeGeneral(); + Register argResultReg = regSet.takeAnyGeneral(); + SetterOp target = shape->setterOp(); MOZ_ASSERT(target); // JSSetterOp: bool fn(JSContext *cx, HandleObject obj, - // HandleId id, MutableHandleValue vp, ObjectOpResult &result); + // HandleId id, HandleValue value, ObjectOpResult &result); // First, allocate an ObjectOpResult on the stack. We push this before // the stubCode pointer in order to match the layout of @@ -2542,12 +2543,12 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler& masm, // OK, now we can grab our remaining registers and grab the pointer to // what we just pushed into one of them. - Register argJSContextReg = regSet.takeGeneral(); - Register argVpReg = regSet.takeGeneral(); + Register argJSContextReg = regSet.takeAnyGeneral(); + Register argValueReg = regSet.takeAnyGeneral(); // We can just reuse the "object" register for argObjReg Register argObjReg = object; - Register argIdReg = regSet.takeGeneral(); - masm.movePtr(StackPointer, argVpReg); + Register argIdReg = regSet.takeAnyGeneral(); + masm.movePtr(StackPointer, argValueReg); // push canonical jsid from shape instead of propertyname. masm.Push(shape->propid(), argIdReg); @@ -2567,7 +2568,7 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler& masm, masm.passABIArg(argJSContextReg); masm.passABIArg(argObjReg); masm.passABIArg(argIdReg); - masm.passABIArg(argVpReg); + masm.passABIArg(argValueReg); masm.passABIArg(argResultReg); masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, target)); @@ -2579,7 +2580,8 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler& masm, EmitObjectOpResultCheck(masm, masm.exceptionLabel(), strict, scratchReg, argJSContextReg, argObjReg, - argIdReg, argVpReg, argResultReg); + argIdReg, argValueReg, + argResultReg); // masm.leaveExitFrame & pop locals. masm.adjustStack(IonOOLSetterOpExitFrameLayout::Size()); @@ -3290,18 +3292,18 @@ SetPropertyIC::update(JSContext *cx, HandleScript outerScript, size_t cacheIndex // The property did not exist before, now we can try to inline the property add. bool checkTypeset; if (!addedSetterStub && canCache == MaybeCanAttachAddSlot && - IsPropertyAddInlineable(&obj->as(), id, cache.value(), oldShape, - cache.needsTypeBarrier(), &checkTypeset)) - { - if (!cache.attachAddSlot(cx, outerScript, ion, obj, oldShape, oldGroup, checkTypeset)) - return false; - addedSetterStub = true; - } + IsPropertyAddInlineable(&obj->as(), id, cache.value(), oldShape, + cache.needsTypeBarrier(), &checkTypeset)) + { + if (!cache.attachAddSlot(cx, outerScript, ion, obj, oldShape, oldGroup, checkTypeset)) + return false; + addedSetterStub = true; + } - checkTypeset = false; - if (!addedSetterStub && cache.canAttachStub() && - CanAttachAddUnboxedExpando(cx, obj, oldShape, id, cache.value(), -cache.needsTypeBarrier(), &checkTypeset)) + checkTypeset = false; + if (!addedSetterStub && cache.canAttachStub() && + CanAttachAddUnboxedExpando(cx, obj, oldShape, id, cache.value(), + cache.needsTypeBarrier(), &checkTypeset)) { if (!cache.attachAddSlot(cx, outerScript, ion, obj, oldShape, oldGroup, checkTypeset)) return false; @@ -3397,7 +3399,7 @@ GetElementIC::attachGetProp(JSContext* cx, HandleScript outerScript, IonScript* // We have a non-atomized string with the same length. For now call a helper // function to do the comparison. - RegisterSet volatileRegs = RegisterSet::Volatile(); + LiveRegisterSet volatileRegs(RegisterSet::Volatile()); masm.PushRegsInMask(volatileRegs); Register objReg = object(); @@ -3417,7 +3419,7 @@ GetElementIC::attachGetProp(JSContext* cx, HandleScript outerScript, IonScript* if (!volatileRegs.has(objReg)) masm.pop(objReg); - RegisterSet ignore = RegisterSet(); + LiveRegisterSet ignore; ignore.add(scratch); masm.PopRegsInMaskIgnore(volatileRegs, ignore); @@ -3750,20 +3752,21 @@ GenerateGetTypedArrayElement(JSContext* cx, MacroAssembler& masm, IonCache::Stub } // Part 2: Call to translate the str into index - RegisterSet regs = RegisterSet::Volatile(); - masm.PushRegsInMask(regs); + AllocatableRegisterSet regs(RegisterSet::Volatile()); + LiveRegisterSet save(regs.asLiveSet()); + masm.PushRegsInMask(save); regs.takeUnchecked(str); - Register temp = regs.takeGeneral(); + Register temp = regs.takeAnyGeneral(); masm.setupUnalignedABICall(1, temp); masm.passABIArg(str); masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, GetIndexFromString)); masm.mov(ReturnReg, indexReg); - RegisterSet ignore = RegisterSet(); + LiveRegisterSet ignore; ignore.add(indexReg); - masm.PopRegsInMaskIgnore(RegisterSet::Volatile(), ignore); + masm.PopRegsInMaskIgnore(save, ignore); masm.branch32(Assembler::Equal, indexReg, Imm32(UINT32_MAX), &failures); diff --git a/js/src/jit/IonCaches.h b/js/src/jit/IonCaches.h index b9689f1217..6acfa09298 100644 --- a/js/src/jit/IonCaches.h +++ b/js/src/jit/IonCaches.h @@ -544,7 +544,7 @@ class GetPropertyIC : public RepatchIonCache protected: // Registers live after the cache, excluding output registers. The initial // value of these registers must be preserved by the cache. - RegisterSet liveRegs_; + LiveRegisterSet liveRegs_; Register object_; PropertyName *name_; @@ -562,7 +562,7 @@ class GetPropertyIC : public RepatchIonCache bool hasGenericProxyStub_ : 1; public: - GetPropertyIC(RegisterSet liveRegs, + GetPropertyIC(LiveRegisterSet liveRegs, Register object, PropertyName *name, TypedOrValueRegister output, bool monitoredResult) @@ -689,7 +689,7 @@ class SetPropertyIC : public RepatchIonCache protected: // Registers live after the cache, excluding output registers. The initial // value of these registers must be preserved by the cache. - RegisterSet liveRegs_; + LiveRegisterSet liveRegs_; Register object_; PropertyName *name_; @@ -700,7 +700,7 @@ class SetPropertyIC : public RepatchIonCache bool hasGenericProxyStub_; public: - SetPropertyIC(RegisterSet liveRegs, Register object, PropertyName *name, + SetPropertyIC(LiveRegisterSet liveRegs, Register object, PropertyName *name, ConstantOrRegister value, bool strict, bool needsTypeBarrier) : liveRegs_(liveRegs), object_(object), @@ -774,7 +774,7 @@ class SetPropertyIC : public RepatchIonCache class GetElementIC : public RepatchIonCache { protected: - RegisterSet liveRegs_; + LiveRegisterSet liveRegs_; Register object_; ConstantOrRegister index_; @@ -791,7 +791,7 @@ class GetElementIC : public RepatchIonCache static const size_t MAX_FAILED_UPDATES; public: - GetElementIC(RegisterSet liveRegs, Register object, ConstantOrRegister index, + GetElementIC(LiveRegisterSet liveRegs, Register object, ConstantOrRegister index, TypedOrValueRegister output, bool monitoredResult, bool allowDoubleResult) : liveRegs_(liveRegs), object_(object), @@ -1008,7 +1008,7 @@ class NameIC : public RepatchIonCache protected: // Registers live after the cache, excluding output registers. The initial // value of these registers must be preserved by the cache. - RegisterSet liveRegs_; + LiveRegisterSet liveRegs_; bool typeOf_; Register scopeChain_; @@ -1016,7 +1016,7 @@ class NameIC : public RepatchIonCache TypedOrValueRegister output_; public: - NameIC(RegisterSet liveRegs, bool typeOf, + NameIC(LiveRegisterSet liveRegs, bool typeOf, Register scopeChain, PropertyName *name, TypedOrValueRegister output) : liveRegs_(liveRegs), diff --git a/js/src/jit/JitCommon.h b/js/src/jit/JitCommon.h index 1ab86f323e..6919a5efff 100644 --- a/js/src/jit/JitCommon.h +++ b/js/src/jit/JitCommon.h @@ -19,15 +19,15 @@ // Call into cross-jitted code by following the ABI of the simulated architecture. #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \ (js::jit::Simulator::Current()->call( \ - JS_FUNC_TO_DATA_PTR(uint8_t *, entry), 8, p0, p1, p2, p3, p4, p5, p6, p7) & 0xffffffff) + JS_FUNC_TO_DATA_PTR(uint8_t*, entry), 8, p0, p1, p2, p3, p4, p5, p6, p7) & 0xffffffff) #define CALL_GENERATED_1(entry, p0) \ (js::jit::Simulator::Current()->call( \ - JS_FUNC_TO_DATA_PTR(uint8_t *, entry), 1, p0) & 0xffffffff) + JS_FUNC_TO_DATA_PTR(uint8_t*, entry), 1, p0) & 0xffffffff) #define CALL_GENERATED_2(entry, p0, p1) \ (js::jit::Simulator::Current()->call( \ - JS_FUNC_TO_DATA_PTR(uint8_t *, entry), 2, p0, p1) & 0xffffffff) + JS_FUNC_TO_DATA_PTR(uint8_t*, entry), 2, p0, p1) & 0xffffffff) #else diff --git a/js/src/jit/JitFrames.cpp b/js/src/jit/JitFrames.cpp index c1e7e8d9b1..6670a06a86 100644 --- a/js/src/jit/JitFrames.cpp +++ b/js/src/jit/JitFrames.cpp @@ -347,7 +347,7 @@ JitFrameIterator::machineState() const uint8_t *spillAlign = alignDoubleSpillWithOffset(reinterpret_cast(spill), 0); char *floatSpill = reinterpret_cast(spillAlign); - FloatRegisterSet fregs = reader.allFloatSpills(); + FloatRegisterSet fregs = reader.allFloatSpills().set(); fregs = fregs.reduceSetForPush(); for (FloatRegisterBackwardIterator iter(fregs); iter.more(); iter++) { floatSpill -= (*iter).size(); @@ -998,7 +998,7 @@ ReadAllocation(const JitFrameIterator& frame, const LAllocation* a) #endif static void -MarkThisAndArguments(JSTracer *trc, JitFrameLayout *layout) +MarkThisAndArguments(JSTracer* trc, JitFrameLayout* layout) { // Mark |this| and any extra actual arguments for an Ion frame. Marking of // formal arguments is taken care of by the frame's safepoint/snapshot, @@ -1023,15 +1023,15 @@ MarkThisAndArguments(JSTracer *trc, JitFrameLayout *layout) } static void -MarkThisAndArguments(JSTracer *trc, const JitFrameIterator &frame) +MarkThisAndArguments(JSTracer* trc, const JitFrameIterator& frame) { - JitFrameLayout *layout = frame.jsFrame(); + JitFrameLayout* layout = frame.jsFrame(); MarkThisAndArguments(trc, layout); } #ifdef JS_NUNBOX32 static inline void -WriteAllocation(const JitFrameIterator &frame, const LAllocation *a, uintptr_t value) +WriteAllocation(const JitFrameIterator& frame, const LAllocation* a, uintptr_t value) { if (a->isGeneralReg()) { Register reg = a->toGeneralReg()->reg(); @@ -1080,8 +1080,8 @@ MarkIonJSFrame(JSTracer* trc, const JitFrameIterator& frame) } uintptr_t *spill = frame.spillBase(); - GeneralRegisterSet gcRegs = safepoint.gcSpills(); - GeneralRegisterSet valueRegs = safepoint.valueSpills(); + LiveGeneralRegisterSet gcRegs = safepoint.gcSpills(); + LiveGeneralRegisterSet valueRegs = safepoint.valueSpills(); for (GeneralRegisterBackwardIterator iter(safepoint.allGprSpills()); iter.more(); iter++) { --spill; if (gcRegs.has(*iter)) @@ -1167,7 +1167,7 @@ UpdateIonJSFrameForMinorGC(JSTracer* trc, const JitFrameIterator& frame) const SafepointIndex *si = ionScript->getSafepointIndex(frame.returnAddressToFp()); SafepointReader safepoint(ionScript, si); - GeneralRegisterSet slotsRegs = safepoint.slotsOrElementsSpills(); + LiveGeneralRegisterSet slotsRegs = safepoint.slotsOrElementsSpills(); uintptr_t *spill = frame.spillBase(); for (GeneralRegisterBackwardIterator iter(safepoint.allGprSpills()); iter.more(); iter++) { --spill; @@ -1308,15 +1308,15 @@ MarkJitExitFrame(JSTracer *trc, const JitFrameIterator &frame) // CodeGenerator.cpp which handle the case of a native function call. We // need to mark the argument vector of the function call. if (frame.isExitFrameLayout()) { - NativeExitFrameLayout *native = frame.exitFrame()->as(); + NativeExitFrameLayout* native = frame.exitFrame()->as(); size_t len = native->argc() + 2; - Value *vp = native->vp(); + Value* vp = native->vp(); gc::MarkValueRootRange(trc, len, vp, "ion-native-args"); return; } if (frame.isExitFrameLayout()) { - IonOOLNativeExitFrameLayout *oolnative = + IonOOLNativeExitFrameLayout* oolnative = frame.exitFrame()->as(); gc::MarkJitCodeRoot(trc, oolnative->stubCode(), "ion-ool-native-code"); gc::MarkValueRoot(trc, oolnative->vp(), "iol-ool-native-vp"); @@ -1331,7 +1331,7 @@ MarkJitExitFrame(JSTracer *trc, const JitFrameIterator &frame) // A SetterOp frame is a different size, but that's the only relevant // difference between the two. The fields that need marking are all in // the common base class. - IonOOLPropertyOpExitFrameLayout *oolgetter = + IonOOLPropertyOpExitFrameLayout* oolgetter = frame.isExitFrameLayout() ? frame.exitFrame()->as() : frame.exitFrame()->as(); @@ -1369,8 +1369,8 @@ MarkJitExitFrame(JSTracer *trc, const JitFrameIterator &frame) } if (frame.isExitFrameLayout()) { - LazyLinkExitFrameLayout *ll = frame.exitFrame()->as(); - JitFrameLayout *layout = ll->jsFrame(); + LazyLinkExitFrameLayout* ll = frame.exitFrame()->as(); + JitFrameLayout* layout = ll->jsFrame(); gc::MarkJitCodeRoot(trc, ll->stubCode(), "lazy-link-code"); layout->replaceCalleeToken(MarkCalleeToken(trc, layout->calleeToken())); @@ -2504,20 +2504,20 @@ InlineFrameIterator::isFunctionFrame() const } MachineState -MachineState::FromBailout(RegisterDump::GPRArray ®s, RegisterDump::FPUArray &fpregs) +MachineState::FromBailout(RegisterDump::GPRArray& regs, RegisterDump::FPUArray& fpregs) { MachineState machine; for (unsigned i = 0; i < Registers::Total; i++) machine.setRegisterLocation(Register::FromCode(i), ®s[i].r); #ifdef JS_CODEGEN_ARM - float *fbase = (float*)&fpregs[0]; + float* fbase = (float*)&fpregs[0]; for (unsigned i = 0; i < FloatRegisters::TotalDouble; i++) machine.setRegisterLocation(FloatRegister(i, FloatRegister::Double), &fpregs[i].d); for (unsigned i = 0; i < FloatRegisters::TotalSingle; i++) machine.setRegisterLocation(FloatRegister(i, FloatRegister::Single), (double*)&fbase[i]); #elif defined(JS_CODEGEN_MIPS) - float *fbase = (float*)&fpregs[0]; + float* fbase = (float*)&fpregs[0]; for (unsigned i = 0; i < FloatRegisters::TotalDouble; i++) { machine.setRegisterLocation(FloatRegister::FromIndex(i, FloatRegister::Double), &fpregs[i].d); @@ -3017,9 +3017,9 @@ void JitProfilingFrameIterator::fixBaselineDebugModeOSRReturnAddress() { MOZ_ASSERT(type_ == JitFrame_BaselineJS); - BaselineFrame *bl = (BaselineFrame *)(fp_ - BaselineFrame::FramePointerOffset - + BaselineFrame* bl = (BaselineFrame*)(fp_ - BaselineFrame::FramePointerOffset - BaselineFrame::Size()); - if (BaselineDebugModeOSRInfo *info = bl->getDebugModeOSRInfo()) + if (BaselineDebugModeOSRInfo* info = bl->getDebugModeOSRInfo()) returnAddressToFp_ = info->resumeAddr; } diff --git a/js/src/jit/JitcodeMap.cpp b/js/src/jit/JitcodeMap.cpp index 3aff298a4a..466f0a0104 100644 --- a/js/src/jit/JitcodeMap.cpp +++ b/js/src/jit/JitcodeMap.cpp @@ -24,12 +24,12 @@ namespace js { namespace jit { static inline JitcodeRegionEntry -RegionAtAddr(const JitcodeGlobalEntry::IonEntry &entry, void *ptr, - uint32_t *ptrOffset) +RegionAtAddr(const JitcodeGlobalEntry::IonEntry& entry, void* ptr, + uint32_t* ptrOffset) { MOZ_ASSERT(entry.containsPointer(ptr)); - *ptrOffset = reinterpret_cast(ptr) - - reinterpret_cast(entry.nativeStartAddr()); + *ptrOffset = reinterpret_cast(ptr) - + reinterpret_cast(entry.nativeStartAddr()); uint32_t regionIdx = entry.regionTable()->findRegionEntry(*ptrOffset); MOZ_ASSERT(regionIdx < entry.regionTable()->numRegions()); @@ -96,8 +96,8 @@ JitcodeGlobalEntry::IonEntry::callStackAtAddr(JSRuntime* rt, void* ptr, } void -JitcodeGlobalEntry::IonEntry::youngestFrameLocationAtAddr(JSRuntime *rt, void *ptr, - JSScript **script, jsbytecode **pc) const +JitcodeGlobalEntry::IonEntry::youngestFrameLocationAtAddr(JSRuntime* rt, void* ptr, + JSScript** script, jsbytecode** pc) const { uint32_t ptrOffset; JitcodeRegionEntry region = RegionAtAddr(*this, ptr, &ptrOffset); @@ -180,11 +180,11 @@ JitcodeGlobalEntry::BaselineEntry::callStackAtAddr(JSRuntime* rt, void* ptr, } void -JitcodeGlobalEntry::BaselineEntry::youngestFrameLocationAtAddr(JSRuntime *rt, void *ptr, - JSScript **script, - jsbytecode **pc) const +JitcodeGlobalEntry::BaselineEntry::youngestFrameLocationAtAddr(JSRuntime* rt, void* ptr, + JSScript** script, + jsbytecode** pc) const { - uint8_t *addr = reinterpret_cast(ptr); + uint8_t* addr = reinterpret_cast(ptr); *script = script_; *pc = script_->baselineScript()->approximatePcForNativeAddress(script_, addr); } @@ -233,9 +233,9 @@ JitcodeGlobalEntry::IonCacheEntry::callStackAtAddr(JSRuntime* rt, void* ptr, } void -JitcodeGlobalEntry::IonCacheEntry::youngestFrameLocationAtAddr(JSRuntime *rt, void *ptr, - JSScript **script, - jsbytecode **pc) const +JitcodeGlobalEntry::IonCacheEntry::youngestFrameLocationAtAddr(JSRuntime* rt, void* ptr, + JSScript** script, + jsbytecode** pc) const { JitcodeGlobalEntry entry; RejoinEntry(rt, *this, ptr, &entry); @@ -375,7 +375,7 @@ JitcodeGlobalEntry::createScriptString(JSContext* cx, JSScript* script, size_t* } -JitcodeGlobalTable::Enum::Enum(JitcodeGlobalTable &table, JSRuntime *rt) +JitcodeGlobalTable::Enum::Enum(JitcodeGlobalTable& table, JSRuntime* rt) : Range(table), rt_(rt), next_(cur_ ? cur_->tower_->next(0) : nullptr) @@ -392,7 +392,7 @@ JitcodeGlobalTable::Enum::popFront() // Did not remove current entry; advance prevTower_. if (cur_ != table_.freeEntries_) { for (int level = cur_->tower_->height() - 1; level >= 0; level--) { - JitcodeGlobalEntry *prevTowerEntry = prevTower_[level]; + JitcodeGlobalEntry* prevTowerEntry = prevTower_[level]; if (prevTowerEntry) { if (prevTowerEntry->tower_->next(level) == cur_) @@ -429,12 +429,12 @@ JitcodeGlobalTable::lookup(void* ptr, JitcodeGlobalEntry* result, JSRuntime* rt) } bool -JitcodeGlobalTable::lookupForSampler(void *ptr, JitcodeGlobalEntry *result, JSRuntime *rt, +JitcodeGlobalTable::lookupForSampler(void* ptr, JitcodeGlobalEntry* result, JSRuntime* rt, uint32_t sampleBufferGen) { MOZ_ASSERT(result); - JitcodeGlobalEntry *entry = lookupInternal(ptr); + JitcodeGlobalEntry* entry = lookupInternal(ptr); if (!entry) return false; @@ -461,11 +461,11 @@ JitcodeGlobalTable::lookupForSampler(void *ptr, JitcodeGlobalEntry *result, JSRu return true; } -JitcodeGlobalEntry * -JitcodeGlobalTable::lookupInternal(void *ptr) +JitcodeGlobalEntry* +JitcodeGlobalTable::lookupInternal(void* ptr) { JitcodeGlobalEntry query = JitcodeGlobalEntry::MakeQuery(ptr); - JitcodeGlobalEntry *searchTower[JitcodeSkiplistTower::MAX_HEIGHT]; + JitcodeGlobalEntry* searchTower[JitcodeSkiplistTower::MAX_HEIGHT]; searchInternal(query, searchTower); if (searchTower[0] == nullptr) { @@ -479,10 +479,10 @@ JitcodeGlobalTable::lookupInternal(void *ptr) return (cmp == 0) ? startTower_[0] : nullptr; } - JitcodeGlobalEntry *bottom = searchTower[0]; + JitcodeGlobalEntry* bottom = searchTower[0]; MOZ_ASSERT(bottom->compareTo(query) < 0); - JitcodeGlobalEntry *bottomNext = bottom->tower_->next(0); + JitcodeGlobalEntry* bottomNext = bottom->tower_->next(0); if (bottomNext == nullptr) return nullptr; @@ -516,10 +516,10 @@ JitcodeGlobalTable::addEntry(const JitcodeGlobalEntry& entry, JSRuntime* rt) // Link up entry with forward entries taken from tower. for (int level = newTower->height() - 1; level >= 0; level--) { - JitcodeGlobalEntry *searchTowerEntry = searchTower[level]; + JitcodeGlobalEntry* searchTowerEntry = searchTower[level]; if (searchTowerEntry) { MOZ_ASSERT(searchTowerEntry->compareTo(*newEntry) < 0); - JitcodeGlobalEntry *searchTowerNextEntry = searchTowerEntry->tower_->next(level); + JitcodeGlobalEntry* searchTowerNextEntry = searchTowerEntry->tower_->next(level); MOZ_ASSERT_IF(searchTowerNextEntry, searchTowerNextEntry->compareTo(*newEntry) > 0); @@ -536,14 +536,14 @@ JitcodeGlobalTable::addEntry(const JitcodeGlobalEntry& entry, JSRuntime* rt) } void -JitcodeGlobalTable::removeEntry(JitcodeGlobalEntry &entry, JitcodeGlobalEntry **prevTower, - JSRuntime *rt) +JitcodeGlobalTable::removeEntry(JitcodeGlobalEntry& entry, JitcodeGlobalEntry** prevTower, + JSRuntime* rt) { MOZ_ASSERT(!rt->isProfilerSamplingEnabled()); // Unlink query entry. for (int level = entry.tower_->height() - 1; level >= 0; level--) { - JitcodeGlobalEntry *prevTowerEntry = prevTower[level]; + JitcodeGlobalEntry* prevTowerEntry = prevTower[level]; if (prevTowerEntry) { MOZ_ASSERT(prevTowerEntry->tower_->next(level) == &entry); prevTowerEntry->tower_->setNext(level, entry.tower_->next(level)); @@ -563,8 +563,8 @@ JitcodeGlobalTable::removeEntry(JitcodeGlobalEntry &entry, JitcodeGlobalEntry ** } void -JitcodeGlobalTable::releaseEntry(JitcodeGlobalEntry &entry, JitcodeGlobalEntry **prevTower, - JSRuntime *rt) +JitcodeGlobalTable::releaseEntry(JitcodeGlobalEntry& entry, JitcodeGlobalEntry** prevTower, + JSRuntime* rt) { mozilla::DebugOnly gen = rt->profilerSampleBufferGen(); mozilla::DebugOnly lapCount = rt->profilerSampleBufferLapCount(); @@ -573,11 +573,11 @@ JitcodeGlobalTable::releaseEntry(JitcodeGlobalEntry &entry, JitcodeGlobalEntry * } void -JitcodeGlobalTable::searchInternal(const JitcodeGlobalEntry &query, JitcodeGlobalEntry **towerOut) +JitcodeGlobalTable::searchInternal(const JitcodeGlobalEntry& query, JitcodeGlobalEntry** towerOut) { - JitcodeGlobalEntry *cur = nullptr; + JitcodeGlobalEntry* cur = nullptr; for (int level = JitcodeSkiplistTower::MAX_HEIGHT - 1; level >= 0; level--) { - JitcodeGlobalEntry *entry = searchAtHeight(level, cur, query); + JitcodeGlobalEntry* entry = searchAtHeight(level, cur, query); MOZ_ASSERT_IF(entry == nullptr, cur == nullptr); towerOut[level] = entry; cur = entry; @@ -594,7 +594,7 @@ JitcodeGlobalTable::searchInternal(const JitcodeGlobalEntry &query, JitcodeGloba continue; } - JitcodeGlobalEntry *cur = towerOut[level]; + JitcodeGlobalEntry* cur = towerOut[level]; // Non-null result at a given level must sort < query. MOZ_ASSERT(cur->compareTo(query) < 0); @@ -603,7 +603,7 @@ JitcodeGlobalTable::searchInternal(const JitcodeGlobalEntry &query, JitcodeGloba if (!cur->tower_->next(level)) continue; - JitcodeGlobalEntry *next = cur->tower_->next(level); + JitcodeGlobalEntry* next = cur->tower_->next(level); // Next entry must have tower height that accomodates level. MOZ_ASSERT(unsigned(level) < next->tower_->height()); @@ -614,11 +614,11 @@ JitcodeGlobalTable::searchInternal(const JitcodeGlobalEntry &query, JitcodeGloba #endif // DEBUG } -JitcodeGlobalEntry * -JitcodeGlobalTable::searchAtHeight(unsigned level, JitcodeGlobalEntry *start, - const JitcodeGlobalEntry &query) +JitcodeGlobalEntry* +JitcodeGlobalTable::searchAtHeight(unsigned level, JitcodeGlobalEntry* start, + const JitcodeGlobalEntry& query) { - JitcodeGlobalEntry *cur = start; + JitcodeGlobalEntry* cur = start; // If starting with nullptr, use the start tower. if (start == nullptr) { @@ -630,7 +630,7 @@ JitcodeGlobalTable::searchAtHeight(unsigned level, JitcodeGlobalEntry *start, // Keep skipping at |level| until we reach an entry < query whose // successor is an entry >= query. for (;;) { - JitcodeGlobalEntry *next = cur->tower_->next(level); + JitcodeGlobalEntry* next = cur->tower_->next(level); if (next == nullptr || next->compareTo(query) >= 0) return cur; @@ -657,26 +657,26 @@ JitcodeGlobalTable::generateTowerHeight() return result + 1; } -JitcodeSkiplistTower * +JitcodeSkiplistTower* JitcodeGlobalTable::allocateTower(unsigned height) { MOZ_ASSERT(height >= 1); - JitcodeSkiplistTower *tower = JitcodeSkiplistTower::PopFromFreeList(&freeTowers_[height - 1]); + JitcodeSkiplistTower* tower = JitcodeSkiplistTower::PopFromFreeList(&freeTowers_[height - 1]); if (tower) return tower; size_t size = JitcodeSkiplistTower::CalculateSize(height); - tower = (JitcodeSkiplistTower *) alloc_.alloc(size); + tower = (JitcodeSkiplistTower*) alloc_.alloc(size); if (!tower) return nullptr; return new (tower) JitcodeSkiplistTower(height); } -JitcodeGlobalEntry * +JitcodeGlobalEntry* JitcodeGlobalTable::allocateEntry() { - JitcodeGlobalEntry *entry = JitcodeGlobalEntry::PopFromFreeList(&freeEntries_); + JitcodeGlobalEntry* entry = JitcodeGlobalEntry::PopFromFreeList(&freeEntries_); if (entry) return entry; @@ -687,12 +687,12 @@ JitcodeGlobalTable::allocateEntry() void JitcodeGlobalTable::verifySkiplist() { - JitcodeGlobalEntry *curTower[JitcodeSkiplistTower::MAX_HEIGHT]; + JitcodeGlobalEntry* curTower[JitcodeSkiplistTower::MAX_HEIGHT]; for (unsigned i = 0; i < JitcodeSkiplistTower::MAX_HEIGHT; i++) curTower[i] = startTower_[i]; uint32_t count = 0; - JitcodeGlobalEntry *curEntry = startTower_[0]; + JitcodeGlobalEntry* curEntry = startTower_[0]; while (curEntry) { count++; unsigned curHeight = curEntry->tower_->height(); @@ -701,7 +701,7 @@ JitcodeGlobalTable::verifySkiplist() for (unsigned i = 0; i < JitcodeSkiplistTower::MAX_HEIGHT; i++) { if (i < curHeight) { MOZ_ASSERT(curTower[i] == curEntry); - JitcodeGlobalEntry *nextEntry = curEntry->tower_->next(i); + JitcodeGlobalEntry* nextEntry = curEntry->tower_->next(i); MOZ_ASSERT_IF(nextEntry, curEntry->compareTo(*nextEntry) < 0); curTower[i] = nextEntry; } else { @@ -716,7 +716,7 @@ JitcodeGlobalTable::verifySkiplist() #endif // DEBUG bool -JitcodeGlobalTable::markIteratively(JSTracer *trc) +JitcodeGlobalTable::markIteratively(JSTracer* trc) { // JitcodeGlobalTable must keep entries that are in the sampler buffer // alive. This conditionality is akin to holding the entries weakly. @@ -749,7 +749,7 @@ JitcodeGlobalTable::markIteratively(JSTracer *trc) bool markedAny = false; for (Range r(*this); !r.empty(); r.popFront()) { - JitcodeGlobalEntry *entry = r.front(); + JitcodeGlobalEntry* entry = r.front(); // If an entry is not sampled, reset its generation to the invalid // generation, and conditionally mark the rest of the entry if its @@ -776,11 +776,11 @@ JitcodeGlobalTable::markIteratively(JSTracer *trc) } void -JitcodeGlobalTable::sweep(JSRuntime *rt) +JitcodeGlobalTable::sweep(JSRuntime* rt) { AutoSuppressProfilerSampling suppressSampling(rt); for (Enum e(*this, rt); !e.empty(); e.popFront()) { - JitcodeGlobalEntry *entry = e.front(); + JitcodeGlobalEntry* entry = e.front(); if (!entry->zone()->isCollecting() || entry->zone()->isGCFinished()) continue; @@ -793,7 +793,7 @@ JitcodeGlobalTable::sweep(JSRuntime *rt) } bool -JitcodeGlobalEntry::BaseEntry::markJitcodeIfUnmarked(JSTracer *trc) +JitcodeGlobalEntry::BaseEntry::markJitcodeIfUnmarked(JSTracer* trc) { if (!IsJitCodeMarked(&jitcode_)) { MarkJitCodeUnbarriered(trc, &jitcode_, "jitcodglobaltable-baseentry-jitcode"); @@ -816,7 +816,7 @@ JitcodeGlobalEntry::BaseEntry::isJitcodeAboutToBeFinalized() } bool -JitcodeGlobalEntry::BaselineEntry::markIfUnmarked(JSTracer *trc) +JitcodeGlobalEntry::BaselineEntry::markIfUnmarked(JSTracer* trc) { if (!IsScriptMarked(&script_)) { MarkScriptUnbarriered(trc, &script_, "jitcodeglobaltable-baselineentry-script"); @@ -839,7 +839,7 @@ JitcodeGlobalEntry::BaselineEntry::isMarkedFromAnyThread() } bool -JitcodeGlobalEntry::IonEntry::markIfUnmarked(JSTracer *trc) +JitcodeGlobalEntry::IonEntry::markIfUnmarked(JSTracer* trc) { bool markedAny = false; @@ -854,7 +854,7 @@ JitcodeGlobalEntry::IonEntry::markIfUnmarked(JSTracer *trc) if (!optsAllTypes_) return markedAny; - for (IonTrackedTypeWithAddendum *iter = optsAllTypes_->begin(); + for (IonTrackedTypeWithAddendum* iter = optsAllTypes_->begin(); iter != optsAllTypes_->end(); iter++) { if (!TypeSet::IsTypeMarked(&iter->type)) { @@ -884,7 +884,7 @@ JitcodeGlobalEntry::IonEntry::sweep() if (!optsAllTypes_) return; - for (IonTrackedTypeWithAddendum *iter = optsAllTypes_->begin(); + for (IonTrackedTypeWithAddendum* iter = optsAllTypes_->begin(); iter != optsAllTypes_->end(); iter++) { // Types may move under compacting GC. This method is only called on @@ -911,7 +911,7 @@ JitcodeGlobalEntry::IonEntry::isMarkedFromAnyThread() if (!optsAllTypes_) return true; - for (IonTrackedTypeWithAddendum *iter = optsAllTypes_->begin(); + for (IonTrackedTypeWithAddendum* iter = optsAllTypes_->begin(); iter != optsAllTypes_->end(); iter++) { if (!TypeSet::IsTypeMarked(&iter->type) && @@ -925,7 +925,7 @@ JitcodeGlobalEntry::IonEntry::isMarkedFromAnyThread() } bool -JitcodeGlobalEntry::IonCacheEntry::isMarkedFromAnyThread(JSRuntime *rt) +JitcodeGlobalEntry::IonCacheEntry::isMarkedFromAnyThread(JSRuntime* rt) { JitcodeGlobalEntry entry; RejoinEntry(rt, *this, nativeStartAddr(), &entry); @@ -1508,9 +1508,9 @@ JitcodeIonTable::WriteIonTable(CompactBufferWriter& writer, JS_PUBLIC_API(JS::ProfilingFrameIterator::FrameKind) -JS::GetProfilingFrameKindFromNativeAddr(JSRuntime *rt, void *addr) +JS::GetProfilingFrameKindFromNativeAddr(JSRuntime* rt, void* addr) { - JitcodeGlobalTable *table = rt->jitRuntime()->getJitcodeGlobalTable(); + JitcodeGlobalTable* table = rt->jitRuntime()->getJitcodeGlobalTable(); JitcodeGlobalEntry entry; table->lookupInfallible(addr, &entry, rt); MOZ_ASSERT(entry.isIon() || entry.isIonCache() || entry.isBaseline()); diff --git a/js/src/jit/LIR.h b/js/src/jit/LIR.h index b35bc80b99..c8f4119981 100644 --- a/js/src/jit/LIR.h +++ b/js/src/jit/LIR.h @@ -1323,15 +1323,15 @@ class LSafepoint : public TempObject // registers: if passed to the call, the values passed will be marked via // MarkJitExitFrame, and no registers can be live after the instruction // except its outputs. - RegisterSet liveRegs_; + LiveRegisterSet liveRegs_; // The subset of liveRegs which contains gcthing pointers. - GeneralRegisterSet gcRegs_; + LiveGeneralRegisterSet gcRegs_; #ifdef CHECK_OSIPOINT_REGISTERS // Clobbered regs of the current instruction. This set is never written to // the safepoint; it's only used by assertions during compilation. - RegisterSet clobberedRegs_; + LiveRegisterSet clobberedRegs_; #endif // Offset to a position in the safepoint stream, or @@ -1352,11 +1352,11 @@ class LSafepoint : public TempObject NunboxList nunboxParts_; #elif JS_PUNBOX64 // The subset of liveRegs which have Values. - GeneralRegisterSet valueRegs_; + LiveGeneralRegisterSet valueRegs_; #endif // The subset of liveRegs which contains pointers to slots/elements. - GeneralRegisterSet slotsOrElementsRegs_; + LiveGeneralRegisterSet slotsOrElementsRegs_; // List of slots which have slots/elements pointers. SlotList slotsOrElementsSlots_; @@ -1386,7 +1386,7 @@ class LSafepoint : public TempObject liveRegs_.addUnchecked(reg); assertInvariants(); } - const RegisterSet &liveRegs() const { + const LiveRegisterSet &liveRegs() const { return liveRegs_; } #ifdef CHECK_OSIPOINT_REGISTERS @@ -1394,7 +1394,7 @@ class LSafepoint : public TempObject clobberedRegs_.addUnchecked(reg); assertInvariants(); } - const RegisterSet &clobberedRegs() const { + const LiveRegisterSet &clobberedRegs() const { return clobberedRegs_; } #endif @@ -1402,7 +1402,7 @@ class LSafepoint : public TempObject gcRegs_.addUnchecked(reg); assertInvariants(); } - GeneralRegisterSet gcRegs() const { + LiveGeneralRegisterSet gcRegs() const { return gcRegs_; } bool addGcSlot(bool stack, uint32_t slot) { @@ -1418,7 +1418,7 @@ class LSafepoint : public TempObject SlotList &slotsOrElementsSlots() { return slotsOrElementsSlots_; } - GeneralRegisterSet slotsOrElementsRegs() const { + LiveGeneralRegisterSet slotsOrElementsRegs() const { return slotsOrElementsRegs_; } void addSlotsOrElementsRegister(Register reg) { @@ -1567,7 +1567,7 @@ class LSafepoint : public TempObject valueRegs_.add(reg); assertInvariants(); } - GeneralRegisterSet valueRegs() const { + LiveGeneralRegisterSet valueRegs() const { return valueRegs_; } @@ -1844,7 +1844,7 @@ LAllocation::toRegister() const # elif defined(JS_CODEGEN_X64) # include "jit/x64/LIR-x64.h" # endif -# include "jit/shared/LIR-x86-shared.h" +# include "jit/x86-shared/LIR-x86-shared.h" #elif defined(JS_CODEGEN_ARM) # include "jit/arm/LIR-arm.h" #elif defined(JS_CODEGEN_MIPS) diff --git a/js/src/jit/LinearScan.cpp b/js/src/jit/LinearScan.cpp index 4a63e0e8ea..12a65692a9 100644 --- a/js/src/jit/LinearScan.cpp +++ b/js/src/jit/LinearScan.cpp @@ -995,11 +995,17 @@ LinearScanAllocator::findBestFreeRegister(CodePosition* freeUntil) // Compute free-until positions for all registers CodePosition freeUntilPos[AnyRegister::Total]; bool needFloat = vregs[current->vreg()].isFloatReg(); - for (RegisterSet regs(allRegisters_); !regs.empty(needFloat); ) { - // If the requested register is a FP, we may need to look at - // all of the float32 and float64 registers. - AnyRegister reg = regs.takeUnaliasedAny(needFloat); - freeUntilPos[reg.code()] = CodePosition::MAX; + if (needFloat) { + // we may need to look at all of the float32 and float64 registers. + for (LiveRegisterSet regs(allRegisters_.asLiveSet()); !regs.emptyFloat(); ) { + AnyRegister reg(regs.takeAnyFloat()); + freeUntilPos[reg.code()] = CodePosition::MAX; + } + } else { + for (LiveRegisterSet regs(allRegisters_.asLiveSet()); !regs.emptyGeneral(); ) { + AnyRegister reg(regs.takeAnyGeneral()); + freeUntilPos[reg.code()] = CodePosition::MAX; + } } for (IntervalIterator i(active.begin()); i != active.end(); i++) { LAllocation* alloc = i->getAllocation(); @@ -1125,9 +1131,16 @@ LinearScanAllocator::findBestBlockedRegister(CodePosition* nextUsed) // Compute next-used positions for all registers CodePosition nextUsePos[AnyRegister::Total]; bool needFloat = vregs[current->vreg()].isFloatReg(); - for (RegisterSet regs(allRegisters_); !regs.empty(needFloat); ) { - AnyRegister reg = regs.takeUnaliasedAny(needFloat); - nextUsePos[reg.code()] = CodePosition::MAX; + if (needFloat) { + for (LiveRegisterSet regs(allRegisters_.asLiveSet()); !regs.emptyFloat(); ) { + AnyRegister reg(regs.takeAnyFloat()); + nextUsePos[reg.code()] = CodePosition::MAX; + } + } else { + for (LiveRegisterSet regs(allRegisters_.asLiveSet()); !regs.emptyGeneral(); ) { + AnyRegister reg(regs.takeAnyGeneral()); + nextUsePos[reg.code()] = CodePosition::MAX; + } } for (IntervalIterator i(active.begin()); i != active.end(); i++) { LAllocation* alloc = i->getAllocation(); diff --git a/js/src/jit/LiveRangeAllocator.cpp b/js/src/jit/LiveRangeAllocator.cpp index e59407d712..a21a0b0b93 100644 --- a/js/src/jit/LiveRangeAllocator.cpp +++ b/js/src/jit/LiveRangeAllocator.cpp @@ -645,18 +645,10 @@ LiveRangeAllocator::buildLivenessInfo() for (LInstructionReverseIterator ins = block->rbegin(); ins != block->rend(); ins++) { // Calls may clobber registers, so force a spill and reload around the callsite. if (ins->isCall()) { - for (AnyRegisterIterator iter(allRegisters_); iter.more(); iter++) { + for (AnyRegisterIterator iter(allRegisters_.asLiveSet()); iter.more(); iter++) { if (forLSRA) { - AnyRegister reg(*iter); - // AnyRegisterIterator only iterates every allocatable - // register once, and skip all aliased registers. Thus, - // we have to record that each typed-variant/alias of - // the same register has to be spilled if it got - // allocated. - for (size_t i = 0; i < reg.numAliased(); i++) { - if (!addFixedRangeAtHead(reg.aliased(i), inputOf(*ins), outputOf(*ins))) - return false; - } + if (!addFixedRangeAtHead(*iter, inputOf(*ins), outputOf(*ins))) + return false; } else { bool found = false; diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 440b2aa913..ba9a190351 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -2534,12 +2534,12 @@ LIRGenerator::visitNot(MNot* ins) } void -LIRGenerator::visitBoundsCheck(MBoundsCheck *ins) +LIRGenerator::visitBoundsCheck(MBoundsCheck* ins) { if (!ins->fallible()) return; - LInstruction *check; + LInstruction* check; if (ins->minimum() || ins->maximum()) { check = new(alloc()) LBoundsCheckRange(useRegisterOrConstant(ins->index()), useAny(ins->length()), @@ -2966,7 +2966,7 @@ LIRGenerator::visitLoadTypedArrayElementStatic(MLoadTypedArrayElementStatic* ins } void -LIRGenerator::visitStoreUnboxedScalar(MStoreUnboxedScalar *ins) +LIRGenerator::visitStoreUnboxedScalar(MStoreUnboxedScalar* ins) { MOZ_ASSERT(IsValidElementsType(ins->elements(), ins->offsetAdjustment())); MOZ_ASSERT(ins->index()->type() == MIRType_Int32); @@ -3965,7 +3965,7 @@ LIRGenerator::visitSimdGeneralShuffle(MSimdGeneralShuffle*ins) { MOZ_ASSERT(IsSimdType(ins->type())); - LSimdGeneralShuffleBase *lir; + LSimdGeneralShuffleBase* lir; if (ins->type() == MIRType_Int32x4) lir = new (alloc()) LSimdGeneralShuffleI(temp()); else if (ins->type() == MIRType_Float32x4) @@ -3991,7 +3991,7 @@ LIRGenerator::visitSimdGeneralShuffle(MSimdGeneralShuffle*ins) } void -LIRGenerator::visitSimdUnaryArith(MSimdUnaryArith *ins) +LIRGenerator::visitSimdUnaryArith(MSimdUnaryArith* ins) { MOZ_ASSERT(IsSimdType(ins->input()->type())); MOZ_ASSERT(IsSimdType(ins->type())); @@ -4000,10 +4000,10 @@ LIRGenerator::visitSimdUnaryArith(MSimdUnaryArith *ins) LUse in = use(ins->input()); if (ins->type() == MIRType_Int32x4) { - LSimdUnaryArithIx4 *lir = new(alloc()) LSimdUnaryArithIx4(in); + LSimdUnaryArithIx4* lir = new(alloc()) LSimdUnaryArithIx4(in); define(lir, ins); } else if (ins->type() == MIRType_Float32x4) { - LSimdUnaryArithFx4 *lir = new(alloc()) LSimdUnaryArithFx4(in); + LSimdUnaryArithFx4* lir = new(alloc()) LSimdUnaryArithFx4(in); define(lir, ins); } else { MOZ_CRASH("Unknown SIMD kind for unary operation"); @@ -4011,7 +4011,7 @@ LIRGenerator::visitSimdUnaryArith(MSimdUnaryArith *ins) } void -LIRGenerator::visitSimdBinaryComp(MSimdBinaryComp *ins) +LIRGenerator::visitSimdBinaryComp(MSimdBinaryComp* ins) { MOZ_ASSERT(IsSimdType(ins->lhs()->type())); MOZ_ASSERT(IsSimdType(ins->rhs()->type())); @@ -4021,10 +4021,10 @@ LIRGenerator::visitSimdBinaryComp(MSimdBinaryComp *ins) ins->reverse(); if (ins->specialization() == MIRType_Int32x4) { - LSimdBinaryCompIx4 *add = new(alloc()) LSimdBinaryCompIx4(); + LSimdBinaryCompIx4* add = new(alloc()) LSimdBinaryCompIx4(); lowerForCompIx4(add, ins, ins->lhs(), ins->rhs()); } else if (ins->specialization() == MIRType_Float32x4) { - LSimdBinaryCompFx4 *add = new(alloc()) LSimdBinaryCompFx4(); + LSimdBinaryCompFx4* add = new(alloc()) LSimdBinaryCompFx4(); lowerForCompFx4(add, ins, ins->lhs(), ins->rhs()); } else { MOZ_CRASH("Unknown compare type when comparing values"); @@ -4032,18 +4032,18 @@ LIRGenerator::visitSimdBinaryComp(MSimdBinaryComp *ins) } void -LIRGenerator::visitSimdBinaryBitwise(MSimdBinaryBitwise *ins) +LIRGenerator::visitSimdBinaryBitwise(MSimdBinaryBitwise* ins) { MOZ_ASSERT(IsSimdType(ins->lhs()->type())); MOZ_ASSERT(IsSimdType(ins->rhs()->type())); MOZ_ASSERT(IsSimdType(ins->type())); - MDefinition *lhs = ins->lhs(); - MDefinition *rhs = ins->rhs(); + MDefinition* lhs = ins->lhs(); + MDefinition* rhs = ins->rhs(); ReorderCommutative(&lhs, &rhs, ins); if (ins->type() == MIRType_Int32x4 || ins->type() == MIRType_Float32x4) { - LSimdBinaryBitwiseX4 *lir = new(alloc()) LSimdBinaryBitwiseX4; + LSimdBinaryBitwiseX4* lir = new(alloc()) LSimdBinaryBitwiseX4; lowerForFPU(lir, ins, lhs, rhs); } else { MOZ_CRASH("Unknown SIMD kind when doing bitwise operations"); diff --git a/js/src/jit/MIRGraph.cpp b/js/src/jit/MIRGraph.cpp index 134609c9eb..7902a6a9e4 100644 --- a/js/src/jit/MIRGraph.cpp +++ b/js/src/jit/MIRGraph.cpp @@ -98,7 +98,7 @@ MIRGenerator::abort(const char* message, ...) } void -MIRGenerator::addAbortedPreliminaryGroup(ObjectGroup *group) +MIRGenerator::addAbortedPreliminaryGroup(ObjectGroup* group) { for (size_t i = 0; i < abortedPreliminaryGroups_.length(); i++) { if (group == abortedPreliminaryGroups_[i]) diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp index 6e0ad71aad..b6cede6f62 100644 --- a/js/src/jit/MacroAssembler.cpp +++ b/js/src/jit/MacroAssembler.cpp @@ -1354,7 +1354,7 @@ MacroAssembler::initGCThing(Register obj, Register temp, JSObject *templateObj, RegisterSet regs = RegisterSet::Volatile(); PushRegsInMask(regs); regs.takeUnchecked(obj); - Register temp = regs.takeGeneral(); + Register temp = regs.takeAnyGeneral(); setupUnalignedABICall(2, temp); passABIArg(obj); @@ -1503,7 +1503,7 @@ MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo) bind(&baseline); { // Prepare a register set for use in this case. - GeneralRegisterSet regs(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); MOZ_ASSERT(!regs.has(BaselineStackReg)); regs.take(bailoutInfo); @@ -1565,7 +1565,7 @@ MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo) branchTest32(Zero, ReturnReg, ReturnReg, exceptionLabel()); // Restore values where they need to be and resume execution. - GeneralRegisterSet enterMonRegs(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet enterMonRegs(GeneralRegisterSet::All()); enterMonRegs.take(R0); enterMonRegs.take(BaselineStubReg); enterMonRegs.take(BaselineFrameReg); @@ -1603,7 +1603,7 @@ MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo) branchTest32(Zero, ReturnReg, ReturnReg, exceptionLabel()); // Restore values where they need to be and resume execution. - GeneralRegisterSet enterRegs(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet enterRegs(GeneralRegisterSet::All()); enterRegs.take(R0); enterRegs.take(R1); enterRegs.take(BaselineFrameReg); @@ -1667,16 +1667,17 @@ MacroAssembler::assumeUnreachable(const char* output) { #ifdef DEBUG if (!IsCompilingAsmJS()) { - RegisterSet regs = RegisterSet::Volatile(); - PushRegsInMask(regs); - Register temp = regs.takeGeneral(); + AllocatableRegisterSet regs(RegisterSet::Volatile()); + LiveRegisterSet save(regs.asLiveSet()); + PushRegsInMask(save); + Register temp = regs.takeAnyGeneral(); setupUnalignedABICall(1, temp); movePtr(ImmPtr(output), temp); passABIArg(temp); callWithABI(JS_FUNC_TO_DATA_PTR(void *, AssumeUnreachable_)); - PopRegsInMask(RegisterSet::Volatile()); + PopRegsInMask(save); } #endif @@ -1708,17 +1709,18 @@ Printf0_(const char* output) { void MacroAssembler::printf(const char *output) { - RegisterSet regs = RegisterSet::Volatile(); - PushRegsInMask(regs); + AllocatableRegisterSet regs(RegisterSet::Volatile()); + LiveRegisterSet save(regs.asLiveSet()); + PushRegsInMask(save); - Register temp = regs.takeGeneral(); + Register temp = regs.takeAnyGeneral(); setupUnalignedABICall(1, temp); movePtr(ImmPtr(output), temp); passABIArg(temp); callWithABI(JS_FUNC_TO_DATA_PTR(void *, Printf0_)); - PopRegsInMask(RegisterSet::Volatile()); + PopRegsInMask(save); } static void @@ -1731,12 +1733,13 @@ Printf1_(const char* output, uintptr_t value) { void MacroAssembler::printf(const char *output, Register value) { - RegisterSet regs = RegisterSet::Volatile(); - PushRegsInMask(regs); + AllocatableRegisterSet regs(RegisterSet::Volatile()); + LiveRegisterSet save(regs.asLiveSet()); + PushRegsInMask(save); regs.takeUnchecked(value); - Register temp = regs.takeGeneral(); + Register temp = regs.takeAnyGeneral(); setupUnalignedABICall(2, temp); movePtr(ImmPtr(output), temp); @@ -1744,7 +1747,7 @@ MacroAssembler::printf(const char *output, Register value) passABIArg(value); callWithABI(JS_FUNC_TO_DATA_PTR(void*, Printf1_)); - PopRegsInMask(RegisterSet::Volatile()); + PopRegsInMask(save); } #ifdef JS_TRACE_LOGGING @@ -1754,12 +1757,12 @@ MacroAssembler::tracelogStartId(Register logger, uint32_t textId, bool force) if (!force && !TraceLogTextIdEnabled(textId)) return; - PushRegsInMask(RegisterSet::Volatile()); - - RegisterSet regs = RegisterSet::Volatile(); + AllocatableRegisterSet regs(RegisterSet::Volatile()); + LiveRegisterSet save(regs.asLiveSet()); + PushRegsInMask(save); regs.takeUnchecked(logger); - Register temp = regs.takeGeneral(); + Register temp = regs.takeAnyGeneral(); setupUnalignedABICall(2, temp); passABIArg(logger); @@ -1767,26 +1770,26 @@ MacroAssembler::tracelogStartId(Register logger, uint32_t textId, bool force) passABIArg(temp); callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogStartEventPrivate)); - PopRegsInMask(RegisterSet::Volatile()); + PopRegsInMask(save); } void MacroAssembler::tracelogStartId(Register logger, Register textId) { - PushRegsInMask(RegisterSet::Volatile()); - - RegisterSet regs = RegisterSet::Volatile(); + AllocatableRegisterSet regs(RegisterSet::Volatile()); + LiveRegisterSet save(regs.asLiveSet()); + PushRegsInMask(save); regs.takeUnchecked(logger); regs.takeUnchecked(textId); - Register temp = regs.takeGeneral(); + Register temp = regs.takeAnyGeneral(); setupUnalignedABICall(2, temp); passABIArg(logger); passABIArg(textId); callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogStartEventPrivate)); - PopRegsInMask(RegisterSet::Volatile()); + PopRegsInMask(save); } void @@ -1794,20 +1797,20 @@ MacroAssembler::tracelogStartEvent(Register logger, Register event) { void (&TraceLogFunc)(TraceLoggerThread *, const TraceLoggerEvent &) = TraceLogStartEvent; - PushRegsInMask(RegisterSet::Volatile()); - - RegisterSet regs = RegisterSet::Volatile(); + AllocatableRegisterSet regs(RegisterSet::Volatile()); + LiveRegisterSet save(regs.asLiveSet()); + PushRegsInMask(save); regs.takeUnchecked(logger); regs.takeUnchecked(event); - Register temp = regs.takeGeneral(); + Register temp = regs.takeAnyGeneral(); setupUnalignedABICall(2, temp); passABIArg(logger); passABIArg(event); callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogFunc)); - PopRegsInMask(RegisterSet::Volatile()); + PopRegsInMask(save); } void @@ -1816,12 +1819,12 @@ MacroAssembler::tracelogStopId(Register logger, uint32_t textId, bool force) if (!force && !TraceLogTextIdEnabled(textId)) return; - PushRegsInMask(RegisterSet::Volatile()); - - RegisterSet regs = RegisterSet::Volatile(); + AllocatableRegisterSet regs(RegisterSet::Volatile()); + LiveRegisterSet save(regs.asLiveSet()); + PushRegsInMask(save); regs.takeUnchecked(logger); - Register temp = regs.takeGeneral(); + Register temp = regs.takeAnyGeneral(); setupUnalignedABICall(2, temp); passABIArg(logger); @@ -1830,26 +1833,26 @@ MacroAssembler::tracelogStopId(Register logger, uint32_t textId, bool force) callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogStopEventPrivate)); - PopRegsInMask(RegisterSet::Volatile()); + PopRegsInMask(save); } void MacroAssembler::tracelogStopId(Register logger, Register textId) { - PushRegsInMask(RegisterSet::Volatile()); - RegisterSet regs = RegisterSet::Volatile(); + AllocatableRegisterSet regs(RegisterSet::Volatile()); + LiveRegisterSet save(regs.asLiveSet()); + PushRegsInMask(save); regs.takeUnchecked(logger); - regs.takeUnchecked(textId); - Register temp = regs.takeGeneral(); + Register temp = regs.takeAnyGeneral(); setupUnalignedABICall(2, temp); passABIArg(logger); passABIArg(textId); callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogStopEventPrivate)); - PopRegsInMask(RegisterSet::Volatile()); + PopRegsInMask(save); } #endif @@ -2437,39 +2440,21 @@ MacroAssembler::alignJitStackBasedOnNArgs(uint32_t nargs) // Stack manipulation functions. void -MacroAssembler::PushRegsInMask(RegisterSet set) +MacroAssembler::PushRegsInMask(LiveGeneralRegisterSet set) { - PushRegsInMask(set, FloatRegisterSet()); + PushRegsInMask(LiveRegisterSet(set.set(), FloatRegisterSet())); } void -MacroAssembler::PushRegsInMask(GeneralRegisterSet set) +MacroAssembler::PopRegsInMask(LiveRegisterSet set) { - PushRegsInMask(RegisterSet(set, FloatRegisterSet())); + PopRegsInMaskIgnore(set, LiveRegisterSet()); } void -MacroAssembler::PopRegsInMask(RegisterSet set) +MacroAssembler::PopRegsInMask(LiveGeneralRegisterSet set) { - PopRegsInMaskIgnore(set, RegisterSet()); -} - -void -MacroAssembler::PopRegsInMask(RegisterSet set, FloatRegisterSet simdSet) -{ - PopRegsInMaskIgnore(set, RegisterSet(), simdSet); -} - -void -MacroAssembler::PopRegsInMask(GeneralRegisterSet set) -{ - PopRegsInMask(RegisterSet(set, FloatRegisterSet())); -} - -void -MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore) -{ - PopRegsInMaskIgnore(set, ignore, FloatRegisterSet()); + PopRegsInMask(LiveRegisterSet(set.set(), FloatRegisterSet())); } void diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index ec8fb231b1..d951ab74fe 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -296,16 +296,12 @@ class MacroAssembler : public MacroAssemblerSpecific // =============================================================== // Stack manipulation functions. - void PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet) PER_ARCH; - void PushRegsInMask(RegisterSet set); - void PushRegsInMask(GeneralRegisterSet set); + void PushRegsInMask(LiveRegisterSet set) PER_ARCH; + void PushRegsInMask(LiveGeneralRegisterSet set); - void PopRegsInMask(RegisterSet set); - void PopRegsInMask(RegisterSet set, FloatRegisterSet simdSet); - void PopRegsInMask(GeneralRegisterSet set); - void PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, - FloatRegisterSet simdSet) PER_ARCH; - void PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore); + void PopRegsInMask(LiveRegisterSet set); + void PopRegsInMask(LiveGeneralRegisterSet set); + void PopRegsInMaskIgnore(LiveRegisterSet set, LiveRegisterSet ignore) PER_ARCH; void Push(const Operand op) PER_ARCH ONLY_X86_X64; void Push(Register reg) PER_ARCH; @@ -1226,7 +1222,7 @@ class MacroAssembler : public MacroAssemblerSpecific void alignFrameForICArguments(AfterICSaveLive &aic); void restoreFrameAlignmentForICArguments(AfterICSaveLive &aic); - AfterICSaveLive icSaveLive(RegisterSet &liveRegs) { + AfterICSaveLive icSaveLive(LiveRegisterSet &liveRegs) { PushRegsInMask(liveRegs); AfterICSaveLive aic(framePushed()); alignFrameForICArguments(aic); @@ -1237,7 +1233,7 @@ class MacroAssembler : public MacroAssemblerSpecific return buildOOLFakeExitFrame(fakeReturnAddr); } - void icRestoreLive(RegisterSet &liveRegs, AfterICSaveLive &aic) { + void icRestoreLive(LiveRegisterSet &liveRegs, AfterICSaveLive &aic) { restoreFrameAlignmentForICArguments(aic); MOZ_ASSERT(framePushed() == aic.initialStack); PopRegsInMask(liveRegs); diff --git a/js/src/jit/MoveEmitter.h b/js/src/jit/MoveEmitter.h index a86b5c1fad..4264c930ed 100644 --- a/js/src/jit/MoveEmitter.h +++ b/js/src/jit/MoveEmitter.h @@ -8,7 +8,7 @@ #define jit_MoveEmitter_h #if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64) -# include "jit/shared/MoveEmitter-x86-shared.h" +# include "jit/x86-shared/MoveEmitter-x86-shared.h" #elif defined(JS_CODEGEN_ARM) # include "jit/arm/MoveEmitter-arm.h" #elif defined(JS_CODEGEN_MIPS) diff --git a/js/src/jit/RegisterAllocator.cpp b/js/src/jit/RegisterAllocator.cpp index 8b67c3f215..decbb935f2 100644 --- a/js/src/jit/RegisterAllocator.cpp +++ b/js/src/jit/RegisterAllocator.cpp @@ -144,8 +144,8 @@ AllocationIntegrityState::check(bool populateSafepoints) return false; } MOZ_ASSERT_IF(ins->isCall() && !populateSafepoints, - safepoint->liveRegs().empty(true) && - safepoint->liveRegs().empty(false)); + safepoint->liveRegs().emptyFloat() && + safepoint->liveRegs().emptyGeneral()); } size_t inputIndex = 0; diff --git a/js/src/jit/RegisterAllocator.h b/js/src/jit/RegisterAllocator.h index f8ca60d45d..1deb29f6ed 100644 --- a/js/src/jit/RegisterAllocator.h +++ b/js/src/jit/RegisterAllocator.h @@ -265,7 +265,7 @@ class RegisterAllocator LIRGraph& graph; // Pool of all registers that should be considered allocateable - RegisterSet allRegisters_; + AllocatableRegisterSet allRegisters_; // Computed data InstructionDataMap insData; diff --git a/js/src/jit/RegisterSets.h b/js/src/jit/RegisterSets.h index 216675da30..ca4be79697 100644 --- a/js/src/jit/RegisterSets.h +++ b/js/src/jit/RegisterSets.h @@ -323,9 +323,12 @@ struct Int32Key { template class TypedRegisterSet { + public: + typedef T RegType; typedef typename T::SetType SetType; - SetType bits_; + private: + SetType bits_; public: explicit MOZ_CONSTEXPR TypedRegisterSet(SetType bits) @@ -367,96 +370,33 @@ class TypedRegisterSet static inline TypedRegisterSet NonVolatile() { return TypedRegisterSet(T::Codes::AllocatableMask & T::Codes::NonVolatileMask); } - bool has(T reg) const { - // When checking to see if a set has a register, we only want that exact - // register, not worrying about aliasing. - return !!(bits_ & (SetType(1) << reg.code())); - } - void addUnchecked(T reg) { - bits_ |= (SetType(1) << reg.code()); - } - void addAllAliasedUnchecked(T reg) { - for (uint32_t a = 0; a < reg.numAliased(); a++) { - T tmp; - reg.aliased(a, &tmp); - bits_ |= (SetType(1) << tmp.code()); - } - } - void add(T reg) { - // Make sure we don't add two overlapping registers. -#ifdef DEBUG - for (uint32_t a = 0; a < reg.numAliased(); a++) { - T tmp; - reg.aliased(a, &tmp); - MOZ_ASSERT(!has(tmp)); - } -#endif - addUnchecked(reg); - } - - void add(ValueOperand value) { -#if defined(JS_NUNBOX32) - add(value.payloadReg()); - add(value.typeReg()); -#elif defined(JS_PUNBOX64) - add(value.valueReg()); -#else -#error "Bad architecture" -#endif - } - // Determine if some register are still allocated. This function should - // be used with the set of allocatable registers used for the initialization - // of the current set. - bool someAllocated(const TypedRegisterSet &allocatable) const { - return allocatable.bits_ & ~bits_; - } bool empty() const { return !bits_; } - void take(T reg) { - MOZ_ASSERT(has(reg)); - takeUnchecked(reg); + + bool hasRegisterIndex(T reg) const { + return !!(bits_ & (SetType(1) << reg.code())); } - void takeUnchecked(T reg) { + bool hasAllocatable(T reg) const { + return !(~bits_ & reg.alignedOrDominatedAliasedSet()); + } + + void addRegisterIndex(T reg) { + bits_ |= (SetType(1) << reg.code()); + } + void addAllocatable(T reg) { + bits_ |= reg.alignedOrDominatedAliasedSet(); + } + + + void takeRegisterIndex(T reg) { bits_ &= ~(SetType(1) << reg.code()); } - void takeAllAliasedUnchecked(T reg) { - for (uint32_t a = 0; a < reg.numAliased(); a++) { - T tmp; - reg.aliased(a, &tmp); - takeUnchecked(tmp); - } - } - void take(ValueOperand value) { -#if defined(JS_NUNBOX32) - take(value.payloadReg()); - take(value.typeReg()); -#elif defined(JS_PUNBOX64) - take(value.valueReg()); -#else -#error "Bad architecture" -#endif - } - void takeUnchecked(ValueOperand value) { -#if defined(JS_NUNBOX32) - takeUnchecked(value.payloadReg()); - takeUnchecked(value.typeReg()); -#elif defined(JS_PUNBOX64) - takeUnchecked(value.valueReg()); -#else -#error "Bad architecture" -#endif - } - ValueOperand takeValueOperand() { -#if defined(JS_NUNBOX32) - return ValueOperand(takeAny(), takeAny()); -#elif defined(JS_PUNBOX64) - return ValueOperand(takeAny()); -#else -#error "Bad architecture" -#endif + void takeAllocatable(T reg) { + bits_ &= ~reg.alignedOrDominatedAliasedSet(); } + T getAny() const { // The choice of first or last here is mostly arbitrary, as they are // about the same speed on popular architectures. We choose first, as @@ -465,17 +405,6 @@ class TypedRegisterSet // EAX on x86). return getFirst(); } - T getAnyExcluding(T preclude) { - MOZ_ASSERT(!empty()); - if (!has(preclude)) - return getAny(); - - take(preclude); - MOZ_ASSERT(!empty()); - T result = getAny(); - add(preclude); - return result; - } T getFirst() const { MOZ_ASSERT(!empty()); return T::FromCode(T::FirstBit(bits_)); @@ -485,56 +414,7 @@ class TypedRegisterSet int ireg = T::LastBit(bits_); return T::FromCode(ireg); } - T takeAny() { - MOZ_ASSERT(!empty()); - T reg = getAny(); - takeAllAliasedUnchecked(reg); - return reg; - } - T takeUnaliasedAny() { - // This variant is used by LinearScan for iterating over all registers. - MOZ_ASSERT(!empty()); - T reg = getAny(); - takeUnchecked(reg); - return reg; - } - T takeAnyExcluding(T preclude) { - T reg = getAnyExcluding(preclude); - takeAllAliasedUnchecked(reg); - return reg; - } - ValueOperand takeAnyValue() { -#if defined(JS_NUNBOX32) - T type = takeAny(); - T payload = takeAny(); - return ValueOperand(type, payload); -#elif defined(JS_PUNBOX64) - T reg = takeAny(); - return ValueOperand(reg); -#else -#error "Bad architecture" -#endif - } - T takeFirst() { - // This function is used to implement a forward register set iterator. - MOZ_ASSERT(!empty()); - T reg = getFirst(); - // The iterator is used by PushRegsInMask which might be called with - // AllAlllocatableRegister mask. To avoid saving more than needed we - // should take aliased registers too. - takeAllAliasedUnchecked(reg); - return reg; - } - T takeLast() { - // This function is used to implement a backward register set iterator. - MOZ_ASSERT(!empty()); - T reg = getLast(); - takeAllAliasedUnchecked(reg); - return reg; - } - void clear() { - bits_ = 0; - } + SetType bits() const { return bits_; } @@ -592,27 +472,473 @@ class RegisterSet { static inline RegisterSet Volatile() { return RegisterSet(GeneralRegisterSet::Volatile(), FloatRegisterSet::Volatile()); } + + bool empty() const { + return fpu_.empty() && gpr_.empty(); + } + bool emptyGeneral() const { + return gpr_.empty(); + } + bool emptyFloat() const { + return fpu_.empty(); + } + MOZ_CONSTEXPR GeneralRegisterSet gprs() const { + return gpr_; + } + GeneralRegisterSet &gprs() { + return gpr_; + } + MOZ_CONSTEXPR FloatRegisterSet fpus() const { + return fpu_; + } + FloatRegisterSet &fpus() { + return fpu_; + } + bool operator ==(const RegisterSet &other) const { + return other.gpr_ == gpr_ && other.fpu_ == fpu_; + } + +}; + +// There are 2 use cases for register sets: +// +// 1. To serve as a pool of allocatable register. This is useful for working +// on the code produced by some stub where free registers are available, or +// when we can release some registers. +// +// 2. To serve as a list of typed registers. This is useful for working with +// live registers and to manipulate them with the proper instructions. This +// is used by the register allocator to fill the Safepoints. +// +// These 2 uses cases can be used on top of 3 different backend representation +// of register sets, which are either GeneralRegisterSet, FloatRegisterSet, or +// RegisterSet (for both). These classes are used to store the bit sets to +// represent each register. +// +// Each use case defines an Accessor class, such as AllocatableSetAccessor or +// LiveSetAccessor, which is parameterized with the type of the register +// set. These accessors are in charge of manipulating the register set in a +// consistent way. +// +// The RegSetCommonInterface class is used to wrap the accessors with convenient +// shortcuts which are based on the accessors. +// +// Then, to avoid to many levels of complexity while using these interfaces, +// shortcut templates are created to make it easy to distinguish between a +// register set used for allocating registers, or a register set used for making +// a collection of allocated (live) registers. +// +// This separation exists to prevent mixing LiveSet and AllocatableSet +// manipulations of the same register set, and ensure safety while avoiding +// false positive. + +template +class AllocatableSet; + +template +class LiveSet; + +// Base accessors classes have the minimal set of raw methods to manipulate the register set +// given as parameter in a consistent manner. These methods are: +// +// - has: Returns if all the bits needed to take a register are present. +// +// - takeUnchecked: Subtracts the bits used to represent the register in the +// register set. +// +// - addUnchecked: Adds the bits used to represent the register in the +// register set. + +// The AllocatableSet accessors are used to make a pool of unused +// registers. Taking or adding registers should consider the aliasing rules of +// the architecture. For example, on ARM, the following piece of code should +// work fine, knowing that the double register |d0| is composed of float +// registers |s0| and |s1|: +// +// AllocatableFloatRegisterSet regs; +// regs.add(s0); +// regs.add(s1); +// // d0 is now available. +// regs.take(d0); +// +// These accessors are useful for allocating registers within the functions used +// to generate stubs, trampolines, and inline caches (BaselineIC, IonCache). +template +class AllocatableSetAccessors +{ + public: + typedef Set RegSet; + typedef typename RegSet::RegType RegType; + typedef typename RegSet::SetType SetType; + + protected: + RegSet set_; + + public: + AllocatableSetAccessors() : set_() {} + explicit MOZ_CONSTEXPR AllocatableSetAccessors(SetType set) : set_(set) {} + explicit MOZ_CONSTEXPR AllocatableSetAccessors(RegSet set) : set_(set) {} + + bool has(RegType reg) const { + return set_.hasAllocatable(reg); + } + + void addUnchecked(RegType reg) { + set_.addAllocatable(reg); + } + + void takeUnchecked(RegType reg) { + set_.takeAllocatable(reg); + } +}; + +// Specialization of the AllocatableSet accessors for the RegisterSet aggregate. +template <> +class AllocatableSetAccessors +{ + public: + typedef RegisterSet RegSet; + typedef AnyRegister RegType; + typedef char SetType; + + protected: + RegisterSet set_; + + public: + AllocatableSetAccessors() : set_() {} + explicit MOZ_CONSTEXPR AllocatableSetAccessors(SetType) = delete; + explicit MOZ_CONSTEXPR AllocatableSetAccessors(RegisterSet set) : set_(set) {} + bool has(Register reg) const { - return gpr_.has(reg); + return set_.gprs().hasAllocatable(reg); } bool has(FloatRegister reg) const { - return fpu_.has(reg); + return set_.fpus().hasAllocatable(reg); } + + void addUnchecked(Register reg) { + set_.gprs().addAllocatable(reg); + } + void addUnchecked(FloatRegister reg) { + set_.fpus().addAllocatable(reg); + } + + void takeUnchecked(Register reg) { + set_.gprs().takeAllocatable(reg); + } + void takeUnchecked(FloatRegister reg) { + set_.fpus().takeAllocatable(reg); + } +}; + + +// The LiveSet accessors are used to collect a list of allocated +// registers. Taking or adding a register should *not* consider the aliases, as +// we care about interpreting the registers with the correct type. For example, +// on x64, where one float registers can be interpreted as an Int32x4, a Double, +// or a Float, adding xmm0 as an Int32x4, does not make the register available +// as a Double. +// +// LiveFloatRegisterSet regs; +// regs.add(xmm0.asInt32x4()); +// regs.take(xmm0); // Assert! +// +// These accessors are useful for recording the result of a register allocator, +// such as what the Backtracking allocator do on the Safepoints. +template +class LiveSetAccessors +{ + public: + typedef Set RegSet; + typedef typename RegSet::RegType RegType; + typedef typename RegSet::SetType SetType; + + protected: + RegSet set_; + + public: + LiveSetAccessors() : set_() {} + explicit MOZ_CONSTEXPR LiveSetAccessors(SetType set) : set_(set) {} + explicit MOZ_CONSTEXPR LiveSetAccessors(RegSet set) : set_(set) {} + + bool has(RegType reg) const { + return set_.hasRegisterIndex(reg); + } + + void addUnchecked(RegType reg) { + set_.addRegisterIndex(reg); + } + + void takeUnchecked(RegType reg) { + set_.takeRegisterIndex(reg); + } +}; + +// Specialization of the LiveSet accessors for the RegisterSet aggregate. +template <> +class LiveSetAccessors +{ + public: + typedef RegisterSet RegSet; + typedef AnyRegister RegType; + typedef char SetType; + + protected: + RegisterSet set_; + + public: + LiveSetAccessors() : set_() {} + explicit MOZ_CONSTEXPR LiveSetAccessors(SetType) = delete; + explicit MOZ_CONSTEXPR LiveSetAccessors(RegisterSet set) : set_(set) {} + + bool has(Register reg) const { + return set_.gprs().hasRegisterIndex(reg); + } + bool has(FloatRegister reg) const { + return set_.fpus().hasRegisterIndex(reg); + } + + void addUnchecked(Register reg) { + set_.gprs().addRegisterIndex(reg); + } + void addUnchecked(FloatRegister reg) { + set_.fpus().addRegisterIndex(reg); + } + + void takeUnchecked(Register reg) { + set_.gprs().takeRegisterIndex(reg); + } + void takeUnchecked(FloatRegister reg) { + set_.fpus().takeRegisterIndex(reg); + } +}; + +#define DEFINE_ACCESSOR_CONSTRUCTORS_(REGSET) \ + typedef typename Parent::RegSet RegSet; \ + typedef typename Parent::RegType RegType; \ + typedef typename Parent::SetType SetType; \ + \ + MOZ_CONSTEXPR_TMPL REGSET() : Parent() {} \ + explicit MOZ_CONSTEXPR_TMPL REGSET(SetType set) : Parent(set) {} \ + explicit MOZ_CONSTEXPR_TMPL REGSET(RegSet set) : Parent(set) {} + +// This class adds checked accessors on top of the unchecked variants defined by +// AllocatableSet and LiveSet accessors. Also it defines interface which are +// specialized to the register set implementation, such as |getAny| and +// |takeAny| variants. +template +class SpecializedRegSet : public Accessors +{ + typedef Accessors Parent; + + public: + DEFINE_ACCESSOR_CONSTRUCTORS_(SpecializedRegSet) + + SetType bits() const { + return this->Parent::set_.bits(); + } + + using Parent::has; + + using Parent::addUnchecked; + void add(RegType reg) { + MOZ_ASSERT(!has(reg)); + addUnchecked(reg); + } + + using Parent::takeUnchecked; + void take(RegType reg) { + MOZ_ASSERT(has(reg)); + takeUnchecked(reg); + } + + RegType getAny() const { + return this->Parent::set_.getAny(); + } + RegType getFirst() const { + return this->Parent::set_.getFirst(); + } + RegType getLast() const { + return this->Parent::set_.getLast(); + } + + RegType getAnyExcluding(RegType preclude) { + if (!has(preclude)) + return getAny(); + + take(preclude); + RegType result = getAny(); + add(preclude); + return result; + } + + RegType takeAny() { + RegType reg = getAny(); + take(reg); + return reg; + } + RegType takeFirst() { + RegType reg = getFirst(); + take(reg); + return reg; + } + RegType takeLast() { + RegType reg = getLast(); + take(reg); + return reg; + } + + ValueOperand takeAnyValue() { +#if defined(JS_NUNBOX32) + return ValueOperand(takeAny(), takeAny()); +#elif defined(JS_PUNBOX64) + return ValueOperand(takeAny()); +#else +#error "Bad architecture" +#endif + } + + RegType takeAnyExcluding(RegType preclude) { + RegType reg = getAnyExcluding(preclude); + take(reg); + return reg; + } +}; + +// Specialization of the accessors for the RegisterSet aggregate. +template +class SpecializedRegSet : public Accessors +{ + typedef Accessors Parent; + + public: + DEFINE_ACCESSOR_CONSTRUCTORS_(SpecializedRegSet) + + GeneralRegisterSet gprs() const { + return this->Parent::set_.gprs(); + } + GeneralRegisterSet &gprs() { + return this->Parent::set_.gprs(); + } + FloatRegisterSet fpus() const { + return this->Parent::set_.fpus(); + } + FloatRegisterSet &fpus() { + return this->Parent::set_.fpus(); + } + + bool emptyGeneral() const { + return this->Parent::set_.emptyGeneral(); + } + bool emptyFloat() const { + return this->Parent::set_.emptyFloat(); + } + + + using Parent::has; bool has(AnyRegister reg) const { return reg.isFloat() ? has(reg.fpu()) : has(reg.gpr()); } + + + using Parent::addUnchecked; + void addUnchecked(AnyRegister reg) { + if (reg.isFloat()) + addUnchecked(reg.fpu()); + else + addUnchecked(reg.gpr()); + } + void add(Register reg) { - gpr_.add(reg); + MOZ_ASSERT(!has(reg)); + addUnchecked(reg); } void add(FloatRegister reg) { - fpu_.add(reg); + MOZ_ASSERT(!has(reg)); + addUnchecked(reg); } - void add(AnyRegister any) { - if (any.isFloat()) - add(any.fpu()); + void add(AnyRegister reg) { + if (reg.isFloat()) + add(reg.fpu()); else - add(any.gpr()); + add(reg.gpr()); } + + using Parent::takeUnchecked; + void takeUnchecked(AnyRegister reg) { + if (reg.isFloat()) + takeUnchecked(reg.fpu()); + else + takeUnchecked(reg.gpr()); + } + + void take(Register reg) { + MOZ_ASSERT(has(reg)); + takeUnchecked(reg); + } + void take(FloatRegister reg) { + MOZ_ASSERT(has(reg)); + takeUnchecked(reg); + } + void take(AnyRegister reg) { + if (reg.isFloat()) + take(reg.fpu()); + else + take(reg.gpr()); + } + + Register getAnyGeneral() const { + return this->Parent::set_.gprs().getAny(); + } + FloatRegister getAnyFloat() const { + return this->Parent::set_.fpus().getAny(); + } + + Register takeAnyGeneral() { + Register reg = getAnyGeneral(); + take(reg); + return reg; + } + FloatRegister takeAnyFloat() { + FloatRegister reg = getAnyFloat(); + take(reg); + return reg; + } + ValueOperand takeAnyValue() { +#if defined(JS_NUNBOX32) + return ValueOperand(takeAnyGeneral(), takeAnyGeneral()); +#elif defined(JS_PUNBOX64) + return ValueOperand(takeAnyGeneral()); +#else +#error "Bad architecture" +#endif + } +}; + + +// Interface which is common to all register set implementations. It overloads +// |add|, |take| and |takeUnchecked| methods for types such as |ValueOperand| +// and |TypedOrValueRegister|. +template +class CommonRegSet : public SpecializedRegSet +{ + typedef SpecializedRegSet Parent; + + public: + DEFINE_ACCESSOR_CONSTRUCTORS_(CommonRegSet) + + RegSet set() const { + return this->Parent::set_; + } + RegSet &set() { + return this->Parent::set_; + } + + bool empty() const { + return this->Parent::set_.empty(); + } + + using Parent::add; void add(ValueOperand value) { #if defined(JS_NUNBOX32) add(value.payloadReg()); @@ -629,96 +955,35 @@ class RegisterSet { else if (reg.hasTyped()) add(reg.typedReg()); } - void addUnchecked(Register reg) { - gpr_.addUnchecked(reg); - } - void addUnchecked(FloatRegister reg) { - fpu_.addUnchecked(reg); - } - void addUnchecked(AnyRegister any) { - if (any.isFloat()) - addUnchecked(any.fpu()); - else - addUnchecked(any.gpr()); - } - void addAllAliasedUnchecked(const AnyRegister ®) { - if (reg.isFloat()) - fpu_.addAllAliasedUnchecked(reg.fpu()); - else - gpr_.addAllAliasedUnchecked(reg.gpr()); - } - - bool empty(bool floats) const { - return floats ? fpu_.empty() : gpr_.empty(); - } - FloatRegister takeFloat() { - return fpu_.takeAny(); - } - FloatRegister takeUnaliasedFloat() { - return fpu_.takeUnaliasedAny(); - } - Register takeGeneral() { - return gpr_.takeAny(); - } - Register takeUnaliasedGeneral() { - return gpr_.takeUnaliasedAny(); - } - ValueOperand takeValueOperand() { + using Parent::take; + void take(ValueOperand value) { #if defined(JS_NUNBOX32) - return ValueOperand(takeGeneral(), takeGeneral()); + take(value.payloadReg()); + take(value.typeReg()); #elif defined(JS_PUNBOX64) - return ValueOperand(takeGeneral()); + take(value.valueReg()); #else #error "Bad architecture" #endif } - void take(AnyRegister reg) { - if (reg.isFloat()) - fpu_.take(reg.fpu()); - else - gpr_.take(reg.gpr()); - } - void takeAllAliasedUnchecked(AnyRegister reg) { - if (reg.isFloat()) - fpu_.takeAllAliasedUnchecked(reg.fpu()); - else - gpr_.takeAllAliasedUnchecked(reg.gpr()); - } - // This function is used by LinearScan to find a free register. - AnyRegister takeUnaliasedAny(bool isFloat) { - if (isFloat) - return AnyRegister(takeUnaliasedFloat()); - return AnyRegister(takeUnaliasedGeneral()); - } - void clear() { - gpr_.clear(); - fpu_.clear(); - } - MOZ_CONSTEXPR GeneralRegisterSet gprs() const { - return gpr_; - } - MOZ_CONSTEXPR FloatRegisterSet fpus() const { - return fpu_; - } - bool operator ==(const RegisterSet &other) const { - return other.gpr_ == gpr_ && other.fpu_ == fpu_; + void take(TypedOrValueRegister reg) { + if (reg.hasValue()) + take(reg.valueReg()); + else if (reg.hasTyped()) + take(reg.typedReg()); } - void takeUnchecked(Register reg) { - gpr_.takeUnchecked(reg); - } - void takeUnchecked(FloatRegister reg) { - fpu_.takeUnchecked(reg); - } - void takeUnchecked(AnyRegister reg) { - if (reg.isFloat()) - fpu_.takeUnchecked(reg.fpu()); - else - gpr_.takeUnchecked(reg.gpr()); - } + using Parent::takeUnchecked; void takeUnchecked(ValueOperand value) { - gpr_.takeUnchecked(value); +#if defined(JS_NUNBOX32) + takeUnchecked(value.payloadReg()); + takeUnchecked(value.typeReg()); +#elif defined(JS_PUNBOX64) + takeUnchecked(value.valueReg()); +#else +#error "Bad architecture" +#endif } void takeUnchecked(TypedOrValueRegister reg) { if (reg.hasValue()) @@ -728,17 +993,101 @@ class RegisterSet { } }; + +// These classes do not provide any additional members, they only use their +// constructors to forward to the common interface for all register sets. The +// only benefit of these classes is to provide user friendly names. +template +class LiveSet : public CommonRegSet, Set> +{ + typedef CommonRegSet, Set> Parent; + + public: + DEFINE_ACCESSOR_CONSTRUCTORS_(LiveSet) +}; + +template +class AllocatableSet : public CommonRegSet, Set> +{ + typedef CommonRegSet, Set> Parent; + + public: + DEFINE_ACCESSOR_CONSTRUCTORS_(AllocatableSet) + + LiveSet asLiveSet() const { + return LiveSet(this->set()); + } +}; + +#define DEFINE_ACCESSOR_CONSTRUCTORS_FOR_REGISTERSET_(REGSET) \ + typedef Parent::RegSet RegSet; \ + typedef Parent::RegType RegType; \ + typedef Parent::SetType SetType; \ + \ + MOZ_CONSTEXPR_TMPL REGSET() : Parent() {} \ + explicit MOZ_CONSTEXPR_TMPL REGSET(SetType) = delete; \ + explicit MOZ_CONSTEXPR_TMPL REGSET(RegSet set) : Parent(set) {} \ + MOZ_CONSTEXPR_TMPL REGSET(GeneralRegisterSet gpr, FloatRegisterSet fpu) \ + : Parent(RegisterSet(gpr, fpu)) \ + {} \ + REGSET(REGSET gpr, REGSET fpu) \ + : Parent(RegisterSet(gpr.set(), fpu.set())) \ + {} + +template <> +class LiveSet + : public CommonRegSet, RegisterSet> +{ + // Note: We have to provide a qualified name for LiveSetAccessors, as it is + // interpreted as being the specialized class name inherited from the parent + // class specialization. + typedef CommonRegSet, RegisterSet> Parent; + + public: + DEFINE_ACCESSOR_CONSTRUCTORS_FOR_REGISTERSET_(LiveSet) +}; + +template <> +class AllocatableSet + : public CommonRegSet, RegisterSet> +{ + // Note: We have to provide a qualified name for AllocatableSetAccessors, as + // it is interpreted as being the specialized class name inherited from the + // parent class specialization. + typedef CommonRegSet, RegisterSet> Parent; + + public: + DEFINE_ACCESSOR_CONSTRUCTORS_FOR_REGISTERSET_(AllocatableSet) + + LiveSet asLiveSet() const { + return LiveSet(this->set()); + } +}; + +#undef DEFINE_ACCESSOR_CONSTRUCTORS_FOR_REGISTERSET_ +#undef DEFINE_ACCESSOR_CONSTRUCTORS_ + +typedef AllocatableSet AllocatableGeneralRegisterSet; +typedef AllocatableSet AllocatableFloatRegisterSet; +typedef AllocatableSet AllocatableRegisterSet; + +typedef LiveSet LiveGeneralRegisterSet; +typedef LiveSet LiveFloatRegisterSet; +typedef LiveSet LiveRegisterSet; + // iterates in whatever order happens to be convenient. // Use TypedRegisterBackwardIterator or TypedRegisterForwardIterator if a // specific order is required. template class TypedRegisterIterator { - TypedRegisterSet regset_; + LiveSet> regset_; public: explicit TypedRegisterIterator(TypedRegisterSet regset) : regset_(regset) { } + explicit TypedRegisterIterator(LiveSet> regset) : regset_(regset) + { } TypedRegisterIterator(const TypedRegisterIterator &other) : regset_(other.regset_) { } @@ -763,11 +1112,13 @@ class TypedRegisterIterator template class TypedRegisterBackwardIterator { - TypedRegisterSet regset_; + LiveSet> regset_; public: explicit TypedRegisterBackwardIterator(TypedRegisterSet regset) : regset_(regset) { } + explicit TypedRegisterBackwardIterator(LiveSet> regset) : regset_(regset) + { } TypedRegisterBackwardIterator(const TypedRegisterBackwardIterator &other) : regset_(other.regset_) { } @@ -793,11 +1144,13 @@ class TypedRegisterBackwardIterator template class TypedRegisterForwardIterator { - TypedRegisterSet regset_; + LiveSet> regset_; public: explicit TypedRegisterForwardIterator(TypedRegisterSet regset) : regset_(regset) { } + explicit TypedRegisterForwardIterator(LiveSet> regset) : regset_(regset) + { } TypedRegisterForwardIterator(const TypedRegisterForwardIterator &other) : regset_(other.regset_) { } @@ -840,6 +1193,9 @@ class AnyRegisterIterator explicit AnyRegisterIterator(const RegisterSet &set) : geniter_(set.gpr_), floatiter_(set.fpu_) { } + explicit AnyRegisterIterator(const LiveSet &set) + : geniter_(set.gprs()), floatiter_(set.fpus()) + { } AnyRegisterIterator(const AnyRegisterIterator &other) : geniter_(other.geniter_), floatiter_(other.floatiter_) { } @@ -892,10 +1248,10 @@ class ABIArg // Get the set of registers which should be saved by a block of code which // clobbers all registers besides |unused|, but does not clobber floating point // registers. -inline GeneralRegisterSet -SavedNonVolatileRegisters(GeneralRegisterSet unused) +inline LiveGeneralRegisterSet +SavedNonVolatileRegisters(AllocatableGeneralRegisterSet unused) { - GeneralRegisterSet result; + LiveGeneralRegisterSet result; for (GeneralRegisterIterator iter(GeneralRegisterSet::NonVolatile()); iter.more(); iter++) { Register reg = *iter; diff --git a/js/src/jit/Registers.h b/js/src/jit/Registers.h index cc895ef227..b4b7e587df 100644 --- a/js/src/jit/Registers.h +++ b/js/src/jit/Registers.h @@ -10,10 +10,8 @@ #include "mozilla/Array.h" #include "jit/IonTypes.h" -#if defined(JS_CODEGEN_X86) -# include "jit/x86/Architecture-x86.h" -#elif defined(JS_CODEGEN_X64) -# include "jit/x64/Architecture-x64.h" +#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64) +# include "jit/x86-shared/Architecture-x86-shared.h" #elif defined(JS_CODEGEN_ARM) # include "jit/arm/Architecture-arm.h" #elif defined(JS_CODEGEN_MIPS) @@ -73,6 +71,11 @@ struct Register { MOZ_ASSERT(aliasIdx == 0); *ret = *this; } + + SetType alignedOrDominatedAliasedSet() const { + return SetType(1) << code_; + } + static uint32_t SetSize(SetType x) { return Codes::SetSize(x); } diff --git a/js/src/jit/Safepoints.cpp b/js/src/jit/Safepoints.cpp index 44b26f29da..3aec50a222 100644 --- a/js/src/jit/Safepoints.cpp +++ b/js/src/jit/Safepoints.cpp @@ -88,11 +88,11 @@ ReadFloatRegisterMask(CompactBufferReader& stream) void SafepointWriter::writeGcRegs(LSafepoint* safepoint) { - GeneralRegisterSet gc = safepoint->gcRegs(); - GeneralRegisterSet spilledGpr = safepoint->liveRegs().gprs(); - FloatRegisterSet spilledFloat = safepoint->liveRegs().fpus(); - GeneralRegisterSet slots = safepoint->slotsOrElementsRegs(); - GeneralRegisterSet valueRegs; + LiveGeneralRegisterSet gc(safepoint->gcRegs()); + LiveGeneralRegisterSet spilledGpr(safepoint->liveRegs().gprs()); + LiveFloatRegisterSet spilledFloat(safepoint->liveRegs().fpus()); + LiveGeneralRegisterSet slots(safepoint->slotsOrElementsRegs()); + LiveGeneralRegisterSet valueRegs; WriteRegisterMask(stream_, spilledGpr.bits()); if (!spilledGpr.empty()) { diff --git a/js/src/jit/Safepoints.h b/js/src/jit/Safepoints.h index d6d0cd6c79..3081137cbb 100644 --- a/js/src/jit/Safepoints.h +++ b/js/src/jit/Safepoints.h @@ -92,20 +92,20 @@ class SafepointReader uint32_t osiCallPointOffset() const { return osiCallPointOffset_; } - GeneralRegisterSet gcSpills() const { - return gcSpills_; + LiveGeneralRegisterSet gcSpills() const { + return LiveGeneralRegisterSet(gcSpills_); } - GeneralRegisterSet slotsOrElementsSpills() const { - return slotsOrElementsSpills_; + LiveGeneralRegisterSet slotsOrElementsSpills() const { + return LiveGeneralRegisterSet(slotsOrElementsSpills_); } - GeneralRegisterSet valueSpills() const { - return valueSpills_; + LiveGeneralRegisterSet valueSpills() const { + return LiveGeneralRegisterSet(valueSpills_); } - GeneralRegisterSet allGprSpills() const { - return allGprSpills_; + LiveGeneralRegisterSet allGprSpills() const { + return LiveGeneralRegisterSet(allGprSpills_); } - FloatRegisterSet allFloatSpills() const { - return allFloatSpills_; + LiveFloatRegisterSet allFloatSpills() const { + return LiveFloatRegisterSet(allFloatSpills_); } uint32_t osiReturnPointOffset() const; diff --git a/js/src/jit/StupidAllocator.cpp b/js/src/jit/StupidAllocator.cpp index f32a5b032f..5a8a5d9e95 100644 --- a/js/src/jit/StupidAllocator.cpp +++ b/js/src/jit/StupidAllocator.cpp @@ -76,12 +76,12 @@ StupidAllocator::init() // Assign physical registers to the tracked allocation. { registerCount = 0; - RegisterSet remainingRegisters(allRegisters_); - while (!remainingRegisters.empty(/* float = */ false)) - registers[registerCount++].reg = AnyRegister(remainingRegisters.takeUnaliasedGeneral()); + LiveRegisterSet remainingRegisters(allRegisters_.asLiveSet()); + while (!remainingRegisters.emptyGeneral()) + registers[registerCount++].reg = AnyRegister(remainingRegisters.takeAnyGeneral()); - while (!remainingRegisters.empty(/* float = */ true)) - registers[registerCount++].reg = AnyRegister(remainingRegisters.takeUnaliasedFloat()); + while (!remainingRegisters.emptyFloat()) + registers[registerCount++].reg = AnyRegister(remainingRegisters.takeAnyFloat()); MOZ_ASSERT(registerCount <= MAX_REGISTERS); } diff --git a/js/src/jit/TypePolicy.cpp b/js/src/jit/TypePolicy.cpp index 6a6196961a..07f0ec3183 100644 --- a/js/src/jit/TypePolicy.cpp +++ b/js/src/jit/TypePolicy.cpp @@ -64,7 +64,7 @@ BoxInputsPolicy::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins) } bool -ArithPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins) +ArithPolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins) { MIRType specialization = ins->typePolicySpecialization(); if (specialization == MIRType_None) @@ -757,18 +757,18 @@ MaybeSimdUnbox(TempAllocator &alloc, MInstruction *ins, MIRType type, unsigned o template bool -SimdSameAsReturnedTypePolicy::staticAdjustInputs(TempAllocator &alloc, MInstruction *ins) +SimdSameAsReturnedTypePolicy::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins) { return MaybeSimdUnbox(alloc, ins, ins->type(), Op); } template bool -SimdSameAsReturnedTypePolicy<0>::staticAdjustInputs(TempAllocator &alloc, MInstruction *ins); +SimdSameAsReturnedTypePolicy<0>::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins); template bool -SimdSameAsReturnedTypePolicy<1>::staticAdjustInputs(TempAllocator &alloc, MInstruction *ins); +SimdSameAsReturnedTypePolicy<1>::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins); bool -SimdAllPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins) +SimdAllPolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins) { MIRType specialization = ins->typePolicySpecialization(); for (unsigned i = 0, e = ins->numOperands(); i < e; i++) { @@ -780,20 +780,20 @@ SimdAllPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins) template bool -SimdPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins) +SimdPolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins) { return MaybeSimdUnbox(alloc, ins, ins->typePolicySpecialization(), Op); } template bool -SimdPolicy<0>::adjustInputs(TempAllocator &alloc, MInstruction *ins); +SimdPolicy<0>::adjustInputs(TempAllocator& alloc, MInstruction* ins); bool -SimdShufflePolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins) +SimdShufflePolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins) { MIRType specialization = ins->typePolicySpecialization(); - MSimdGeneralShuffle *s = ins->toSimdGeneralShuffle(); + MSimdGeneralShuffle* s = ins->toSimdGeneralShuffle(); for (unsigned i = 0; i < s->numVectors(); i++) { if (!MaybeSimdUnbox(alloc, ins, specialization, i)) @@ -802,11 +802,11 @@ SimdShufflePolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins) // Next inputs are the lanes, which need to be int32 for (unsigned i = 0; i < s->numLanes(); i++) { - MDefinition *in = ins->getOperand(s->numVectors() + i); + MDefinition* in = ins->getOperand(s->numVectors() + i); if (in->type() == MIRType_Int32) continue; - MInstruction *replace = MToInt32::New(alloc, in, MacroAssembler::IntConversion_NumbersOnly); + MInstruction* replace = MToInt32::New(alloc, in, MacroAssembler::IntConversion_NumbersOnly); ins->block()->insertBefore(ins, replace); ins->replaceOperand(s->numVectors() + i, replace); if (!replace->typePolicy()->adjustInputs(alloc, replace)) @@ -817,7 +817,7 @@ SimdShufflePolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins) } bool -SimdSelectPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins) +SimdSelectPolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins) { MIRType specialization = ins->typePolicySpecialization(); @@ -882,15 +882,15 @@ InstanceOfPolicy::adjustInputs(TempAllocator& alloc, MInstruction* def) } bool -StoreUnboxedScalarPolicy::adjustValueInput(TempAllocator &alloc, MInstruction *ins, - Scalar::Type writeType, MDefinition *value, +StoreUnboxedScalarPolicy::adjustValueInput(TempAllocator& alloc, MInstruction* ins, + Scalar::Type writeType, MDefinition* value, int valueOperand) { // Storing a SIMD value just implies that we might need a SimdUnbox. if (Scalar::isSimdType(writeType)) return MaybeSimdUnbox(alloc, ins, ScalarTypeToMIRType(writeType), valueOperand); - MDefinition *curValue = value; + MDefinition* curValue = value; // First, ensure the value is int32, boolean, double or Value. // The conversion is based on TypedArrayObjectTemplate::setElementTail. switch (value->type()) { @@ -969,11 +969,11 @@ StoreUnboxedScalarPolicy::adjustValueInput(TempAllocator &alloc, MInstruction *i } bool -StoreUnboxedScalarPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins) +StoreUnboxedScalarPolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins) { SingleObjectPolicy::staticAdjustInputs(alloc, ins); - MStoreUnboxedScalar *store = ins->toStoreUnboxedScalar(); + MStoreUnboxedScalar* store = ins->toStoreUnboxedScalar(); MOZ_ASSERT(IsValidElementsType(store->elements(), store->offsetAdjustment())); MOZ_ASSERT(store->index()->type() == MIRType_Int32); diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 9f27704cf5..618ed71858 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -434,7 +434,6 @@ bool SetProperty(JSContext* cx, HandleObject obj, HandlePropertyName name, HandleValue value, bool strict, jsbytecode* pc) { - RootedValue v(cx, value); RootedId id(cx, NameToId(name)); JSOp op = JSOp(*pc); @@ -448,21 +447,21 @@ SetProperty(JSContext* cx, HandleObject obj, HandlePropertyName name, HandleValu return true; } + RootedValue receiver(cx, ObjectValue(*obj)); ObjectOpResult result; if (MOZ_LIKELY(!obj->getOps()->setProperty)) { if (!NativeSetProperty( - cx, obj.as(), obj.as(), id, + cx, obj.as(), id, value, receiver, (op == JSOP_SETNAME || op == JSOP_STRICTSETNAME || op == JSOP_SETGNAME || op == JSOP_STRICTSETGNAME) ? Unqualified : Qualified, - &v, result)) { return false; } } else { - if (!SetProperty(cx, obj, obj, id, &v, result)) + if (!SetProperty(cx, obj, id, value, receiver, result)) return false; } return result.checkStrictErrorOrWarning(cx, obj, id, strict); diff --git a/js/src/jit/arm/Architecture-arm.cpp b/js/src/jit/arm/Architecture-arm.cpp index 70e4752e96..57c7c60299 100644 --- a/js/src/jit/arm/Architecture-arm.cpp +++ b/js/src/jit/arm/Architecture-arm.cpp @@ -347,8 +347,8 @@ FloatRegisters::FromName(const char* name) FloatRegisterSet VFPRegister::ReduceSetForPush(const FloatRegisterSet& s) { - FloatRegisterSet mod; - for (TypedRegisterIterator iter(s); iter.more(); iter++) { + LiveFloatRegisterSet mod; + for (FloatRegisterIterator iter(s); iter.more(); iter++) { if ((*iter).isSingle()) { // Add in just this float. mod.addUnchecked(*iter); @@ -361,7 +361,7 @@ VFPRegister::ReduceSetForPush(const FloatRegisterSet& s) mod.addUnchecked(*iter); } } - return mod; + return mod.set(); } uint32_t diff --git a/js/src/jit/arm/Architecture-arm.h b/js/src/jit/arm/Architecture-arm.h index fcb94cd952..52ebcecabc 100644 --- a/js/src/jit/arm/Architecture-arm.h +++ b/js/src/jit/arm/Architecture-arm.h @@ -247,14 +247,14 @@ class FloatRegisters double d; }; - static const char *GetDoubleName(Code code) { + static const char* GetDoubleName(Code code) { static const char * const Names[] = { "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"}; return Names[code]; } - static const char *GetSingleName(Code code) { + static const char* GetSingleName(Code code) { static const char * const Names[] = { "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", @@ -516,7 +516,37 @@ class VFPRegister *ret = doubleOverlay(aliasIdx - 1); return; } + typedef FloatRegisters::SetType SetType; + + // This function is used to ensure that Register set can take all Single + // registers, even if we are taking a mix of either double or single + // registers. + // + // s0.alignedOrDominatedAliasedSet() == s0 | d0. + // s1.alignedOrDominatedAliasedSet() == s1. + // d0.alignedOrDominatedAliasedSet() == s0 | s1 | d0. + // + // This way the Allocator register set does not have to do any arithmetics + // to know if a register is available or not, as we have the following + // relations: + // + // d0.alignedOrDominatedAliasedSet() == + // s0.alignedOrDominatedAliasedSet() | s1.alignedOrDominatedAliasedSet() + // + // s0.alignedOrDominatedAliasedSet() & s1.alignedOrDominatedAliasedSet() == 0 + // + SetType alignedOrDominatedAliasedSet() const { + if (isSingle()) { + if (code_ % 2 != 0) + return SetType(1) << code_; + return (SetType(1) << code_) | (SetType(1) << (32 + code_ / 2)); + } + + MOZ_ASSERT(isDouble()); + return (SetType(0b11) << (code_ * 2)) | (SetType(1) << (32 + code_)); + } + static uint32_t SetSize(SetType x) { static_assert(sizeof(SetType) == 8, "SetType must be 64 bits"); return mozilla::CountPopulation32(x); diff --git a/js/src/jit/arm/BaselineIC-arm.cpp b/js/src/jit/arm/BaselineIC-arm.cpp index 431ebd5c58..91153b1ae0 100644 --- a/js/src/jit/arm/BaselineIC-arm.cpp +++ b/js/src/jit/arm/BaselineIC-arm.cpp @@ -86,8 +86,8 @@ ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm) Register scratchReg = R2.payloadReg(); // DIV and MOD need an extra non-volatile ValueOperand to hold R0. - GeneralRegisterSet savedRegs = availableGeneralRegs(2); - savedRegs = GeneralRegisterSet::Intersect(GeneralRegisterSet::NonVolatile(), savedRegs); + AllocatableGeneralRegisterSet savedRegs(availableGeneralRegs(2)); + savedRegs.set() = GeneralRegisterSet::Intersect(GeneralRegisterSet::NonVolatile(), savedRegs.set()); ValueOperand savedValue = savedRegs.takeAnyValue(); Label maybeNegZero, revertRegister; diff --git a/js/src/jit/arm/Lowering-arm.cpp b/js/src/jit/arm/Lowering-arm.cpp index 0647ede8fd..645809012c 100644 --- a/js/src/jit/arm/Lowering-arm.cpp +++ b/js/src/jit/arm/Lowering-arm.cpp @@ -18,7 +18,7 @@ using namespace js::jit; using mozilla::FloorLog2; void -LIRGeneratorARM::useBoxFixed(LInstruction *lir, size_t n, MDefinition *mir, Register reg1, +LIRGeneratorARM::useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register reg2) { MOZ_ASSERT(mir->type() == MIRType_Value); diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index f8271ba923..d42a158986 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -5017,9 +5017,8 @@ MacroAssemblerARMCompat::asMasm() const // Stack manipulation functions. void -MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet) +MacroAssembler::PushRegsInMask(LiveRegisterSet set) { - MOZ_ASSERT(!SupportsSimd() && simdSet.size() == 0); int32_t diffF = set.fpus().getPushSizeInBytes(); int32_t diffG = set.gprs().size() * sizeof(intptr_t); @@ -5046,9 +5045,8 @@ MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet) } void -MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRegisterSet simdSet) +MacroAssembler::PopRegsInMaskIgnore(LiveRegisterSet set, LiveRegisterSet ignore) { - MOZ_ASSERT(!SupportsSimd() && simdSet.size() == 0); int32_t diffG = set.gprs().size() * sizeof(intptr_t); int32_t diffF = set.fpus().getPushSizeInBytes(); const int32_t reservedG = diffG; @@ -5056,12 +5054,12 @@ MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRe // ARM can load multiple registers at once, but only if we want back all // the registers we previously saved to the stack. - if (ignore.empty(true)) { + if (ignore.emptyFloat()) { diffF -= transferMultipleByRuns(set.fpus(), IsLoad, StackPointer, IA); adjustFrame(-reservedF); } else { - TypedRegisterSet fpset = set.fpus().reduceSetForPush(); - TypedRegisterSet fpignore = ignore.fpus().reduceSetForPush(); + LiveFloatRegisterSet fpset(set.fpus().reduceSetForPush()); + LiveFloatRegisterSet fpignore(ignore.fpus().reduceSetForPush()); for (FloatRegisterBackwardIterator iter(fpset); iter.more(); iter++) { diffF -= (*iter).size(); if (!fpignore.has(*iter)) @@ -5071,7 +5069,7 @@ MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRe } MOZ_ASSERT(diffF == 0); - if (set.gprs().size() > 1 && ignore.empty(false)) { + if (set.gprs().size() > 1 && ignore.emptyGeneral()) { startDataTransferM(IsLoad, StackPointer, IA, WriteBack); for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) { diffG -= sizeof(intptr_t); diff --git a/js/src/jit/arm/MoveEmitter-arm.cpp b/js/src/jit/arm/MoveEmitter-arm.cpp index 65240fa5fb..df054c8217 100644 --- a/js/src/jit/arm/MoveEmitter-arm.cpp +++ b/js/src/jit/arm/MoveEmitter-arm.cpp @@ -9,7 +9,7 @@ using namespace js; using namespace js::jit; -MoveEmitterARM::MoveEmitterARM(MacroAssembler &masm) +MoveEmitterARM::MoveEmitterARM(MacroAssembler& masm) : inCycle_(0), masm(masm), pushedAtCycle_(-1), diff --git a/js/src/jit/arm/MoveEmitter-arm.h b/js/src/jit/arm/MoveEmitter-arm.h index 79ea6d73f6..eb2957b833 100644 --- a/js/src/jit/arm/MoveEmitter-arm.h +++ b/js/src/jit/arm/MoveEmitter-arm.h @@ -18,7 +18,7 @@ class CodeGenerator; class MoveEmitterARM { uint32_t inCycle_; - MacroAssembler &masm; + MacroAssembler& masm; // Original stack push value. uint32_t pushedAtStart_; diff --git a/js/src/jit/arm/Trampoline-arm.cpp b/js/src/jit/arm/Trampoline-arm.cpp index 2fdd1781f3..33df7395f7 100644 --- a/js/src/jit/arm/Trampoline-arm.cpp +++ b/js/src/jit/arm/Trampoline-arm.cpp @@ -205,7 +205,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type) Label returnLabel; if (type == EnterJitBaseline) { // Handle OSR. - GeneralRegisterSet regs(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); regs.take(JSReturnOperand); regs.takeUnchecked(OsrFrameReg); regs.take(r11); @@ -725,7 +725,7 @@ JitRuntime::generateVMWrapper(JSContext* cx, const VMFunction& f) // Generate a separated code for the wrapper. MacroAssembler masm(cx); - GeneralRegisterSet regs = GeneralRegisterSet(Register::Codes::WrapperMask); + AllocatableGeneralRegisterSet regs(Register::Codes::WrapperMask); // Wrapper register set is a superset of Volatile register set. JS_STATIC_ASSERT((Register::Codes::VolatileMask & ~Register::Codes::WrapperMask) == 0); @@ -904,13 +904,13 @@ JitRuntime::generatePreBarrier(JSContext* cx, MIRType type) { MacroAssembler masm(cx); - RegisterSet save; + LiveRegisterSet save; if (cx->runtime()->jitSupportsFloatingPoint) { - save = RegisterSet(GeneralRegisterSet(Registers::VolatileMask), - FloatRegisterSet(FloatRegisters::VolatileDoubleMask)); + save.set() = RegisterSet(GeneralRegisterSet(Registers::VolatileMask), + FloatRegisterSet(FloatRegisters::VolatileDoubleMask)); } else { - save = RegisterSet(GeneralRegisterSet(Registers::VolatileMask), - FloatRegisterSet()); + save.set() = RegisterSet(GeneralRegisterSet(Registers::VolatileMask), + FloatRegisterSet()); } save.add(lr); masm.PushRegsInMask(save); diff --git a/js/src/jit/mips/Architecture-mips.cpp b/js/src/jit/mips/Architecture-mips.cpp index 5d3d435770..ec7ff204c6 100644 --- a/js/src/jit/mips/Architecture-mips.cpp +++ b/js/src/jit/mips/Architecture-mips.cpp @@ -102,8 +102,8 @@ FloatRegister::singleOverlay(unsigned int which) const FloatRegisterSet FloatRegister::ReduceSetForPush(const FloatRegisterSet& s) { - FloatRegisterSet mod; - for (TypedRegisterIterator iter(s); iter.more(); iter++) { + LiveFloatRegisterSet mod; + for (FloatRegisterIterator iter(s); iter.more(); iter++) { if ((*iter).isSingle()) { // Even for single size registers save complete double register. mod.addUnchecked((*iter).doubleOverlay()); @@ -111,7 +111,7 @@ FloatRegister::ReduceSetForPush(const FloatRegisterSet& s) mod.addUnchecked(*iter); } } - return mod; + return mod.set(); } uint32_t diff --git a/js/src/jit/mips/Architecture-mips.h b/js/src/jit/mips/Architecture-mips.h index 43372624ab..2dd853ef19 100644 --- a/js/src/jit/mips/Architecture-mips.h +++ b/js/src/jit/mips/Architecture-mips.h @@ -490,6 +490,15 @@ class FloatRegister *ret = singleOverlay(aliasIdx - 1); } typedef FloatRegisters::SetType SetType; + + SetType alignedOrDominatedAliasedSet() const { + if (isSingle()) + return SetType(1) << code_; + + MOZ_ASSERT(isDouble()); + return SetType(0b11) << code_; + } + static uint32_t SetSize(SetType x) { static_assert(sizeof(SetType) == 8, "SetType must be 64 bits"); return mozilla::CountPopulation32(x); diff --git a/js/src/jit/mips/BaselineIC-mips.cpp b/js/src/jit/mips/BaselineIC-mips.cpp index 54b0148df5..88f88480d5 100644 --- a/js/src/jit/mips/BaselineIC-mips.cpp +++ b/js/src/jit/mips/BaselineIC-mips.cpp @@ -81,8 +81,8 @@ ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm) Register scratchReg = R2.payloadReg(); // DIV and MOD need an extra non-volatile ValueOperand to hold R0. - GeneralRegisterSet savedRegs = availableGeneralRegs(2); - savedRegs = GeneralRegisterSet::Intersect(GeneralRegisterSet::NonVolatile(), savedRegs); + AllocatableGeneralRegisterSet savedRegs(availableGeneralRegs(2)); + savedRegs.set() = GeneralRegisterSet::Intersect(GeneralRegisterSet::NonVolatile(), savedRegs.set()); Label goodMul, divTest1, divTest2; switch(op_) { diff --git a/js/src/jit/mips/Lowering-mips.cpp b/js/src/jit/mips/Lowering-mips.cpp index 13bee92d68..5b0dd58bc1 100644 --- a/js/src/jit/mips/Lowering-mips.cpp +++ b/js/src/jit/mips/Lowering-mips.cpp @@ -19,7 +19,7 @@ using namespace js::jit; using mozilla::FloorLog2; void -LIRGeneratorMIPS::useBoxFixed(LInstruction *lir, size_t n, MDefinition *mir, Register reg1, +LIRGeneratorMIPS::useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register reg2) { MOZ_ASSERT(mir->type() == MIRType_Value); diff --git a/js/src/jit/mips/MacroAssembler-mips.cpp b/js/src/jit/mips/MacroAssembler-mips.cpp index 673f429fce..ea9b13056d 100644 --- a/js/src/jit/mips/MacroAssembler-mips.cpp +++ b/js/src/jit/mips/MacroAssembler-mips.cpp @@ -3668,9 +3668,8 @@ MacroAssemblerMIPSCompat::asMasm() const // Stack manipulation functions. void -MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet) +MacroAssembler::PushRegsInMask(LiveRegisterSet set) { - MOZ_ASSERT(!SupportsSimd() && simdSet.size() == 0); int32_t diffF = set.fpus().getPushSizeInBytes(); int32_t diffG = set.gprs().size() * sizeof(intptr_t); @@ -3696,9 +3695,8 @@ MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet) } void -MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRegisterSet simdSet) +MacroAssembler::PopRegsInMaskIgnore(LiveRegisterSet set, LiveRegisterSet ignore) { - MOZ_ASSERT(!SupportsSimd() && simdSet.size() == 0); int32_t diffG = set.gprs().size() * sizeof(intptr_t); int32_t diffF = set.fpus().getPushSizeInBytes(); const int32_t reservedG = diffG; diff --git a/js/src/jit/mips/MoveEmitter-mips.cpp b/js/src/jit/mips/MoveEmitter-mips.cpp index 1a982c0947..70af185a8d 100644 --- a/js/src/jit/mips/MoveEmitter-mips.cpp +++ b/js/src/jit/mips/MoveEmitter-mips.cpp @@ -9,7 +9,7 @@ using namespace js; using namespace js::jit; -MoveEmitterMIPS::MoveEmitterMIPS(MacroAssembler &masm) +MoveEmitterMIPS::MoveEmitterMIPS(MacroAssembler& masm) : inCycle_(0), masm(masm), pushedAtCycle_(-1), diff --git a/js/src/jit/mips/MoveEmitter-mips.h b/js/src/jit/mips/MoveEmitter-mips.h index 2477f582e3..4ae3cb4daf 100644 --- a/js/src/jit/mips/MoveEmitter-mips.h +++ b/js/src/jit/mips/MoveEmitter-mips.h @@ -18,7 +18,7 @@ class CodeGenerator; class MoveEmitterMIPS { uint32_t inCycle_; - MacroAssembler &masm; + MacroAssembler& masm; // Original stack push value. uint32_t pushedAtStart_; diff --git a/js/src/jit/mips/Trampoline-mips.cpp b/js/src/jit/mips/Trampoline-mips.cpp index 8d56e856fe..14c08d9594 100644 --- a/js/src/jit/mips/Trampoline-mips.cpp +++ b/js/src/jit/mips/Trampoline-mips.cpp @@ -193,7 +193,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type) CodeLabel returnLabel; if (type == EnterJitBaseline) { // Handle OSR. - GeneralRegisterSet regs(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); regs.take(OsrFrameReg); regs.take(BaselineFrameReg); regs.take(reg_code); @@ -694,7 +694,7 @@ JitRuntime::generateVMWrapper(JSContext* cx, const VMFunction& f) MacroAssembler masm(cx); - GeneralRegisterSet regs = GeneralRegisterSet(Register::Codes::WrapperMask); + AllocatableGeneralRegisterSet regs(GeneralRegisterSet(Register::Codes::WrapperMask)); static_assert((Register::Codes::VolatileMask & ~Register::Codes::WrapperMask) == 0, "Wrapper register set should be a superset of Volatile register set."); @@ -895,12 +895,12 @@ JitRuntime::generatePreBarrier(JSContext* cx, MIRType type) { MacroAssembler masm(cx); - RegisterSet save; + LiveRegisterSet save; if (cx->runtime()->jitSupportsFloatingPoint) { - save = RegisterSet(GeneralRegisterSet(Registers::VolatileMask), + save.set() = RegisterSet(GeneralRegisterSet(Registers::VolatileMask), FloatRegisterSet(FloatRegisters::VolatileMask)); } else { - save = RegisterSet(GeneralRegisterSet(Registers::VolatileMask), + save.set() = RegisterSet(GeneralRegisterSet(Registers::VolatileMask), FloatRegisterSet()); } masm.PushRegsInMask(save); diff --git a/js/src/jit/none/Architecture-none.h b/js/src/jit/none/Architecture-none.h index ad68dde3e2..17ed67e324 100644 --- a/js/src/jit/none/Architecture-none.h +++ b/js/src/jit/none/Architecture-none.h @@ -122,6 +122,7 @@ struct FloatRegister uint32_t size() const { MOZ_CRASH(); } uint32_t numAlignedAliased() const { MOZ_CRASH(); } void alignedAliased(uint32_t, FloatRegister *) { MOZ_CRASH(); } + SetType alignedOrDominatedAliasedSet() const { MOZ_CRASH(); } template static T ReduceSetForPush(T) { MOZ_CRASH(); } uint32_t getRegisterDumpOffsetInBytes() { MOZ_CRASH(); } static uint32_t SetSize(SetType x) { MOZ_CRASH(); } diff --git a/js/src/jit/none/Trampoline-none.cpp b/js/src/jit/none/Trampoline-none.cpp index faaadfc2a5..c19de5b6c2 100644 --- a/js/src/jit/none/Trampoline-none.cpp +++ b/js/src/jit/none/Trampoline-none.cpp @@ -59,12 +59,8 @@ JitCode *JitRuntime::generateProfilerExitFrameTailStub(JSContext *) { MOZ_CRASH( // =============================================================== // Stack manipulation functions. -void MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet) { MOZ_CRASH(); } -void MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, - FloatRegisterSet simdSet) -{ - MOZ_CRASH(); -} +void MacroAssembler::PushRegsInMask(LiveRegisterSet) { MOZ_CRASH(); } +void MacroAssembler::PopRegsInMaskIgnore(LiveRegisterSet, LiveRegisterSet) { MOZ_CRASH(); } void MacroAssembler::Push(Register reg) { MOZ_CRASH(); } void MacroAssembler::Push(const Imm32 imm) { MOZ_CRASH(); } @@ -74,4 +70,4 @@ void MacroAssembler::Push(const ImmGCPtr ptr) { MOZ_CRASH(); } void MacroAssembler::Push(FloatRegister reg) { MOZ_CRASH(); } void MacroAssembler::Pop(Register reg) { MOZ_CRASH(); } -void MacroAssembler::Pop(const ValueOperand &val) { MOZ_CRASH(); } +void MacroAssembler::Pop(const ValueOperand& val) { MOZ_CRASH(); } diff --git a/js/src/jit/shared/CodeGenerator-shared-inl.h b/js/src/jit/shared/CodeGenerator-shared-inl.h index 589ebe0e16..252297aa22 100644 --- a/js/src/jit/shared/CodeGenerator-shared-inl.h +++ b/js/src/jit/shared/CodeGenerator-shared-inl.h @@ -159,7 +159,7 @@ CodeGeneratorShared::restoreLive(LInstruction* ins) } void -CodeGeneratorShared::restoreLiveIgnore(LInstruction *ins, RegisterSet ignore) +CodeGeneratorShared::restoreLiveIgnore(LInstruction *ins, LiveRegisterSet ignore) { MOZ_ASSERT(!ins->isCall()); LSafepoint *safepoint = ins->safepoint(); @@ -171,7 +171,8 @@ CodeGeneratorShared::saveLiveVolatile(LInstruction *ins) { MOZ_ASSERT(!ins->isCall()); LSafepoint *safepoint = ins->safepoint(); - RegisterSet regs = RegisterSet::Intersect(safepoint->liveRegs(), RegisterSet::Volatile()); + LiveRegisterSet regs; + regs.set() = RegisterSet::Intersect(safepoint->liveRegs().set(), RegisterSet::Volatile()); masm.PushRegsInMask(regs); } @@ -180,7 +181,8 @@ CodeGeneratorShared::restoreLiveVolatile(LInstruction *ins) { MOZ_ASSERT(!ins->isCall()); LSafepoint *safepoint = ins->safepoint(); - RegisterSet regs = RegisterSet::Intersect(safepoint->liveRegs(), RegisterSet::Volatile()); + LiveRegisterSet regs; + regs.set() = RegisterSet::Intersect(safepoint->liveRegs().set(), RegisterSet::Volatile()); masm.PopRegsInMask(regs); } diff --git a/js/src/jit/shared/CodeGenerator-shared.cpp b/js/src/jit/shared/CodeGenerator-shared.cpp index 23f8d044b8..1d77a51936 100644 --- a/js/src/jit/shared/CodeGenerator-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-shared.cpp @@ -1029,7 +1029,7 @@ CodeGeneratorShared::markOsiPoint(LOsiPoint* ins) #ifdef CHECK_OSIPOINT_REGISTERS template static void -HandleRegisterDump(Op op, MacroAssembler &masm, RegisterSet liveRegs, Register activation, +HandleRegisterDump(Op op, MacroAssembler &masm, LiveRegisterSet liveRegs, Register activation, Register scratch) { const size_t baseOffset = JitActivation::offsetOfRegs(); @@ -1088,14 +1088,14 @@ class StoreOp }; static void -StoreAllLiveRegs(MacroAssembler &masm, RegisterSet liveRegs) +StoreAllLiveRegs(MacroAssembler &masm, LiveRegisterSet liveRegs) { // Store a copy of all live registers before performing the call. // When we reach the OsiPoint, we can use this to check nothing // modified them in the meantime. // Load pointer to the JitActivation in a scratch register. - GeneralRegisterSet allRegs(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet allRegs(GeneralRegisterSet::All()); Register scratch = allRegs.takeAny(); masm.push(scratch); masm.loadJitActivation(scratch); @@ -1145,7 +1145,7 @@ CodeGeneratorShared::verifyOsiPointRegs(LSafepoint* safepoint) // the call and this OsiPoint. Try-catch relies on this invariant. // Load pointer to the JitActivation in a scratch register. - GeneralRegisterSet allRegs(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet allRegs(GeneralRegisterSet::All()); Register scratch = allRegs.takeAny(); masm.push(scratch); masm.loadJitActivation(scratch); @@ -1172,8 +1172,9 @@ CodeGeneratorShared::verifyOsiPointRegs(LSafepoint* safepoint) // instructions (including this OsiPoint) will depend on them. Also // backtracking can also use the same register for an input and an output. // These are marked as clobbered and shouldn't get checked. - RegisterSet liveRegs = safepoint->liveRegs(); - liveRegs = RegisterSet::Intersect(liveRegs, RegisterSet::Not(safepoint->clobberedRegs())); + LiveRegisterSet liveRegs; + liveRegs.set() = RegisterSet::Intersect(safepoint->liveRegs().set(), + RegisterSet::Not(safepoint->clobberedRegs().set())); VerifyOp op(masm, &failure); HandleRegisterDump(op, masm, liveRegs, scratch, allRegs.getAny()); @@ -1211,7 +1212,7 @@ CodeGeneratorShared::shouldVerifyOsiPointRegs(LSafepoint* safepoint) if (!checkOsiPointRegisters) return false; - if (safepoint->liveRegs().empty(true) && safepoint->liveRegs().empty(false)) + if (safepoint->liveRegs().emptyGeneral() && safepoint->liveRegs().emptyFloat()) return false; // No registers to check. return true; @@ -1225,7 +1226,7 @@ CodeGeneratorShared::resetOsiPointRegs(LSafepoint* safepoint) // Set checkRegs to 0. If we perform a VM call, the instruction // will set it to 1. - GeneralRegisterSet allRegs(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet allRegs(GeneralRegisterSet::All()); Register scratch = allRegs.takeAny(); masm.push(scratch); masm.loadJitActivation(scratch); @@ -1629,9 +1630,9 @@ CodeGeneratorShared::emitTracelogScript(bool isStart) Label done; - RegisterSet regs = RegisterSet::Volatile(); - Register logger = regs.takeGeneral(); - Register script = regs.takeGeneral(); + AllocatableRegisterSet regs(RegisterSet::Volatile()); + Register logger = regs.takeAnyGeneral(); + Register script = regs.takeAnyGeneral(); masm.Push(logger); @@ -1665,8 +1666,8 @@ CodeGeneratorShared::emitTracelogTree(bool isStart, uint32_t textId) return; Label done; - RegisterSet regs = RegisterSet::Volatile(); - Register logger = regs.takeGeneral(); + AllocatableRegisterSet regs(RegisterSet::Volatile()); + Register logger = regs.takeAnyGeneral(); masm.Push(logger); diff --git a/js/src/jit/shared/CodeGenerator-shared.h b/js/src/jit/shared/CodeGenerator-shared.h index 7cc96f6f09..022c556806 100644 --- a/js/src/jit/shared/CodeGenerator-shared.h +++ b/js/src/jit/shared/CodeGenerator-shared.h @@ -406,36 +406,36 @@ class CodeGeneratorShared : public LElementVisitor // instruction [this is purely an optimization]. All other volatiles must // be saved and restored in case future LIR instructions need those values.) void saveVolatile(Register output) { - RegisterSet regs = RegisterSet::Volatile(); + LiveRegisterSet regs(RegisterSet::Volatile()); regs.takeUnchecked(output); masm.PushRegsInMask(regs); } void restoreVolatile(Register output) { - RegisterSet regs = RegisterSet::Volatile(); + LiveRegisterSet regs(RegisterSet::Volatile()); regs.takeUnchecked(output); masm.PopRegsInMask(regs); } void saveVolatile(FloatRegister output) { - RegisterSet regs = RegisterSet::Volatile(); + LiveRegisterSet regs(RegisterSet::Volatile()); regs.takeUnchecked(output); masm.PushRegsInMask(regs); } void restoreVolatile(FloatRegister output) { - RegisterSet regs = RegisterSet::Volatile(); + LiveRegisterSet regs(RegisterSet::Volatile()); regs.takeUnchecked(output); masm.PopRegsInMask(regs); } - void saveVolatile(RegisterSet temps) { - masm.PushRegsInMask(RegisterSet::VolatileNot(temps)); + void saveVolatile(LiveRegisterSet temps) { + masm.PushRegsInMask(LiveRegisterSet(RegisterSet::VolatileNot(temps.set()))); } - void restoreVolatile(RegisterSet temps) { - masm.PopRegsInMask(RegisterSet::VolatileNot(temps)); + void restoreVolatile(LiveRegisterSet temps) { + masm.PopRegsInMask(LiveRegisterSet(RegisterSet::VolatileNot(temps.set()))); } void saveVolatile() { - masm.PushRegsInMask(RegisterSet::Volatile()); + masm.PushRegsInMask(LiveRegisterSet(RegisterSet::Volatile())); } void restoreVolatile() { - masm.PopRegsInMask(RegisterSet::Volatile()); + masm.PopRegsInMask(LiveRegisterSet(RegisterSet::Volatile())); } // These functions have to be called before and after any callVM and before @@ -444,7 +444,7 @@ class CodeGeneratorShared : public LElementVisitor // frame produced by callVM. inline void saveLive(LInstruction *ins); inline void restoreLive(LInstruction *ins); - inline void restoreLiveIgnore(LInstruction *ins, RegisterSet reg); + inline void restoreLiveIgnore(LInstruction *ins, LiveRegisterSet reg); // Save/restore all registers that are both live and volatile. inline void saveLiveVolatile(LInstruction *ins); @@ -682,8 +682,8 @@ struct StoreNothing { inline void generate(CodeGeneratorShared* codegen) const { } - inline RegisterSet clobbered() const { - return RegisterSet(); // No register gets clobbered + inline LiveRegisterSet clobbered() const { + return LiveRegisterSet(); // No register gets clobbered } }; @@ -700,8 +700,8 @@ class StoreRegisterTo inline void generate(CodeGeneratorShared* codegen) const { codegen->storeResultTo(out_); } - inline RegisterSet clobbered() const { - RegisterSet set = RegisterSet(); + inline LiveRegisterSet clobbered() const { + LiveRegisterSet set; set.add(out_); return set; } @@ -720,8 +720,8 @@ class StoreFloatRegisterTo inline void generate(CodeGeneratorShared* codegen) const { codegen->storeFloatResultTo(out_); } - inline RegisterSet clobbered() const { - RegisterSet set = RegisterSet(); + inline LiveRegisterSet clobbered() const { + LiveRegisterSet set; set.add(out_); return set; } @@ -741,8 +741,8 @@ class StoreValueTo_ inline void generate(CodeGeneratorShared* codegen) const { codegen->storeResultValueTo(out_); } - inline RegisterSet clobbered() const { - RegisterSet set = RegisterSet(); + inline LiveRegisterSet clobbered() const { + LiveRegisterSet set; set.add(out_); return set; } diff --git a/js/src/jit/x64/Assembler-x64.cpp b/js/src/jit/x64/Assembler-x64.cpp index c8821ced93..f2438bb82b 100644 --- a/js/src/jit/x64/Assembler-x64.cpp +++ b/js/src/jit/x64/Assembler-x64.cpp @@ -294,7 +294,7 @@ Assembler::CodeFromJump(JitCode* code, uint8_t* jump) } void -Assembler::TraceJumpRelocations(JSTracer *trc, JitCode *code, CompactBufferReader &reader) +Assembler::TraceJumpRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader) { RelocationIterator iter(reader); while (iter.read()) { @@ -303,50 +303,3 @@ Assembler::TraceJumpRelocations(JSTracer *trc, JitCode *code, CompactBufferReade MOZ_ASSERT(child == CodeFromJump(code, code->raw() + iter.offset())); } } - -FloatRegisterSet -FloatRegister::ReduceSetForPush(const FloatRegisterSet &s) -{ - if (JitSupportsSimd()) - return s; - - // Ignore all SIMD register. - return FloatRegisterSet(s.bits() & (Codes::AllPhysMask * Codes::SpreadScalar)); -} -uint32_t -FloatRegister::GetPushSizeInBytes(const FloatRegisterSet &s) -{ - SetType all = s.bits(); - SetType float32x4Set = - (all >> (uint32_t(Codes::Float32x4) * Codes::TotalPhys)) & Codes::AllPhysMask; - SetType int32x4Set = - (all >> (uint32_t(Codes::Int32x4) * Codes::TotalPhys)) & Codes::AllPhysMask; - SetType doubleSet = - (all >> (uint32_t(Codes::Double) * Codes::TotalPhys)) & Codes::AllPhysMask; - SetType singleSet = - (all >> (uint32_t(Codes::Single) * Codes::TotalPhys)) & Codes::AllPhysMask; - - // PushRegsInMask pushes the largest register first, and thus avoids pushing - // aliased registers. So we have to filter out the physical registers which - // are already pushed as part of larger registers. - SetType set128b = int32x4Set | float32x4Set; - SetType set64b = doubleSet & ~set128b; - SetType set32b = singleSet & ~set64b & ~set128b; - - static_assert(Codes::AllPhysMask <= 0xffff, "We can safely use CountPopulation32"); - uint32_t count32b = mozilla::CountPopulation32(set32b); - - // If we have an odd number of 32 bits values, then we increase the size to - // keep the stack aligned on 8 bytes. Note: Keep in sync with - // PushRegsInMask, and PopRegsInMaskIgnore. - count32b += count32b & 1; - - return mozilla::CountPopulation32(set128b) * (4 * sizeof(int32_t)) - + mozilla::CountPopulation32(set64b) * sizeof(double) - + count32b * sizeof(float); -} -uint32_t -FloatRegister::getRegisterDumpOffsetInBytes() -{ - return uint32_t(encoding()) * sizeof(FloatRegisters::RegisterContent); -} diff --git a/js/src/jit/x64/Assembler-x64.h b/js/src/jit/x64/Assembler-x64.h index 4b20de16ad..161a8b83e1 100644 --- a/js/src/jit/x64/Assembler-x64.h +++ b/js/src/jit/x64/Assembler-x64.h @@ -209,7 +209,7 @@ static const Scale ScalePointer = TimesEight; } // namespace jit } // namespace js -#include "jit/shared/Assembler-x86-shared.h" +#include "jit/x86-shared/Assembler-x86-shared.h" namespace js { namespace jit { diff --git a/js/src/jit/x64/BaselineCompiler-x64.h b/js/src/jit/x64/BaselineCompiler-x64.h index 9166506710..ff75f9c093 100644 --- a/js/src/jit/x64/BaselineCompiler-x64.h +++ b/js/src/jit/x64/BaselineCompiler-x64.h @@ -7,7 +7,7 @@ #ifndef jit_x64_BaselineCompiler_x64_h #define jit_x64_BaselineCompiler_x64_h -#include "jit/shared/BaselineCompiler-x86-shared.h" +#include "jit/x86-shared/BaselineCompiler-x86-shared.h" namespace js { namespace jit { diff --git a/js/src/jit/x64/CodeGenerator-x64.h b/js/src/jit/x64/CodeGenerator-x64.h index 82ef143680..9643006e63 100644 --- a/js/src/jit/x64/CodeGenerator-x64.h +++ b/js/src/jit/x64/CodeGenerator-x64.h @@ -7,7 +7,7 @@ #ifndef jit_x64_CodeGenerator_x64_h #define jit_x64_CodeGenerator_x64_h -#include "jit/shared/CodeGenerator-x86-shared.h" +#include "jit/x86-shared/CodeGenerator-x86-shared.h" namespace js { namespace jit { diff --git a/js/src/jit/x64/Lowering-x64.cpp b/js/src/jit/x64/Lowering-x64.cpp index 86c6056aa4..151c71d97b 100644 --- a/js/src/jit/x64/Lowering-x64.cpp +++ b/js/src/jit/x64/Lowering-x64.cpp @@ -15,7 +15,7 @@ using namespace js; using namespace js::jit; void -LIRGeneratorX64::useBoxFixed(LInstruction *lir, size_t n, MDefinition *mir, Register reg1, Register) +LIRGeneratorX64::useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register) { MOZ_ASSERT(mir->type() == MIRType_Value); @@ -165,9 +165,9 @@ LIRGeneratorX64::visitAsmJSLoadHeap(MAsmJSLoadHeap *ins) } void -LIRGeneratorX64::visitAsmJSStoreHeap(MAsmJSStoreHeap *ins) +LIRGeneratorX64::visitAsmJSStoreHeap(MAsmJSStoreHeap* ins) { - MDefinition *ptr = ins->ptr(); + MDefinition* ptr = ins->ptr(); MOZ_ASSERT(ptr->type() == MIRType_Int32); // For simplicity, require a register if we're going to emit a bounds-check @@ -200,24 +200,24 @@ LIRGeneratorX64::visitAsmJSStoreHeap(MAsmJSStoreHeap *ins) } void -LIRGeneratorX64::visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap *ins) +LIRGeneratorX64::visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap* ins) { - MDefinition *ptr = ins->ptr(); + MDefinition* ptr = ins->ptr(); MOZ_ASSERT(ptr->type() == MIRType_Int32); const LAllocation oldval = useRegister(ins->oldValue()); const LAllocation newval = useRegister(ins->newValue()); - LAsmJSCompareExchangeHeap *lir = + LAsmJSCompareExchangeHeap* lir = new(alloc()) LAsmJSCompareExchangeHeap(useRegister(ptr), oldval, newval); defineFixed(lir, ins, LAllocation(AnyRegister(eax))); } void -LIRGeneratorX64::visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap *ins) +LIRGeneratorX64::visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap* ins) { - MDefinition *ptr = ins->ptr(); + MDefinition* ptr = ins->ptr(); MOZ_ASSERT(ptr->type() == MIRType_Int32); // Register allocation: diff --git a/js/src/jit/x64/Lowering-x64.h b/js/src/jit/x64/Lowering-x64.h index 1d0e019651..225f7abe93 100644 --- a/js/src/jit/x64/Lowering-x64.h +++ b/js/src/jit/x64/Lowering-x64.h @@ -7,7 +7,7 @@ #ifndef jit_x64_Lowering_x64_h #define jit_x64_Lowering_x64_h -#include "jit/shared/Lowering-x86-shared.h" +#include "jit/x86-shared/Lowering-x86-shared.h" namespace js { namespace jit { diff --git a/js/src/jit/x64/MacroAssembler-x64.h b/js/src/jit/x64/MacroAssembler-x64.h index 2e3ec97ddc..b3a25ae5b7 100644 --- a/js/src/jit/x64/MacroAssembler-x64.h +++ b/js/src/jit/x64/MacroAssembler-x64.h @@ -9,7 +9,7 @@ #include "jit/JitFrames.h" #include "jit/MoveResolver.h" -#include "jit/shared/MacroAssembler-x86-shared.h" +#include "jit/x86-shared/MacroAssembler-x86-shared.h" namespace js { namespace jit { @@ -36,8 +36,8 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared { private: // Perform a downcast. Should be removed by Bug 996602. - MacroAssembler &asMasm(); - const MacroAssembler &asMasm() const; + MacroAssembler& asMasm(); + const MacroAssembler& asMasm() const; private: // Number of bytes the stack is adjusted inside a call to C. Calls to C may @@ -222,7 +222,7 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared void popValue(ValueOperand val) { pop(val.valueReg()); } - void pushValue(const Value &val) { + void pushValue(const Value& val) { jsval_layout jv = JSVAL_TO_IMPL(val); if (val.isMarkable()) { movWithPatch(ImmWord(jv.asBits), ScratchReg); diff --git a/js/src/jit/x64/Trampoline-x64.cpp b/js/src/jit/x64/Trampoline-x64.cpp index 6d54b5b8f5..f52a51025e 100644 --- a/js/src/jit/x64/Trampoline-x64.cpp +++ b/js/src/jit/x64/Trampoline-x64.cpp @@ -19,9 +19,9 @@ using namespace js::jit; // All registers to save and restore. This includes the stack pointer, since we // use the ability to reference register values on the stack by index. -static const RegisterSet AllRegs = - RegisterSet(GeneralRegisterSet(Registers::AllMask), - FloatRegisterSet(FloatRegisters::AllMask)); +static const LiveRegisterSet AllRegs = + LiveRegisterSet(GeneralRegisterSet(Registers::AllMask), + FloatRegisterSet(FloatRegisters::AllMask)); // Generates a trampoline for calling Jit compiled code from a C++ function. // The trampoline use the EnterJitCode signature, with the standard x64 fastcall @@ -150,7 +150,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type) CodeLabel returnLabel; if (type == EnterJitBaseline) { // Handle OSR. - GeneralRegisterSet regs(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); regs.takeUnchecked(OsrFrameReg); regs.take(rbp); regs.take(reg_code); @@ -516,12 +516,11 @@ PushBailoutFrame(MacroAssembler& masm, Register spArg) // the float registers to have the maximal possible size // (Simd128DataSize). To work around this, we just spill the double // registers by hand here, using the register dump offset directly. - RegisterSet set = AllRegs; - for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) + for (GeneralRegisterBackwardIterator iter(AllRegs.gprs()); iter.more(); iter++) masm.Push(*iter); masm.reserveStack(sizeof(RegisterDump::FPUArray)); - for (FloatRegisterBackwardIterator iter(set.fpus()); iter.more(); iter++) { + for (FloatRegisterBackwardIterator iter(AllRegs.fpus()); iter.more(); iter++) { FloatRegister reg = *iter; Address spillAddress(StackPointer, reg.getRegisterDumpOffsetInBytes()); masm.storeDouble(reg, spillAddress); @@ -602,7 +601,7 @@ JitRuntime::generateVMWrapper(JSContext* cx, const VMFunction& f) // Avoid conflicts with argument registers while discarding the result after // the function call. - GeneralRegisterSet regs = GeneralRegisterSet(Register::Codes::WrapperMask); + AllocatableGeneralRegisterSet regs(Register::Codes::WrapperMask); // Wrapper register set is a superset of Volatile register set. JS_STATIC_ASSERT((Register::Codes::VolatileMask & ~Register::Codes::WrapperMask) == 0); @@ -777,8 +776,9 @@ JitRuntime::generatePreBarrier(JSContext* cx, MIRType type) { MacroAssembler masm; - RegisterSet regs = RegisterSet(GeneralRegisterSet(Registers::VolatileMask), - FloatRegisterSet(FloatRegisters::VolatileMask)); + LiveRegisterSet regs = + LiveRegisterSet(GeneralRegisterSet(Registers::VolatileMask), + FloatRegisterSet(FloatRegisters::VolatileMask)); masm.PushRegsInMask(regs); MOZ_ASSERT(PreBarrierReg == rdx); diff --git a/js/src/jit/x86-shared/Architecture-x86-shared.cpp b/js/src/jit/x86-shared/Architecture-x86-shared.cpp new file mode 100644 index 0000000000..86c1a2ff2f --- /dev/null +++ b/js/src/jit/x86-shared/Architecture-x86-shared.cpp @@ -0,0 +1,98 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * 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/. */ + +#include "jit/x86-shared/Architecture-x86-shared.h" +#if !defined(JS_CODEGEN_X86) && !defined(JS_CODEGEN_X64) +# error "Wrong architecture. Only x86 and x64 should build this file!" +#endif + +const char* +FloatRegister::name() const { + static const char* const names[] = { + +#ifdef JS_CODEGEN_X64 +#define FLOAT_REGS_(TYPE) \ + "%xmm0" TYPE, "%xmm1" TYPE, "%xmm2" TYPE, "%xmm3" TYPE, \ + "%xmm4" TYPE, "%xmm5" TYPE, "%xmm6" TYPE, "%xmm7" TYPE, \ + "%xmm8" TYPE, "%xmm9" TYPE, "%xmm10" TYPE, "%xmm11" TYPE, \ + "%xmm12" TYPE, "%xmm13" TYPE, "%xmm14" TYPE, "%xmm15" TYPE +#else +#define FLOAT_REGS_(TYPE) \ + "%xmm0" TYPE, "%xmm1" TYPE, "%xmm2" TYPE, "%xmm3" TYPE, \ + "%xmm4" TYPE, "%xmm5" TYPE, "%xmm6" TYPE, "%xmm7" TYPE +#endif + + // These should be enumerated in the same order as in + // FloatRegisters::ContentType. + FLOAT_REGS_(".s"), + FLOAT_REGS_(".d"), + FLOAT_REGS_(".i4"), + FLOAT_REGS_(".s4") +#undef FLOAT_REGS_ + + }; + MOZ_ASSERT(size_t(code()) < mozilla::ArrayLength(names)); + return names[size_t(code())]; +} + +FloatRegisterSet +FloatRegister::ReduceSetForPush(const FloatRegisterSet& s) +{ + SetType bits = s.bits(); + + // Ignore all SIMD register, if not supported. + if (!JitSupportsSimd()) + bits &= Codes::AllPhysMask * Codes::SpreadScalar; + + // Exclude registers which are already pushed with a larger type. High bits + // are associated with larger register types. Thus we keep the set of + // registers which are not included in larger type. + bits &= ~(bits >> (1 * Codes::TotalPhys)); + bits &= ~(bits >> (2 * Codes::TotalPhys)); + bits &= ~(bits >> (3 * Codes::TotalPhys)); + + return FloatRegisterSet(bits); +} + +uint32_t +FloatRegister::GetPushSizeInBytes(const FloatRegisterSet& s) +{ + SetType all = s.bits(); + SetType float32x4Set = + (all >> (uint32_t(Codes::Float32x4) * Codes::TotalPhys)) & Codes::AllPhysMask; + SetType int32x4Set = + (all >> (uint32_t(Codes::Int32x4) * Codes::TotalPhys)) & Codes::AllPhysMask; + SetType doubleSet = + (all >> (uint32_t(Codes::Double) * Codes::TotalPhys)) & Codes::AllPhysMask; + SetType singleSet = + (all >> (uint32_t(Codes::Single) * Codes::TotalPhys)) & Codes::AllPhysMask; + + // PushRegsInMask pushes the largest register first, and thus avoids pushing + // aliased registers. So we have to filter out the physical registers which + // are already pushed as part of larger registers. + SetType set128b = int32x4Set | float32x4Set; + SetType set64b = doubleSet & ~set128b; + SetType set32b = singleSet & ~set64b & ~set128b; + + static_assert(Codes::AllPhysMask <= 0xffff, "We can safely use CountPopulation32"); + uint32_t count32b = mozilla::CountPopulation32(set32b); + +#if defined(JS_CODEGEN_X64) + // If we have an odd number of 32 bits values, then we increase the size to + // keep the stack aligned on 8 bytes. Note: Keep in sync with + // PushRegsInMask, and PopRegsInMaskIgnore. + count32b += count32b & 1; +#endif + + return mozilla::CountPopulation32(set128b) * (4 * sizeof(int32_t)) + + mozilla::CountPopulation32(set64b) * sizeof(double) + + count32b * sizeof(float); +} +uint32_t +FloatRegister::getRegisterDumpOffsetInBytes() +{ + return uint32_t(encoding()) * sizeof(FloatRegisters::RegisterContent); +} diff --git a/js/src/jit/x64/Architecture-x64.h b/js/src/jit/x86-shared/Architecture-x86-shared.h similarity index 77% rename from js/src/jit/x64/Architecture-x64.h rename to js/src/jit/x86-shared/Architecture-x86-shared.h index e3175bc2d8..a7fe20b2a5 100644 --- a/js/src/jit/x64/Architecture-x64.h +++ b/js/src/jit/x86-shared/Architecture-x86-shared.h @@ -4,21 +4,44 @@ * 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 jit_x64_Architecture_x64_h -#define jit_x64_Architecture_x64_h +#ifndef jit_x86_shared_Architecture_x86_h +#define jit_x86_shared_Architecture_x86_h -#include "jit/shared/Constants-x86-shared.h" +#if !defined(JS_CODEGEN_X86) && !defined(JS_CODEGEN_X64) +# error "Unsupported architecture!" +#endif + +#include "jit/x86-shared/Constants-x86-shared.h" namespace js { namespace jit { +#if defined(JS_CODEGEN_X86) +// In bytes: slots needed for potential memory->memory move spills. +// +8 for cycles +// +4 for gpr spills +// +8 for double spills +static const uint32_t ION_FRAME_SLACK_SIZE = 20; + +#elif defined(JS_CODEGEN_X64) // In bytes: slots needed for potential memory->memory move spills. // +8 for cycles // +8 for gpr spills // +8 for double spills static const uint32_t ION_FRAME_SLACK_SIZE = 24; +#endif -#ifdef _WIN64 +#if defined(JS_CODEGEN_X86) +// These offsets are specific to nunboxing, and capture offsets into the +// components of a js::Value. +static const int32_t NUNBOX32_TYPE_OFFSET = 4; +static const int32_t NUNBOX32_PAYLOAD_OFFSET = 0; + +// Size of each bailout table entry. On x86 this is a 5-byte relative call. +static const uint32_t BAILOUT_TABLE_ENTRY_SIZE = 5; +#endif + +#if defined(JS_CODEGEN_X64) && defined(_WIN64) static const uint32_t ShadowStackSpace = 32; #else static const uint32_t ShadowStackSpace = 0; @@ -34,9 +57,35 @@ class Registers { uintptr_t r; }; - typedef uint32_t SetType; +#if defined(JS_CODEGEN_X86) + typedef uint8_t SetType; + + static const char* GetName(Code code) { + return X86Encoding::GPRegName(code); + } + + static const uint32_t Total = 8; + static const uint32_t TotalPhys = 8; + static const uint32_t Allocatable = 7; + +#elif defined(JS_CODEGEN_X64) + typedef uint16_t SetType; + + static const char* GetName(Code code) { + static const char * const Names[] = { "rax", "rcx", "rdx", "rbx", + "rsp", "rbp", "rsi", "rdi", + "r8", "r9", "r10", "r11", + "r12", "r13", "r14", "r15" }; + return Names[code]; + } + + static const uint32_t Total = 16; + static const uint32_t TotalPhys = 16; + static const uint32_t Allocatable = 14; +#endif + static uint32_t SetSize(SetType x) { - static_assert(sizeof(SetType) == 4, "SetType must be 32 bits"); + static_assert(sizeof(SetType) <= 4, "SetType must be, at most, 32 bits"); return mozilla::CountPopulation32(x); } static uint32_t FirstBit(SetType x) { @@ -45,13 +94,6 @@ class Registers { static uint32_t LastBit(SetType x) { return 31 - mozilla::CountLeadingZeroes32(x); } - static const char* GetName(Code code) { - static const char * const Names[] = { "rax", "rcx", "rdx", "rbx", - "rsp", "rbp", "rsi", "rdi", - "r8", "r9", "r10", "r11", - "r12", "r13", "r14", "r15" }; - return Names[code]; - } static Code FromName(const char* name) { for (size_t i = 0; i < Total; i++) { @@ -64,12 +106,39 @@ class Registers { static const Code StackPointer = X86Encoding::rsp; static const Code Invalid = X86Encoding::invalid_reg; - static const uint32_t Total = 16; - static const uint32_t TotalPhys = 16; - static const uint32_t Allocatable = 14; - static const SetType AllMask = (1 << Total) - 1; +#if defined(JS_CODEGEN_X86) + static const SetType ArgRegMask = 0; + + static const SetType VolatileMask = + (1 << X86Encoding::rax) | + (1 << X86Encoding::rcx) | + (1 << X86Encoding::rdx); + + static const SetType WrapperMask = + VolatileMask | + (1 << X86Encoding::rbx); + + static const SetType SingleByteRegs = + (1 << X86Encoding::rax) | + (1 << X86Encoding::rcx) | + (1 << X86Encoding::rdx) | + (1 << X86Encoding::rbx); + + static const SetType NonAllocatableMask = + (1 << X86Encoding::rsp); + + // Registers returned from a JS -> JS call. + static const SetType JSCallMask = + (1 << X86Encoding::rcx) | + (1 << X86Encoding::rdx); + + // Registers returned from a JS -> C call. + static const SetType CallMask = + (1 << X86Encoding::rax); + +#elif defined(JS_CODEGEN_X64) static const SetType ArgRegMask = # if !defined(_WIN64) (1 << X86Encoding::rdi) | @@ -82,42 +151,18 @@ class Registers { static const SetType VolatileMask = (1 << X86Encoding::rax) | - (1 << X86Encoding::rcx) | - (1 << X86Encoding::rdx) | -# if !defined(_WIN64) - (1 << X86Encoding::rsi) | - (1 << X86Encoding::rdi) | -# endif - (1 << X86Encoding::r8) | - (1 << X86Encoding::r9) | + ArgRegMask | (1 << X86Encoding::r10) | (1 << X86Encoding::r11); - static const SetType NonVolatileMask = - (1 << X86Encoding::rbx) | -#if defined(_WIN64) - (1 << X86Encoding::rsi) | - (1 << X86Encoding::rdi) | -#endif - (1 << X86Encoding::rbp) | - (1 << X86Encoding::r12) | - (1 << X86Encoding::r13) | - (1 << X86Encoding::r14) | - (1 << X86Encoding::r15); - static const SetType WrapperMask = VolatileMask; - static const SetType SingleByteRegs = VolatileMask | NonVolatileMask; + static const SetType SingleByteRegs = AllMask & ~(1 << X86Encoding::rsp); static const SetType NonAllocatableMask = (1 << X86Encoding::rsp) | (1 << X86Encoding::r11); // This is ScratchReg. - static const SetType AllocatableMask = AllMask & ~NonAllocatableMask; - - // Registers that can be allocated without being saved, generally. - static const SetType TempMask = VolatileMask & ~NonAllocatableMask; - // Registers returned from a JS -> JS call. static const SetType JSCallMask = (1 << X86Encoding::rcx); @@ -125,10 +170,19 @@ class Registers { // Registers returned from a JS -> C call. static const SetType CallMask = (1 << X86Encoding::rax); + +#endif + + static const SetType NonVolatileMask = + AllMask & ~VolatileMask & ~(1 << X86Encoding::rsp); + + static const SetType AllocatableMask = AllMask & ~NonAllocatableMask; + + // Registers that can be allocated without being saved, generally. + static const SetType TempMask = VolatileMask & ~NonAllocatableMask; }; -// Smallest integer type that can hold a register bitmask. -typedef uint16_t PackedRegisterMask; +typedef Registers::SetType PackedRegisterMask; class FloatRegisters { public: @@ -164,11 +218,20 @@ class FloatRegisters { static const Encoding Invalid = X86Encoding::invalid_xmm; +#if defined(JS_CODEGEN_X86) + static const uint32_t Total = 8 * NumTypes; + static const uint32_t TotalPhys = 8; + static const uint32_t Allocatable = 7; + typedef uint32_t SetType; + +#elif defined(JS_CODEGEN_X64) static const uint32_t Total = 16 * NumTypes; static const uint32_t TotalPhys = 16; static const uint32_t Allocatable = 15; - typedef uint64_t SetType; + +#endif + static_assert(sizeof(SetType) * 8 >= Total, "SetType should be large enough to enumerate all registers."); @@ -186,8 +249,18 @@ class FloatRegisters { static const SetType AllPhysMask = ((1 << TotalPhys) - 1); static const SetType AllMask = AllPhysMask * Spread; static const SetType AllDoubleMask = AllPhysMask * SpreadDouble; + +#if defined(JS_CODEGEN_X86) + static const SetType NonAllocatableMask = + Spread * (1 << X86Encoding::xmm7); // This is ScratchDoubleReg. + +#elif defined(JS_CODEGEN_X64) + static const SetType NonAllocatableMask = + Spread * (1 << X86Encoding::xmm15); // This is ScratchDoubleReg. +#endif + +#if defined(JS_CODEGEN_X64) && defined(_WIN64) static const SetType VolatileMask = -#if defined(_WIN64) ( (1 << X86Encoding::xmm0) | (1 << X86Encoding::xmm1) | (1 << X86Encoding::xmm2) | @@ -196,17 +269,14 @@ class FloatRegisters { (1 << X86Encoding::xmm5) ) * SpreadScalar | AllPhysMask * SpreadVector; + #else + static const SetType VolatileMask = AllMask; #endif static const SetType NonVolatileMask = AllMask & ~VolatileMask; - static const SetType WrapperMask = VolatileMask; - - static const SetType NonAllocatableMask = - Spread * (1 << X86Encoding::xmm15); // This is ScratchDoubleReg. - static const SetType AllocatableMask = AllMask & ~NonAllocatableMask; }; @@ -219,7 +289,6 @@ struct FloatRegister { typedef Codes::Encoding Encoding; typedef Codes::SetType SetType; static uint32_t SetSize(SetType x) { - static_assert(sizeof(SetType) == 8, "SetType must be 64 bits"); // Count the number of non-aliased registers, for the moment. // // Copy the set bits of each typed register to the low part of the of @@ -232,12 +301,25 @@ struct FloatRegister { static_assert(Codes::AllPhysMask <= 0xffff, "We can safely use CountPopulation32"); return mozilla::CountPopulation32(x); } + +#if defined(JS_CODEGEN_X86) static uint32_t FirstBit(SetType x) { + static_assert(sizeof(SetType) == 4, "SetType must be 32 bits"); + return mozilla::CountTrailingZeroes32(x); + } + static uint32_t LastBit(SetType x) { + return 31 - mozilla::CountLeadingZeroes32(x); + } + +#elif defined(JS_CODEGEN_X64) + static uint32_t FirstBit(SetType x) { + static_assert(sizeof(SetType) == 8, "SetType must be 64 bits"); return mozilla::CountTrailingZeroes64(x); } static uint32_t LastBit(SetType x) { return 63 - mozilla::CountLeadingZeroes64(x); } +#endif private: // Note: These fields are using one extra bit to make the invalid enumerated @@ -247,7 +329,11 @@ struct FloatRegister { bool isInvalid_ : 1; // Constants used for exporting/importing the float register code. +#if defined(JS_CODEGEN_X86) + static const size_t RegSize = 3; +#elif defined(JS_CODEGEN_X64) static const size_t RegSize = 4; +#endif static const size_t RegMask = (1 << RegSize) - 1; public: @@ -335,6 +421,10 @@ struct FloatRegister { aliased(aliasIdx, ret); } + SetType alignedOrDominatedAliasedSet() const { + return Codes::Spread << reg_; + } + static TypedRegisterSet ReduceSetForPush(const TypedRegisterSet &s); static uint32_t GetPushSizeInBytes(const TypedRegisterSet &s); uint32_t getRegisterDumpOffsetInBytes(); @@ -364,4 +454,4 @@ static const size_t AsmJSImmediateRange = UINT32_C(0x80000000); } // namespace jit } // namespace js -#endif /* jit_x64_Architecture_x64_h */ +#endif /* jit_x86_shared_Architecture_x86_h */ diff --git a/js/src/jit/shared/Assembler-x86-shared.cpp b/js/src/jit/x86-shared/Assembler-x86-shared.cpp similarity index 90% rename from js/src/jit/shared/Assembler-x86-shared.cpp rename to js/src/jit/x86-shared/Assembler-x86-shared.cpp index 5fe51bcf6b..664c8601b9 100644 --- a/js/src/jit/shared/Assembler-x86-shared.cpp +++ b/js/src/jit/x86-shared/Assembler-x86-shared.cpp @@ -293,32 +293,3 @@ CPUInfo::SetSSEVersion() avxPresent = (xcr0EAX & xcr0SSEBit) && (xcr0EAX & xcr0AVXBit); } } - -const char * -FloatRegister::name() const { - static const char *const names[] = { - -#ifdef JS_CODEGEN_X64 -#define FLOAT_REGS_(TYPE) \ - "%xmm0" TYPE, "%xmm1" TYPE, "%xmm2" TYPE, "%xmm3" TYPE, \ - "%xmm4" TYPE, "%xmm5" TYPE, "%xmm6" TYPE, "%xmm7" TYPE, \ - "%xmm8" TYPE, "%xmm9" TYPE, "%xmm10" TYPE, "%xmm11" TYPE, \ - "%xmm12" TYPE, "%xmm13" TYPE, "%xmm14" TYPE, "%xmm15" TYPE -#else -#define FLOAT_REGS_(TYPE) \ - "%xmm0" TYPE, "%xmm1" TYPE, "%xmm2" TYPE, "%xmm3" TYPE, \ - "%xmm4" TYPE, "%xmm5" TYPE, "%xmm6" TYPE, "%xmm7" TYPE -#endif - - // These should be enumerated in the same order as in - // FloatRegisters::ContentType. - FLOAT_REGS_(".s"), - FLOAT_REGS_(".d"), - FLOAT_REGS_(".i4"), - FLOAT_REGS_(".s4") -#undef FLOAT_REGS_ - - }; - MOZ_ASSERT(size_t(code()) < mozilla::ArrayLength(names)); - return names[size_t(code())]; -} diff --git a/js/src/jit/shared/Assembler-x86-shared.h b/js/src/jit/x86-shared/Assembler-x86-shared.h similarity index 99% rename from js/src/jit/shared/Assembler-x86-shared.h rename to js/src/jit/x86-shared/Assembler-x86-shared.h index 931f927edc..3649e21e80 100644 --- a/js/src/jit/shared/Assembler-x86-shared.h +++ b/js/src/jit/x86-shared/Assembler-x86-shared.h @@ -4,13 +4,13 @@ * 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 jit_shared_Assembler_x86_shared_h -#define jit_shared_Assembler_x86_shared_h +#ifndef jit_x86_shared_Assembler_x86_shared_h +#define jit_x86_shared_Assembler_x86_shared_h #include #include "jit/shared/Assembler-shared.h" -#include "jit/shared/BaseAssembler-x86-shared.h" +#include "jit/x86-shared/BaseAssembler-x86-shared.h" namespace js { namespace jit { @@ -1053,8 +1053,8 @@ class AssemblerX86Shared : public AssemblerShared masm.setCC_r(static_cast(cond), r.code()); } void testb(Register rhs, Register lhs) { - MOZ_ASSERT(GeneralRegisterSet(Registers::SingleByteRegs).has(rhs)); - MOZ_ASSERT(GeneralRegisterSet(Registers::SingleByteRegs).has(lhs)); + MOZ_ASSERT(AllocatableGeneralRegisterSet(Registers::SingleByteRegs).has(rhs)); + MOZ_ASSERT(AllocatableGeneralRegisterSet(Registers::SingleByteRegs).has(lhs)); masm.testb_rr(rhs.code(), lhs.code()); } void testw(Register rhs, Register lhs) { @@ -2958,4 +2958,4 @@ class AssemblerX86Shared : public AssemblerShared } // namespace jit } // namespace js -#endif /* jit_shared_Assembler_x86_shared_h */ +#endif /* jit_x86_shared_Assembler_x86_shared_h */ diff --git a/js/src/jit/shared/AssemblerBuffer-x86-shared.cpp b/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.cpp similarity index 93% rename from js/src/jit/shared/AssemblerBuffer-x86-shared.cpp rename to js/src/jit/x86-shared/AssemblerBuffer-x86-shared.cpp index b320b3dbeb..61cdbaed3a 100644 --- a/js/src/jit/shared/AssemblerBuffer-x86-shared.cpp +++ b/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.cpp @@ -4,7 +4,7 @@ * 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/. */ -#include "jit/shared/AssemblerBuffer-x86-shared.h" +#include "jit/x86-shared/AssemblerBuffer-x86-shared.h" #include "jsopcode.h" diff --git a/js/src/jit/shared/AssemblerBuffer-x86-shared.h b/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h similarity index 97% rename from js/src/jit/shared/AssemblerBuffer-x86-shared.h rename to js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h index 6405b3e48e..cd5bcf99b9 100644 --- a/js/src/jit/shared/AssemblerBuffer-x86-shared.h +++ b/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h @@ -27,8 +27,8 @@ * * ***** END LICENSE BLOCK ***** */ -#ifndef jit_shared_AssemblerBuffer_x86_shared_h -#define jit_shared_AssemblerBuffer_x86_shared_h +#ifndef jit_x86_shared_AssemblerBuffer_x86_shared_h +#define jit_x86_shared_AssemblerBuffer_x86_shared_h #include #include @@ -209,4 +209,4 @@ namespace jit { } // namespace jit } // namespace js -#endif /* jit_shared_AssemblerBuffer_x86_shared_h */ +#endif /* jit_x86_shared_AssemblerBuffer_x86_shared_h */ diff --git a/js/src/jit/shared/BaseAssembler-x86-shared.h b/js/src/jit/x86-shared/BaseAssembler-x86-shared.h similarity index 99% rename from js/src/jit/shared/BaseAssembler-x86-shared.h rename to js/src/jit/x86-shared/BaseAssembler-x86-shared.h index a57e01e861..bb48c9df20 100644 --- a/js/src/jit/shared/BaseAssembler-x86-shared.h +++ b/js/src/jit/x86-shared/BaseAssembler-x86-shared.h @@ -27,14 +27,14 @@ * * ***** END LICENSE BLOCK ***** */ -#ifndef jit_shared_BaseAssembler_x86_shared_h -#define jit_shared_BaseAssembler_x86_shared_h +#ifndef jit_x86_shared_BaseAssembler_x86_shared_h +#define jit_x86_shared_BaseAssembler_x86_shared_h #include "mozilla/IntegerPrintfMacros.h" -#include "jit/shared/AssemblerBuffer-x86-shared.h" -#include "jit/shared/Encoding-x86-shared.h" -#include "jit/shared/Patching-x86-shared.h" +#include "jit/x86-shared/AssemblerBuffer-x86-shared.h" +#include "jit/x86-shared/Encoding-x86-shared.h" +#include "jit/x86-shared/Patching-x86-shared.h" namespace js { namespace jit { @@ -5312,4 +5312,4 @@ threeByteOpImmSimd("vblendps", VEX_PD, OP3_BLENDPS_VpsWpsIb, ESCAPE_3A, imm, off } // namespace jit } // namespace js -#endif /* jit_shared_BaseAssembler_x86_shared_h */ +#endif /* jit_x86_shared_BaseAssembler_x86_shared_h */ diff --git a/js/src/jit/shared/BaselineCompiler-x86-shared.cpp b/js/src/jit/x86-shared/BaselineCompiler-x86-shared.cpp similarity index 90% rename from js/src/jit/shared/BaselineCompiler-x86-shared.cpp rename to js/src/jit/x86-shared/BaselineCompiler-x86-shared.cpp index 27d294e3f8..327015df8b 100644 --- a/js/src/jit/shared/BaselineCompiler-x86-shared.cpp +++ b/js/src/jit/x86-shared/BaselineCompiler-x86-shared.cpp @@ -4,7 +4,7 @@ * 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/. */ -#include "jit/shared/BaselineCompiler-x86-shared.h" +#include "jit/x86-shared/BaselineCompiler-x86-shared.h" using namespace js; using namespace js::jit; diff --git a/js/src/jit/shared/BaselineCompiler-x86-shared.h b/js/src/jit/x86-shared/BaselineCompiler-x86-shared.h similarity index 78% rename from js/src/jit/shared/BaselineCompiler-x86-shared.h rename to js/src/jit/x86-shared/BaselineCompiler-x86-shared.h index 2c8e75801f..65b702d54a 100644 --- a/js/src/jit/shared/BaselineCompiler-x86-shared.h +++ b/js/src/jit/x86-shared/BaselineCompiler-x86-shared.h @@ -4,8 +4,8 @@ * 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 jit_shared_BaselineCompiler_x86_shared_h -#define jit_shared_BaselineCompiler_x86_shared_h +#ifndef jit_x86_shared_BaselineCompiler_x86_shared_h +#define jit_x86_shared_BaselineCompiler_x86_shared_h #include "jit/shared/BaselineCompiler-shared.h" @@ -21,4 +21,4 @@ class BaselineCompilerX86Shared : public BaselineCompilerShared } // namespace jit } // namespace js -#endif /* jit_shared_BaselineCompiler_x86_shared_h */ +#endif /* jit_x86_shared_BaselineCompiler_x86_shared_h */ diff --git a/js/src/jit/shared/BaselineIC-x86-shared.cpp b/js/src/jit/x86-shared/BaselineIC-x86-shared.cpp similarity index 100% rename from js/src/jit/shared/BaselineIC-x86-shared.cpp rename to js/src/jit/x86-shared/BaselineIC-x86-shared.cpp diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.cpp b/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp similarity index 99% rename from js/src/jit/shared/CodeGenerator-x86-shared.cpp rename to js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp index 674586ff5f..dbecc7a6dc 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp +++ b/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp @@ -4,7 +4,7 @@ * 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/. */ -#include "jit/shared/CodeGenerator-x86-shared.h" +#include "jit/x86-shared/CodeGenerator-x86-shared.h" #include "mozilla/DebugOnly.h" #include "mozilla/MathAlgorithms.h" diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.h b/js/src/jit/x86-shared/CodeGenerator-x86-shared.h similarity index 98% rename from js/src/jit/shared/CodeGenerator-x86-shared.h rename to js/src/jit/x86-shared/CodeGenerator-x86-shared.h index 2262e46bef..a8ce8aeb9f 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.h +++ b/js/src/jit/x86-shared/CodeGenerator-x86-shared.h @@ -4,8 +4,8 @@ * 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 jit_shared_CodeGenerator_x86_shared_h -#define jit_shared_CodeGenerator_x86_shared_h +#ifndef jit_x86_shared_CodeGenerator_x86_shared_h +#define jit_x86_shared_CodeGenerator_x86_shared_h #include "jit/shared/CodeGenerator-shared.h" @@ -305,4 +305,4 @@ class OutOfLineBailout : public OutOfLineCodeBase } // namespace jit } // namespace js -#endif /* jit_shared_CodeGenerator_x86_shared_h */ +#endif /* jit_x86_shared_CodeGenerator_x86_shared_h */ diff --git a/js/src/jit/shared/Constants-x86-shared.h b/js/src/jit/x86-shared/Constants-x86-shared.h similarity index 97% rename from js/src/jit/shared/Constants-x86-shared.h rename to js/src/jit/x86-shared/Constants-x86-shared.h index 06fdefbe7f..8179f46445 100644 --- a/js/src/jit/shared/Constants-x86-shared.h +++ b/js/src/jit/x86-shared/Constants-x86-shared.h @@ -4,8 +4,8 @@ * 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 jit_shared_Constants_x86_shared_h -#define jit_shared_Constants_x86_shared_h +#ifndef jit_x86_shared_Constants_x86_shared_h +#define jit_x86_shared_Constants_x86_shared_h namespace js { namespace jit { @@ -219,4 +219,4 @@ inline int32_t AddressImmediate(const void* address) } // namespace jit } // namespace js -#endif /* jit_shared_Constants_x86_shared_h */ +#endif /* jit_x86_shared_Constants_x86_shared_h */ diff --git a/js/src/jit/shared/Disassembler-x86-shared.cpp b/js/src/jit/x86-shared/Disassembler-x86-shared.cpp similarity index 99% rename from js/src/jit/shared/Disassembler-x86-shared.cpp rename to js/src/jit/x86-shared/Disassembler-x86-shared.cpp index 830947aa5a..abefaabe45 100644 --- a/js/src/jit/shared/Disassembler-x86-shared.cpp +++ b/js/src/jit/x86-shared/Disassembler-x86-shared.cpp @@ -6,7 +6,7 @@ #include "jit/Disassembler.h" -#include "jit/shared/Encoding-x86-shared.h" +#include "jit/x86-shared/Encoding-x86-shared.h" using namespace js; using namespace js::jit; diff --git a/js/src/jit/shared/Encoding-x86-shared.h b/js/src/jit/x86-shared/Encoding-x86-shared.h similarity index 98% rename from js/src/jit/shared/Encoding-x86-shared.h rename to js/src/jit/x86-shared/Encoding-x86-shared.h index 537153cd7d..3d7cbc8908 100644 --- a/js/src/jit/shared/Encoding-x86-shared.h +++ b/js/src/jit/x86-shared/Encoding-x86-shared.h @@ -4,10 +4,10 @@ * 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 jit_shared_Encoding_x86_shared_h -#define jit_shared_Encoding_x86_shared_h +#ifndef jit_x86_shared_Encoding_x86_shared_h +#define jit_x86_shared_Encoding_x86_shared_h -#include "jit/shared/Constants-x86-shared.h" +#include "jit/x86-shared/Constants-x86-shared.h" namespace js { namespace jit { @@ -325,4 +325,4 @@ enum ModRmMode { } // namespace jit } // namespace js -#endif /* jit_shared_Encoding_x86_shared_h */ +#endif /* jit_x86_shared_Encoding_x86_shared_h */ diff --git a/js/src/jit/shared/LIR-x86-shared.h b/js/src/jit/x86-shared/LIR-x86-shared.h similarity index 98% rename from js/src/jit/shared/LIR-x86-shared.h rename to js/src/jit/x86-shared/LIR-x86-shared.h index 9e9fad0b1a..9125feeaa2 100644 --- a/js/src/jit/shared/LIR-x86-shared.h +++ b/js/src/jit/x86-shared/LIR-x86-shared.h @@ -4,8 +4,8 @@ * 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 jit_shared_LIR_x86_shared_h -#define jit_shared_LIR_x86_shared_h +#ifndef jit_x86_shared_LIR_x86_shared_h +#define jit_x86_shared_LIR_x86_shared_h namespace js { namespace jit { @@ -364,4 +364,4 @@ class LSimdValueFloat32x4 : public LInstructionHelper<1, 4, 1> } // namespace jit } // namespace js -#endif /* jit_shared_LIR_x86_shared_h */ +#endif /* jit_x86_shared_LIR_x86_shared_h */ diff --git a/js/src/jit/shared/Lowering-x86-shared.cpp b/js/src/jit/x86-shared/Lowering-x86-shared.cpp similarity index 99% rename from js/src/jit/shared/Lowering-x86-shared.cpp rename to js/src/jit/x86-shared/Lowering-x86-shared.cpp index bd6e4b6b3c..1347895618 100644 --- a/js/src/jit/shared/Lowering-x86-shared.cpp +++ b/js/src/jit/x86-shared/Lowering-x86-shared.cpp @@ -4,7 +4,7 @@ * 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/. */ -#include "jit/shared/Lowering-x86-shared.h" +#include "jit/x86-shared/Lowering-x86-shared.h" #include "mozilla/MathAlgorithms.h" diff --git a/js/src/jit/shared/Lowering-x86-shared.h b/js/src/jit/x86-shared/Lowering-x86-shared.h similarity index 95% rename from js/src/jit/shared/Lowering-x86-shared.h rename to js/src/jit/x86-shared/Lowering-x86-shared.h index 68f13469b1..2a0d620b97 100644 --- a/js/src/jit/shared/Lowering-x86-shared.h +++ b/js/src/jit/x86-shared/Lowering-x86-shared.h @@ -4,8 +4,8 @@ * 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 jit_shared_Lowering_x86_shared_h -#define jit_shared_Lowering_x86_shared_h +#ifndef jit_x86_shared_Lowering_x86_shared_h +#define jit_x86_shared_Lowering_x86_shared_h #include "jit/shared/Lowering-shared.h" @@ -65,4 +65,4 @@ class LIRGeneratorX86Shared : public LIRGeneratorShared } // namespace jit } // namespace js -#endif /* jit_shared_Lowering_x86_shared_h */ +#endif /* jit_x86_shared_Lowering_x86_shared_h */ diff --git a/js/src/jit/shared/MacroAssembler-x86-shared.cpp b/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp similarity index 77% rename from js/src/jit/shared/MacroAssembler-x86-shared.cpp rename to js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp index d790fbbc90..a9cb964c45 100644 --- a/js/src/jit/shared/MacroAssembler-x86-shared.cpp +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp @@ -4,7 +4,7 @@ * 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/. */ -#include "jit/shared/MacroAssembler-x86-shared.h" +#include "jit/x86-shared/MacroAssembler-x86-shared.h" #include "jit/JitFrames.h" #include "jit/MacroAssembler.h" @@ -63,7 +63,7 @@ MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output) // Builds an exit frame on the stack, with a return address to an internal // non-function. Returns offset to be passed to markSafepointAt(). void -MacroAssemblerX86Shared::buildFakeExitFrame(Register scratch, uint32_t *offset) +MacroAssemblerX86Shared::buildFakeExitFrame(Register scratch, uint32_t* offset) { mozilla::DebugOnly initialDepth = framePushed(); @@ -82,7 +82,7 @@ MacroAssemblerX86Shared::buildFakeExitFrame(Register scratch, uint32_t *offset) } void -MacroAssemblerX86Shared::callWithExitFrame(Label *target) +MacroAssemblerX86Shared::callWithExitFrame(Label* target) { uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS); asMasm().Push(Imm32(descriptor)); @@ -90,7 +90,7 @@ MacroAssemblerX86Shared::callWithExitFrame(Label *target) } void -MacroAssemblerX86Shared::callWithExitFrame(JitCode *target) +MacroAssemblerX86Shared::callWithExitFrame(JitCode* target) { uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS); asMasm().Push(Imm32(descriptor)); @@ -98,19 +98,19 @@ MacroAssemblerX86Shared::callWithExitFrame(JitCode *target) } void -MacroAssembler::alignFrameForICArguments(AfterICSaveLive &aic) +MacroAssembler::alignFrameForICArguments(AfterICSaveLive& aic) { // Exists for MIPS compatibility. } void -MacroAssembler::restoreFrameAlignmentForICArguments(AfterICSaveLive &aic) +MacroAssembler::restoreFrameAlignmentForICArguments(AfterICSaveLive& aic) { // Exists for MIPS compatibility. } bool -MacroAssemblerX86Shared::buildOOLFakeExitFrame(void *fakeReturnAddr) +MacroAssemblerX86Shared::buildOOLFakeExitFrame(void* fakeReturnAddr) { uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS); asMasm().Push(Imm32(descriptor)); @@ -121,7 +121,7 @@ MacroAssemblerX86Shared::buildOOLFakeExitFrame(void *fakeReturnAddr) void MacroAssemblerX86Shared::branchNegativeZero(FloatRegister reg, Register scratch, - Label *label, + Label* label, bool maybeNonZero) { // Determines whether the low double contained in the XMM register reg @@ -156,37 +156,34 @@ MacroAssemblerX86Shared::branchNegativeZero(FloatRegister reg, void MacroAssemblerX86Shared::branchNegativeZeroFloat32(FloatRegister reg, Register scratch, - Label *label) + Label* label) { vmovd(reg, scratch); cmp32(scratch, Imm32(1)); j(Overflow, label); } -MacroAssembler & +MacroAssembler& MacroAssemblerX86Shared::asMasm() { - return *static_cast(this); + return *static_cast(this); } -const MacroAssembler & +const MacroAssembler& MacroAssemblerX86Shared::asMasm() const { - return *static_cast(this); + return *static_cast(this); } // =============================================================== // Stack manipulation functions. void -MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet) +MacroAssembler::PushRegsInMask(LiveRegisterSet set) { - FloatRegisterSet doubleSet(FloatRegisterSet::Subtract(set.fpus(), simdSet)); - MOZ_ASSERT_IF(simdSet.empty(), doubleSet == set.fpus()); - doubleSet = doubleSet.reduceSetForPush(); - unsigned numSimd = simdSet.size(); - unsigned numDouble = doubleSet.size(); - int32_t diffF = doubleSet.getPushSizeInBytes() + numSimd * Simd128DataSize; + FloatRegisterSet fpuSet(set.fpus().reduceSetForPush()); + unsigned numFpu = fpuSet.size(); + int32_t diffF = fpuSet.getPushSizeInBytes(); int32_t diffG = set.gprs().size() * sizeof(intptr_t); // On x86, always use push to push the integer registers, as it's fast @@ -198,10 +195,10 @@ MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet) MOZ_ASSERT(diffG == 0); reserveStack(diffF); - for (FloatRegisterBackwardIterator iter(doubleSet); iter.more(); iter++) { + for (FloatRegisterBackwardIterator iter(fpuSet); iter.more(); iter++) { FloatRegister reg = *iter; diffF -= reg.size(); - numDouble -= 1; + numFpu -= 1; Address spillAddress(StackPointer, diffF); if (reg.isDouble()) storeDouble(reg, spillAddress); @@ -214,14 +211,7 @@ MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet) else MOZ_CRASH("Unknown register type."); } - MOZ_ASSERT(numDouble == 0); - for (FloatRegisterBackwardIterator iter(simdSet); iter.more(); iter++) { - diffF -= Simd128DataSize; - numSimd -= 1; - // XXX how to choose the right move type? - storeUnalignedInt32x4(*iter, Address(StackPointer, diffF)); - } - MOZ_ASSERT(numSimd == 0); + MOZ_ASSERT(numFpu == 0); // x64 padding to keep the stack aligned on uintptr_t. Keep in sync with // GetPushBytesInSize. diffF -= diffF % sizeof(uintptr_t); @@ -229,30 +219,19 @@ MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet) } void -MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRegisterSet simdSet) +MacroAssembler::PopRegsInMaskIgnore(LiveRegisterSet set, LiveRegisterSet ignore) { - FloatRegisterSet doubleSet(FloatRegisterSet::Subtract(set.fpus(), simdSet)); - MOZ_ASSERT_IF(simdSet.empty(), doubleSet == set.fpus()); - doubleSet = doubleSet.reduceSetForPush(); - unsigned numSimd = simdSet.size(); - unsigned numDouble = doubleSet.size(); + FloatRegisterSet fpuSet(set.fpus().reduceSetForPush()); + unsigned numFpu = fpuSet.size(); int32_t diffG = set.gprs().size() * sizeof(intptr_t); - int32_t diffF = doubleSet.getPushSizeInBytes() + numSimd * Simd128DataSize; + int32_t diffF = fpuSet.getPushSizeInBytes(); const int32_t reservedG = diffG; const int32_t reservedF = diffF; - for (FloatRegisterBackwardIterator iter(simdSet); iter.more(); iter++) { - diffF -= Simd128DataSize; - numSimd -= 1; - if (!ignore.has(*iter)) - // XXX how to choose the right move type? - loadUnalignedInt32x4(Address(StackPointer, diffF), *iter); - } - MOZ_ASSERT(numSimd == 0); - for (FloatRegisterBackwardIterator iter(doubleSet); iter.more(); iter++) { + for (FloatRegisterBackwardIterator iter(fpuSet); iter.more(); iter++) { FloatRegister reg = *iter; diffF -= reg.size(); - numDouble -= 1; + numFpu -= 1; if (ignore.has(reg)) continue; @@ -269,7 +248,7 @@ MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRe MOZ_CRASH("Unknown register type."); } freeStack(reservedF); - MOZ_ASSERT(numDouble == 0); + MOZ_ASSERT(numFpu == 0); // x64 padding to keep the stack aligned on uintptr_t. Keep in sync with // GetPushBytesInSize. diffF -= diffF % sizeof(uintptr_t); @@ -278,7 +257,7 @@ MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRe // On x86, use pop to pop the integer registers, if we're not going to // ignore any slots, as it's fast on modern hardware and it's a small // instruction. - if (ignore.empty(false)) { + if (ignore.emptyGeneral()) { for (GeneralRegisterForwardIterator iter(set.gprs()); iter.more(); iter++) { diffG -= sizeof(intptr_t); Pop(*iter); @@ -364,7 +343,7 @@ MacroAssembler::Pop(FloatRegister reg) } void -MacroAssembler::Pop(const ValueOperand &val) +MacroAssembler::Pop(const ValueOperand& val) { popValue(val); framePushed_ -= sizeof(Value); diff --git a/js/src/jit/shared/MacroAssembler-x86-shared.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h similarity index 89% rename from js/src/jit/shared/MacroAssembler-x86-shared.h rename to js/src/jit/x86-shared/MacroAssembler-x86-shared.h index f958f1f9ca..ce2b976878 100644 --- a/js/src/jit/shared/MacroAssembler-x86-shared.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h @@ -4,8 +4,8 @@ * 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 jit_shared_MacroAssembler_x86_shared_h -#define jit_shared_MacroAssembler_x86_shared_h +#ifndef jit_x86_shared_MacroAssembler_x86_shared_h +#define jit_x86_shared_MacroAssembler_x86_shared_h #include "mozilla/Casting.h" #include "mozilla/DebugOnly.h" @@ -17,16 +17,16 @@ #endif #ifdef DEBUG - #define CHECK_BYTEREG(reg) \ - JS_BEGIN_MACRO \ - GeneralRegisterSet byteRegs(Registers::SingleByteRegs); \ - MOZ_ASSERT(byteRegs.has(reg)); \ + #define CHECK_BYTEREG(reg) \ + JS_BEGIN_MACRO \ + AllocatableGeneralRegisterSet byteRegs(Registers::SingleByteRegs); \ + MOZ_ASSERT(byteRegs.has(reg)); \ JS_END_MACRO - #define CHECK_BYTEREGS(r1, r2) \ - JS_BEGIN_MACRO \ - GeneralRegisterSet byteRegs(Registers::SingleByteRegs); \ - MOZ_ASSERT(byteRegs.has(r1)); \ - MOZ_ASSERT(byteRegs.has(r2)); \ + #define CHECK_BYTEREGS(r1, r2) \ + JS_BEGIN_MACRO \ + AllocatableGeneralRegisterSet byteRegs(Registers::SingleByteRegs); \ + MOZ_ASSERT(byteRegs.has(r1)); \ + MOZ_ASSERT(byteRegs.has(r2)); \ JS_END_MACRO #else #define CHECK_BYTEREG(reg) (void)0 @@ -42,8 +42,8 @@ class MacroAssemblerX86Shared : public Assembler { private: // Perform a downcast. Should be removed by Bug 996602. - MacroAssembler &asMasm(); - const MacroAssembler &asMasm() const; + MacroAssembler& asMasm(); + const MacroAssembler& asMasm() const; protected: // Bytes pushed onto the frame by the callee; includes frameDepth_. This is @@ -229,15 +229,15 @@ class MacroAssemblerX86Shared : public Assembler void not32(Register reg) { notl(reg); } - void atomic_inc32(const Operand &addr) { + void atomic_inc32(const Operand& addr) { lock_incl(addr); } - void atomic_dec32(const Operand &addr) { + void atomic_dec32(const Operand& addr) { lock_decl(addr); } template - void atomicFetchAdd8SignExtend(Register src, const T &mem, Register temp, Register output) { + void atomicFetchAdd8SignExtend(Register src, const T& mem, Register temp, Register output) { CHECK_BYTEREGS(src, output); if (src != output) movl(src, output); @@ -246,7 +246,7 @@ class MacroAssemblerX86Shared : public Assembler } template - void atomicFetchAdd8ZeroExtend(Register src, const T &mem, Register temp, Register output) { + void atomicFetchAdd8ZeroExtend(Register src, const T& mem, Register temp, Register output) { CHECK_BYTEREGS(src, output); MOZ_ASSERT(temp == InvalidReg); if (src != output) @@ -256,7 +256,7 @@ class MacroAssemblerX86Shared : public Assembler } template - void atomicFetchAdd8SignExtend(Imm32 src, const T &mem, Register temp, Register output) { + void atomicFetchAdd8SignExtend(Imm32 src, const T& mem, Register temp, Register output) { CHECK_BYTEREG(output); MOZ_ASSERT(temp == InvalidReg); movb(src, output); @@ -265,7 +265,7 @@ class MacroAssemblerX86Shared : public Assembler } template - void atomicFetchAdd8ZeroExtend(Imm32 src, const T &mem, Register temp, Register output) { + void atomicFetchAdd8ZeroExtend(Imm32 src, const T& mem, Register temp, Register output) { CHECK_BYTEREG(output); MOZ_ASSERT(temp == InvalidReg); movb(src, output); @@ -274,7 +274,7 @@ class MacroAssemblerX86Shared : public Assembler } template - void atomicFetchAdd16SignExtend(Register src, const T &mem, Register temp, Register output) { + void atomicFetchAdd16SignExtend(Register src, const T& mem, Register temp, Register output) { MOZ_ASSERT(temp == InvalidReg); if (src != output) movl(src, output); @@ -283,7 +283,7 @@ class MacroAssemblerX86Shared : public Assembler } template - void atomicFetchAdd16ZeroExtend(Register src, const T &mem, Register temp, Register output) { + void atomicFetchAdd16ZeroExtend(Register src, const T& mem, Register temp, Register output) { MOZ_ASSERT(temp == InvalidReg); if (src != output) movl(src, output); @@ -292,7 +292,7 @@ class MacroAssemblerX86Shared : public Assembler } template - void atomicFetchAdd16SignExtend(Imm32 src, const T &mem, Register temp, Register output) { + void atomicFetchAdd16SignExtend(Imm32 src, const T& mem, Register temp, Register output) { MOZ_ASSERT(temp == InvalidReg); movl(src, output); lock_xaddw(output, Operand(mem)); @@ -300,7 +300,7 @@ class MacroAssemblerX86Shared : public Assembler } template - void atomicFetchAdd16ZeroExtend(Imm32 src, const T &mem, Register temp, Register output) { + void atomicFetchAdd16ZeroExtend(Imm32 src, const T& mem, Register temp, Register output) { MOZ_ASSERT(temp == InvalidReg); movl(src, output); lock_xaddw(output, Operand(mem)); @@ -308,7 +308,7 @@ class MacroAssemblerX86Shared : public Assembler } template - void atomicFetchAdd32(Register src, const T &mem, Register temp, Register output) { + void atomicFetchAdd32(Register src, const T& mem, Register temp, Register output) { MOZ_ASSERT(temp == InvalidReg); if (src != output) movl(src, output); @@ -316,14 +316,14 @@ class MacroAssemblerX86Shared : public Assembler } template - void atomicFetchAdd32(Imm32 src, const T &mem, Register temp, Register output) { + void atomicFetchAdd32(Imm32 src, const T& mem, Register temp, Register output) { MOZ_ASSERT(temp == InvalidReg); movl(src, output); lock_xaddl(output, Operand(mem)); } template - void atomicFetchSub8SignExtend(Register src, const T &mem, Register temp, Register output) { + void atomicFetchSub8SignExtend(Register src, const T& mem, Register temp, Register output) { CHECK_BYTEREGS(src, output); MOZ_ASSERT(temp == InvalidReg); if (src != output) @@ -334,7 +334,7 @@ class MacroAssemblerX86Shared : public Assembler } template - void atomicFetchSub8ZeroExtend(Register src, const T &mem, Register temp, Register output) { + void atomicFetchSub8ZeroExtend(Register src, const T& mem, Register temp, Register output) { CHECK_BYTEREGS(src, output); MOZ_ASSERT(temp == InvalidReg); if (src != output) @@ -345,7 +345,7 @@ class MacroAssemblerX86Shared : public Assembler } template - void atomicFetchSub8SignExtend(Imm32 src, const T &mem, Register temp, Register output) { + void atomicFetchSub8SignExtend(Imm32 src, const T& mem, Register temp, Register output) { CHECK_BYTEREG(output); MOZ_ASSERT(temp == InvalidReg); movb(Imm32(-src.value), output); @@ -354,7 +354,7 @@ class MacroAssemblerX86Shared : public Assembler } template - void atomicFetchSub8ZeroExtend(Imm32 src, const T &mem, Register temp, Register output) { + void atomicFetchSub8ZeroExtend(Imm32 src, const T& mem, Register temp, Register output) { CHECK_BYTEREG(output); MOZ_ASSERT(temp == InvalidReg); movb(Imm32(-src.value), output); @@ -363,7 +363,7 @@ class MacroAssemblerX86Shared : public Assembler } template - void atomicFetchSub16SignExtend(Register src, const T &mem, Register temp, Register output) { + void atomicFetchSub16SignExtend(Register src, const T& mem, Register temp, Register output) { MOZ_ASSERT(temp == InvalidReg); if (src != output) movl(src, output); @@ -373,7 +373,7 @@ class MacroAssemblerX86Shared : public Assembler } template - void atomicFetchSub16ZeroExtend(Register src, const T &mem, Register temp, Register output) { + void atomicFetchSub16ZeroExtend(Register src, const T& mem, Register temp, Register output) { MOZ_ASSERT(temp == InvalidReg); if (src != output) movl(src, output); @@ -383,7 +383,7 @@ class MacroAssemblerX86Shared : public Assembler } template - void atomicFetchSub16SignExtend(Imm32 src, const T &mem, Register temp, Register output) { + void atomicFetchSub16SignExtend(Imm32 src, const T& mem, Register temp, Register output) { MOZ_ASSERT(temp == InvalidReg); movl(Imm32(-src.value), output); lock_xaddw(output, Operand(mem)); @@ -391,7 +391,7 @@ class MacroAssemblerX86Shared : public Assembler } template - void atomicFetchSub16ZeroExtend(Imm32 src, const T &mem, Register temp, Register output) { + void atomicFetchSub16ZeroExtend(Imm32 src, const T& mem, Register temp, Register output) { MOZ_ASSERT(temp == InvalidReg); movl(Imm32(-src.value), output); lock_xaddw(output, Operand(mem)); @@ -399,7 +399,7 @@ class MacroAssemblerX86Shared : public Assembler } template - void atomicFetchSub32(Register src, const T &mem, Register temp, Register output) { + void atomicFetchSub32(Register src, const T& mem, Register temp, Register output) { MOZ_ASSERT(temp == InvalidReg); if (src != output) movl(src, output); @@ -408,7 +408,7 @@ class MacroAssemblerX86Shared : public Assembler } template - void atomicFetchSub32(Imm32 src, const T &mem, Register temp, Register output) { + void atomicFetchSub32(Imm32 src, const T& mem, Register temp, Register output) { movl(Imm32(-src.value), output); lock_xaddl(output, Operand(mem)); } @@ -425,83 +425,83 @@ class MacroAssemblerX86Shared : public Assembler j(NonZero, &again); template - void atomicFetchAnd8SignExtend(const S &src, const T &mem, Register temp, Register output) { + void atomicFetchAnd8SignExtend(const S& src, const T& mem, Register temp, Register output) { ATOMIC_BITOP_BODY(movb, andl, lock_cmpxchgb) CHECK_BYTEREG(temp); movsbl(eax, eax); } template - void atomicFetchAnd8ZeroExtend(const S &src, const T &mem, Register temp, Register output) { + void atomicFetchAnd8ZeroExtend(const S& src, const T& mem, Register temp, Register output) { ATOMIC_BITOP_BODY(movb, andl, lock_cmpxchgb) CHECK_BYTEREG(temp); movzbl(eax, eax); } template - void atomicFetchAnd16SignExtend(const S &src, const T &mem, Register temp, Register output) { + void atomicFetchAnd16SignExtend(const S& src, const T& mem, Register temp, Register output) { ATOMIC_BITOP_BODY(movw, andl, lock_cmpxchgw) movswl(eax, eax); } template - void atomicFetchAnd16ZeroExtend(const S &src, const T &mem, Register temp, Register output) { + void atomicFetchAnd16ZeroExtend(const S& src, const T& mem, Register temp, Register output) { ATOMIC_BITOP_BODY(movw, andl, lock_cmpxchgw) movzwl(eax, eax); } template - void atomicFetchAnd32(const S &src, const T &mem, Register temp, Register output) { + void atomicFetchAnd32(const S& src, const T& mem, Register temp, Register output) { ATOMIC_BITOP_BODY(movl, andl, lock_cmpxchgl) } template - void atomicFetchOr8SignExtend(const S &src, const T &mem, Register temp, Register output) { + void atomicFetchOr8SignExtend(const S& src, const T& mem, Register temp, Register output) { ATOMIC_BITOP_BODY(movb, orl, lock_cmpxchgb) CHECK_BYTEREG(temp); movsbl(eax, eax); } template - void atomicFetchOr8ZeroExtend(const S &src, const T &mem, Register temp, Register output) { + void atomicFetchOr8ZeroExtend(const S& src, const T& mem, Register temp, Register output) { ATOMIC_BITOP_BODY(movb, orl, lock_cmpxchgb) CHECK_BYTEREG(temp); movzbl(eax, eax); } template - void atomicFetchOr16SignExtend(const S &src, const T &mem, Register temp, Register output) { + void atomicFetchOr16SignExtend(const S& src, const T& mem, Register temp, Register output) { ATOMIC_BITOP_BODY(movw, orl, lock_cmpxchgw) movswl(eax, eax); } template - void atomicFetchOr16ZeroExtend(const S &src, const T &mem, Register temp, Register output) { + void atomicFetchOr16ZeroExtend(const S& src, const T& mem, Register temp, Register output) { ATOMIC_BITOP_BODY(movw, orl, lock_cmpxchgw) movzwl(eax, eax); } template - void atomicFetchOr32(const S &src, const T &mem, Register temp, Register output) { + void atomicFetchOr32(const S& src, const T& mem, Register temp, Register output) { ATOMIC_BITOP_BODY(movl, orl, lock_cmpxchgl) } template - void atomicFetchXor8SignExtend(const S &src, const T &mem, Register temp, Register output) { + void atomicFetchXor8SignExtend(const S& src, const T& mem, Register temp, Register output) { ATOMIC_BITOP_BODY(movb, xorl, lock_cmpxchgb) CHECK_BYTEREG(temp); movsbl(eax, eax); } template - void atomicFetchXor8ZeroExtend(const S &src, const T &mem, Register temp, Register output) { + void atomicFetchXor8ZeroExtend(const S& src, const T& mem, Register temp, Register output) { ATOMIC_BITOP_BODY(movb, xorl, lock_cmpxchgb) CHECK_BYTEREG(temp); movzbl(eax, eax); } template - void atomicFetchXor16SignExtend(const S &src, const T &mem, Register temp, Register output) { + void atomicFetchXor16SignExtend(const S& src, const T& mem, Register temp, Register output) { ATOMIC_BITOP_BODY(movw, xorl, lock_cmpxchgw) movswl(eax, eax); } template - void atomicFetchXor16ZeroExtend(const S &src, const T &mem, Register temp, Register output) { + void atomicFetchXor16ZeroExtend(const S& src, const T& mem, Register temp, Register output) { ATOMIC_BITOP_BODY(movw, xorl, lock_cmpxchgw) movzwl(eax, eax); } template - void atomicFetchXor32(const S &src, const T &mem, Register temp, Register output) { + void atomicFetchXor32(const S& src, const T& mem, Register temp, Register output) { ATOMIC_BITOP_BODY(movl, xorl, lock_cmpxchgl) } @@ -665,7 +665,7 @@ class MacroAssemblerX86Shared : public Assembler AutoEnsureByteRegister(MacroAssemblerX86Shared* masm, T address, Register reg) : masm(masm), original_(reg) { - GeneralRegisterSet singleByteRegs(Registers::SingleByteRegs); + AllocatableGeneralRegisterSet singleByteRegs(Registers::SingleByteRegs); if (singleByteRegs.has(reg)) { substitute_ = reg; } else { @@ -720,7 +720,7 @@ class MacroAssemblerX86Shared : public Assembler movzbl(output, output); } template - void compareExchange8SignExtend(const T &mem, Register oldval, Register newval, Register output) { + void compareExchange8SignExtend(const T& mem, Register oldval, Register newval, Register output) { MOZ_ASSERT(output == eax); CHECK_BYTEREG(newval); if (oldval != output) @@ -728,18 +728,18 @@ class MacroAssemblerX86Shared : public Assembler lock_cmpxchgb(newval, Operand(mem)); movsbl(output, output); } - void load16ZeroExtend(const Address &src, Register dest) { + void load16ZeroExtend(const Address& src, Register dest) { movzwl(Operand(src), dest); } - void load16ZeroExtend(const BaseIndex &src, Register dest) { + void load16ZeroExtend(const BaseIndex& src, Register dest) { movzwl(Operand(src), dest); } template - void store16(const S &src, const T &dest) { + void store16(const S& src, const T& dest) { movw(src, Operand(dest)); } template - void compareExchange16ZeroExtend(const T &mem, Register oldval, Register newval, Register output) { + void compareExchange16ZeroExtend(const T& mem, Register oldval, Register newval, Register output) { MOZ_ASSERT(output == eax); if (oldval != output) movl(oldval, output); @@ -747,50 +747,50 @@ class MacroAssemblerX86Shared : public Assembler movzwl(output, output); } template - void compareExchange16SignExtend(const T &mem, Register oldval, Register newval, Register output) { + void compareExchange16SignExtend(const T& mem, Register oldval, Register newval, Register output) { MOZ_ASSERT(output == eax); if (oldval != output) movl(oldval, output); lock_cmpxchgw(newval, Operand(mem)); movswl(output, output); } - void load16SignExtend(const Address &src, Register dest) { + void load16SignExtend(const Address& src, Register dest) { movswl(Operand(src), dest); } - void load16SignExtend(const BaseIndex &src, Register dest) { + void load16SignExtend(const BaseIndex& src, Register dest) { movswl(Operand(src), dest); } - void load32(const Address &address, Register dest) { + void load32(const Address& address, Register dest) { movl(Operand(address), dest); } - void load32(const BaseIndex &src, Register dest) { + void load32(const BaseIndex& src, Register dest) { movl(Operand(src), dest); } - void load32(const Operand &src, Register dest) { + void load32(const Operand& src, Register dest) { movl(src, dest); } template - void store32(const S &src, const T &dest) { + void store32(const S& src, const T& dest) { movl(src, Operand(dest)); } template - void compareExchange32(const T &mem, Register oldval, Register newval, Register output) { + void compareExchange32(const T& mem, Register oldval, Register newval, Register output) { MOZ_ASSERT(output == eax); if (oldval != output) movl(oldval, output); lock_cmpxchgl(newval, Operand(mem)); } template - void store32_NoSecondScratch(const S &src, const T &dest) { + void store32_NoSecondScratch(const S& src, const T& dest) { store32(src, dest); } - void loadDouble(const Address &src, FloatRegister dest) { + void loadDouble(const Address& src, FloatRegister dest) { vmovsd(src, dest); } - void loadDouble(const BaseIndex &src, FloatRegister dest) { + void loadDouble(const BaseIndex& src, FloatRegister dest) { vmovsd(src, dest); } - void loadDouble(const Operand &src, FloatRegister dest) { + void loadDouble(const Operand& src, FloatRegister dest) { switch (src.kind()) { case Operand::MEM_REG_DISP: loadDouble(src.toAddress(), dest); @@ -802,13 +802,13 @@ class MacroAssemblerX86Shared : public Assembler MOZ_CRASH("unexpected operand kind"); } } - void storeDouble(FloatRegister src, const Address &dest) { + void storeDouble(FloatRegister src, const Address& dest) { vmovsd(src, dest); } - void storeDouble(FloatRegister src, const BaseIndex &dest) { + void storeDouble(FloatRegister src, const BaseIndex& dest) { vmovsd(src, dest); } - void storeDouble(FloatRegister src, const Operand &dest) { + void storeDouble(FloatRegister src, const Operand& dest) { switch (dest.kind()) { case Operand::MEM_REG_DISP: storeDouble(src, dest.toAddress()); @@ -900,24 +900,24 @@ class MacroAssemblerX86Shared : public Assembler vpxor(dest, dest, dest); } - template inline void loadScalar(const Operand &src, Reg dest); - template inline void storeScalar(Reg src, const Address &dest); - template inline void loadAlignedVector(const Address &src, FloatRegister dest); - template inline void storeAlignedVector(FloatRegister src, const Address &dest); + template inline void loadScalar(const Operand& src, Reg dest); + template inline void storeScalar(Reg src, const Address& dest); + template inline void loadAlignedVector(const Address& src, FloatRegister dest); + template inline void storeAlignedVector(FloatRegister src, const Address& dest); - void loadInt32x1(const Address &src, FloatRegister dest) { + void loadInt32x1(const Address& src, FloatRegister dest) { vmovd(Operand(src), dest); } - void loadInt32x1(const BaseIndex &src, FloatRegister dest) { + void loadInt32x1(const BaseIndex& src, FloatRegister dest) { vmovd(Operand(src), dest); } - void loadInt32x2(const Address &src, FloatRegister dest) { + void loadInt32x2(const Address& src, FloatRegister dest) { vmovq(Operand(src), dest); } - void loadInt32x2(const BaseIndex &src, FloatRegister dest) { + void loadInt32x2(const BaseIndex& src, FloatRegister dest) { vmovq(Operand(src), dest); } - void loadInt32x3(const BaseIndex &src, FloatRegister dest) { + void loadInt32x3(const BaseIndex& src, FloatRegister dest) { BaseIndex srcZ(src); srcZ.offset += 2 * sizeof(int32_t); @@ -925,7 +925,7 @@ class MacroAssemblerX86Shared : public Assembler vmovd(Operand(srcZ), ScratchSimdReg); vmovlhps(ScratchSimdReg, dest, dest); } - void loadInt32x3(const Address &src, FloatRegister dest) { + void loadInt32x3(const Address& src, FloatRegister dest) { Address srcZ(src); srcZ.offset += 2 * sizeof(int32_t); @@ -934,13 +934,13 @@ class MacroAssemblerX86Shared : public Assembler vmovlhps(ScratchSimdReg, dest, dest); } - void loadAlignedInt32x4(const Address &src, FloatRegister dest) { + void loadAlignedInt32x4(const Address& src, FloatRegister dest) { vmovdqa(Operand(src), dest); } - void loadAlignedInt32x4(const Operand &src, FloatRegister dest) { + void loadAlignedInt32x4(const Operand& src, FloatRegister dest) { vmovdqa(src, dest); } - void storeAlignedInt32x4(FloatRegister src, const Address &dest) { + void storeAlignedInt32x4(FloatRegister src, const Address& dest) { vmovdqa(src, Operand(dest)); } void moveInt32x4(FloatRegister src, FloatRegister dest) { @@ -1049,14 +1049,14 @@ class MacroAssemblerX86Shared : public Assembler vpsrld(count, dest, dest); } - void loadFloat32x3(const Address &src, FloatRegister dest) { + void loadFloat32x3(const Address& src, FloatRegister dest) { Address srcZ(src); srcZ.offset += 2 * sizeof(float); vmovsd(src, dest); vmovss(srcZ, ScratchSimdReg); vmovlhps(ScratchSimdReg, dest, dest); } - void loadFloat32x3(const BaseIndex &src, FloatRegister dest) { + void loadFloat32x3(const BaseIndex& src, FloatRegister dest) { BaseIndex srcZ(src); srcZ.offset += 2 * sizeof(float); vmovsd(src, dest); @@ -1064,28 +1064,28 @@ class MacroAssemblerX86Shared : public Assembler vmovlhps(ScratchSimdReg, dest, dest); } - void loadAlignedFloat32x4(const Address &src, FloatRegister dest) { + void loadAlignedFloat32x4(const Address& src, FloatRegister dest) { vmovaps(Operand(src), dest); } - void loadAlignedFloat32x4(const Operand &src, FloatRegister dest) { + void loadAlignedFloat32x4(const Operand& src, FloatRegister dest) { vmovaps(src, dest); } - void storeFloat32x3(FloatRegister src, const Address &dest) { + void storeFloat32x3(FloatRegister src, const Address& dest) { Address destZ(dest); destZ.offset += 2 * sizeof(int32_t); storeDouble(src, dest); vmovhlps(src, ScratchSimdReg, ScratchSimdReg); storeFloat32(ScratchSimdReg, destZ); } - void storeFloat32x3(FloatRegister src, const BaseIndex &dest) { + void storeFloat32x3(FloatRegister src, const BaseIndex& dest) { BaseIndex destZ(dest); destZ.offset += 2 * sizeof(int32_t); storeDouble(src, dest); vmovhlps(src, ScratchSimdReg, ScratchSimdReg); storeFloat32(ScratchSimdReg, destZ); } - void storeAlignedFloat32x4(FloatRegister src, const Address &dest) { + void storeAlignedFloat32x4(FloatRegister src, const Address& dest) { vmovaps(src, Operand(dest)); } void moveFloat32x4(FloatRegister src, FloatRegister dest) { @@ -1334,7 +1334,7 @@ class MacroAssemblerX86Shared : public Assembler void emitSet(Assembler::Condition cond, Register dest, Assembler::NaNCond ifNaN = Assembler::NaN_HandledByCond) { - if (GeneralRegisterSet(Registers::SingleByteRegs).has(dest)) { + if (AllocatableGeneralRegisterSet(Registers::SingleByteRegs).has(dest)) { // If the register we're defining is a single byte register, // take advantage of the setCC instruction setCC(cond, dest); @@ -1472,4 +1472,4 @@ MacroAssemblerX86Shared::storeScalar(FloatRegister src, const Address &de #undef CHECK_BYTEREG #undef CHECK_BYTEREGS -#endif /* jit_shared_MacroAssembler_x86_shared_h */ +#endif /* jit_x86_shared_MacroAssembler_x86_shared_h */ diff --git a/js/src/jit/shared/MoveEmitter-x86-shared.cpp b/js/src/jit/x86-shared/MoveEmitter-x86-shared.cpp similarity index 99% rename from js/src/jit/shared/MoveEmitter-x86-shared.cpp rename to js/src/jit/x86-shared/MoveEmitter-x86-shared.cpp index 73a31788fd..beb9a60cbf 100644 --- a/js/src/jit/shared/MoveEmitter-x86-shared.cpp +++ b/js/src/jit/x86-shared/MoveEmitter-x86-shared.cpp @@ -4,12 +4,12 @@ * 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/. */ -#include "jit/shared/MoveEmitter-x86-shared.h" +#include "jit/x86-shared/MoveEmitter-x86-shared.h" using namespace js; using namespace js::jit; -MoveEmitterX86::MoveEmitterX86(MacroAssembler &masm) +MoveEmitterX86::MoveEmitterX86(MacroAssembler& masm) : inCycle_(false), masm(masm), pushedAtCycle_(-1) diff --git a/js/src/jit/shared/MoveEmitter-x86-shared.h b/js/src/jit/x86-shared/MoveEmitter-x86-shared.h similarity index 99% rename from js/src/jit/shared/MoveEmitter-x86-shared.h rename to js/src/jit/x86-shared/MoveEmitter-x86-shared.h index caf73829f2..f37d958ea7 100644 --- a/js/src/jit/shared/MoveEmitter-x86-shared.h +++ b/js/src/jit/x86-shared/MoveEmitter-x86-shared.h @@ -18,7 +18,7 @@ class CodeGenerator; class MoveEmitterX86 { bool inCycle_; - MacroAssembler &masm; + MacroAssembler& masm; // Original stack push value. uint32_t pushedAtStart_; diff --git a/js/src/jit/shared/Patching-x86-shared.h b/js/src/jit/x86-shared/Patching-x86-shared.h similarity index 95% rename from js/src/jit/shared/Patching-x86-shared.h rename to js/src/jit/x86-shared/Patching-x86-shared.h index 60ffe0c2cd..317bebe921 100644 --- a/js/src/jit/shared/Patching-x86-shared.h +++ b/js/src/jit/x86-shared/Patching-x86-shared.h @@ -4,8 +4,8 @@ * 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 jit_shared_Patching_x86_shared_h -#define jit_shared_Patching_x86_shared_h +#ifndef jit_x86_shared_Patching_x86_shared_h +#define jit_x86_shared_Patching_x86_shared_h namespace js { namespace jit { @@ -134,4 +134,4 @@ CanRelinkJump(void* from, void* to) } // namespace jit } // namespace js -#endif /* jit_shared_Patching_x86_shared_h */ +#endif /* jit_x86_shared_Patching_x86_shared_h */ diff --git a/js/src/jit/x86/Architecture-x86.h b/js/src/jit/x86/Architecture-x86.h deleted file mode 100644 index 901a656c3c..0000000000 --- a/js/src/jit/x86/Architecture-x86.h +++ /dev/null @@ -1,340 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jit_x86_Architecture_x86_h -#define jit_x86_Architecture_x86_h - -#include "jit/shared/Constants-x86-shared.h" - -namespace js { -namespace jit { - -// In bytes: slots needed for potential memory->memory move spills. -// +8 for cycles -// +4 for gpr spills -// +8 for double spills -static const uint32_t ION_FRAME_SLACK_SIZE = 20; - -// Only Win64 requires shadow stack space. -static const uint32_t ShadowStackSpace = 0; - -// These offsets are specific to nunboxing, and capture offsets into the -// components of a js::Value. -static const int32_t NUNBOX32_TYPE_OFFSET = 4; -static const int32_t NUNBOX32_PAYLOAD_OFFSET = 0; - -//// -// These offsets are related to bailouts. -//// - -// Size of each bailout table entry. On x86 this is a 5-byte relative call. -static const uint32_t BAILOUT_TABLE_ENTRY_SIZE = 5; - -class Registers { - public: - typedef X86Encoding::RegisterID Code; - typedef X86Encoding::RegisterID Encoding; - - // Content spilled during bailouts. - union RegisterContent { - uintptr_t r; - }; - - typedef uint8_t SetType; - static uint32_t SetSize(SetType x) { - static_assert(sizeof(SetType) == 1, "SetType must be 8 bits"); - return mozilla::CountPopulation32(x); - } - static uint32_t FirstBit(SetType x) { - return mozilla::CountTrailingZeroes32(x); - } - static uint32_t LastBit(SetType x) { - return 31 - mozilla::CountLeadingZeroes32(x); - } - static const char* GetName(Code code) { - return X86Encoding::GPRegName(code); - } - - static Code FromName(const char* name) { - for (size_t i = 0; i < Total; i++) { - if (strcmp(GetName(Code(i)), name) == 0) - return Code(i); - } - return Invalid; - } - - static const Code StackPointer = X86Encoding::rsp; - static const Code Invalid = X86Encoding::invalid_reg; - - static const uint32_t Total = 8; - static const uint32_t TotalPhys = 8; - static const uint32_t Allocatable = 7; - - static const SetType AllMask = (1 << Total) - 1; - - static const SetType ArgRegMask = 0; - - static const SetType VolatileMask = - (1 << X86Encoding::rax) | - (1 << X86Encoding::rcx) | - (1 << X86Encoding::rdx); - - static const SetType NonVolatileMask = - (1 << X86Encoding::rbx) | - (1 << X86Encoding::rsi) | - (1 << X86Encoding::rdi) | - (1 << X86Encoding::rbp); - - static const SetType WrapperMask = - VolatileMask | - (1 << X86Encoding::rbx); - - static const SetType SingleByteRegs = - (1 << X86Encoding::rax) | - (1 << X86Encoding::rcx) | - (1 << X86Encoding::rdx) | - (1 << X86Encoding::rbx); - - static const SetType NonAllocatableMask = - (1 << X86Encoding::rsp); - - static const SetType AllocatableMask = AllMask & ~NonAllocatableMask; - - // Registers that can be allocated without being saved, generally. - static const SetType TempMask = VolatileMask & ~NonAllocatableMask; - - // Registers returned from a JS -> JS call. - static const SetType JSCallMask = - (1 << X86Encoding::rcx) | - (1 << X86Encoding::rdx); - - // Registers returned from a JS -> C call. - static const SetType CallMask = - (1 << X86Encoding::rax); -}; - -// Smallest integer type that can hold a register bitmask. -typedef uint8_t PackedRegisterMask; - -class FloatRegisters { - public: - typedef X86Encoding::XMMRegisterID Encoding; - - enum ContentType { - Single, - Double, - Int32x4, - Float32x4, - NumTypes - }; - - // Content spilled during bailouts. - union RegisterContent { - float s; - double d; - int32_t i4[4]; - float s4[4]; - }; - - static const char *GetName(Encoding code) { - return X86Encoding::XMMRegName(code); - } - - static Encoding FromName(const char* name) { - for (size_t i = 0; i < Total; i++) { - if (strcmp(GetName(Encoding(i)), name) == 0) - return Encoding(i); - } - return Invalid; - } - - static const Encoding Invalid = X86Encoding::invalid_xmm; - - static const uint32_t Total = 8 * NumTypes; - static const uint32_t TotalPhys = 8; - static const uint32_t Allocatable = 7; - - typedef uint32_t SetType; - static_assert(sizeof(SetType) * 8 >= Total, - "SetType should be large enough to enumerate all registers."); - - // Magic values which are used to duplicate a mask of physical register for - // a specific type of register. A multiplication is used to copy and shift - // the bits of the physical register mask. - static const SetType SpreadSingle = SetType(1) << (uint32_t(Single) * TotalPhys); - static const SetType SpreadDouble = SetType(1) << (uint32_t(Double) * TotalPhys); - static const SetType SpreadInt32x4 = SetType(1) << (uint32_t(Int32x4) * TotalPhys); - static const SetType SpreadFloat32x4 = SetType(1) << (uint32_t(Float32x4) * TotalPhys); - static const SetType SpreadScalar = SpreadSingle | SpreadDouble; - static const SetType SpreadVector = SpreadInt32x4 | SpreadFloat32x4; - static const SetType Spread = SpreadScalar | SpreadVector; - - static const SetType AllPhysMask = ((1 << TotalPhys) - 1); - static const SetType AllMask = AllPhysMask * Spread; - static const SetType AllDoubleMask = AllPhysMask * SpreadDouble; - static const SetType VolatileMask = AllMask; - static const SetType NonVolatileMask = 0; - - static const SetType WrapperMask = VolatileMask; - - static const SetType NonAllocatableMask = - Spread * (1 << X86Encoding::xmm7); // This is ScratchDoubleReg. - - static const SetType AllocatableMask = AllMask & ~NonAllocatableMask; -}; - -template -class TypedRegisterSet; - -struct FloatRegister { - typedef FloatRegisters Codes; - typedef size_t Code; - typedef Codes::Encoding Encoding; - typedef Codes::SetType SetType; - static uint32_t SetSize(SetType x) { - static_assert(sizeof(SetType) == 4, "SetType must be 32 bits"); - // Count the number of non-aliased registers, for the moment. - // - // Copy the set bits of each typed register to the low part of the of - // the Set, and count the number of registers. This is made to avoid - // registers which are allocated twice with different types (such as in - // AllMask). - x |= x >> (2 * Codes::TotalPhys); - x |= x >> Codes::TotalPhys; - x &= Codes::AllPhysMask; - static_assert(Codes::AllPhysMask <= 0xffff, "We can safely use CountPopulation32"); - return mozilla::CountPopulation32(x); - } - static uint32_t FirstBit(SetType x) { - return mozilla::CountTrailingZeroes32(x); - } - static uint32_t LastBit(SetType x) { - return 31 - mozilla::CountLeadingZeroes32(x); - } - - private: - // Note: These fields are using one extra bit to make the invalid enumerated - // values fit, and thus prevent a warning. - Codes::Encoding reg_ : 4; - Codes::ContentType type_ : 3; - bool isInvalid_ : 1; - - // Constants used for exporting/importing the float register code. - static const size_t RegSize = 3; - static const size_t RegMask = (1 << RegSize) - 1; - - public: - MOZ_CONSTEXPR FloatRegister() - : reg_(Codes::Encoding(0)), type_(Codes::Single), isInvalid_(true) - { } - MOZ_CONSTEXPR FloatRegister(uint32_t r, Codes::ContentType k) - : reg_(Codes::Encoding(r)), type_(k), isInvalid_(false) - { } - - static FloatRegister FromCode(uint32_t i) { - MOZ_ASSERT(i < Codes::Total); - return FloatRegister(i & RegMask, Codes::ContentType(i >> RegSize)); - } - - bool isSingle() const { MOZ_ASSERT(!isInvalid()); return type_ == Codes::Single; } - bool isDouble() const { MOZ_ASSERT(!isInvalid()); return type_ == Codes::Double; } - bool isInt32x4() const { MOZ_ASSERT(!isInvalid()); return type_ == Codes::Int32x4; } - bool isFloat32x4() const { MOZ_ASSERT(!isInvalid()); return type_ == Codes::Float32x4; } - bool isInvalid() const { return isInvalid_; } - - FloatRegister asSingle() const { MOZ_ASSERT(!isInvalid()); return FloatRegister(reg_, Codes::Single); } - FloatRegister asDouble() const { MOZ_ASSERT(!isInvalid()); return FloatRegister(reg_, Codes::Double); } - FloatRegister asInt32x4() const { MOZ_ASSERT(!isInvalid()); return FloatRegister(reg_, Codes::Int32x4); } - FloatRegister asFloat32x4() const { MOZ_ASSERT(!isInvalid()); return FloatRegister(reg_, Codes::Float32x4); } - - uint32_t size() const { - MOZ_ASSERT(!isInvalid()); - if (isSingle()) - return sizeof(float); - if (isDouble()) - return sizeof(double); - MOZ_ASSERT(isInt32x4() || isFloat32x4()); - return 4 * sizeof(int32_t); - } - - Code code() const { - MOZ_ASSERT(!isInvalid()); - MOZ_ASSERT(uint32_t(reg_) < Codes::TotalPhys); - // :TODO: ARM is doing the same thing, but we should avoid this, except - // that the RegisterSets depends on this. - return Code(reg_ | (type_ << RegSize)); - } - Encoding encoding() const { - MOZ_ASSERT(!isInvalid()); - MOZ_ASSERT(uint32_t(reg_) < Codes::TotalPhys); - return reg_; - } - // defined in Assembler-x86-shared.cpp - const char *name() const; - bool volatile_() const { - return !!((SetType(1) << code()) & FloatRegisters::VolatileMask); - } - bool operator !=(FloatRegister other) const { - return other.reg_ != reg_ || other.type_ != type_; - } - bool operator ==(FloatRegister other) const { - return other.reg_ == reg_ && other.type_ == type_; - } - bool aliases(FloatRegister other) const { - return other.reg_ == reg_; - } - // Check if two floating point registers have the same type. - bool equiv(FloatRegister other) const { - return other.type_ == type_; - } - - uint32_t numAliased() const { - return Codes::NumTypes; - } - uint32_t numAlignedAliased() const { - return numAliased(); - } - - // N.B. FloatRegister is an explicit outparam here because msvc-2010 - // miscompiled it on win64 when the value was simply returned - void aliased(uint32_t aliasIdx, FloatRegister *ret) const { - MOZ_ASSERT(aliasIdx < Codes::NumTypes); - *ret = FloatRegister(reg_, Codes::ContentType((aliasIdx + type_) % Codes::NumTypes)); - } - void alignedAliased(uint32_t aliasIdx, FloatRegister *ret) const { - aliased(aliasIdx, ret); - } - - static TypedRegisterSet ReduceSetForPush(const TypedRegisterSet &s); - static uint32_t GetPushSizeInBytes(const TypedRegisterSet &s); - uint32_t getRegisterDumpOffsetInBytes(); -}; - -// Arm/D32 has double registers that can NOT be treated as float32 -// and this requires some dances in lowering. -inline bool -hasUnaliasedDouble() -{ - return false; -} - -// On ARM, Dn aliases both S2n and S2n+1, so if you need to convert a float32 -// to a double as a temporary, you need a temporary double register. -inline bool -hasMultiAlias() -{ - return false; -} - -// Support some constant-offset addressing. -// See the comments above AsmJSMappedSize in AsmJSValidate.h for more info. -static const size_t AsmJSCheckedImmediateRange = 4096; -static const size_t AsmJSImmediateRange = UINT32_C(0x80000000); - -} // namespace jit -} // namespace js - -#endif /* jit_x86_Architecture_x86_h */ diff --git a/js/src/jit/x86/Assembler-x86.cpp b/js/src/jit/x86/Assembler-x86.cpp index 4c8514a180..9e8f5726bb 100644 --- a/js/src/jit/x86/Assembler-x86.cpp +++ b/js/src/jit/x86/Assembler-x86.cpp @@ -92,7 +92,7 @@ CodeFromJump(uint8_t* jump) } void -Assembler::TraceJumpRelocations(JSTracer *trc, JitCode *code, CompactBufferReader &reader) +Assembler::TraceJumpRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader) { RelocationIterator iter(reader); while (iter.read()) { @@ -101,43 +101,3 @@ Assembler::TraceJumpRelocations(JSTracer *trc, JitCode *code, CompactBufferReade MOZ_ASSERT(child == CodeFromJump(code->raw() + iter.offset())); } } - -FloatRegisterSet -FloatRegister::ReduceSetForPush(const FloatRegisterSet &s) -{ - if (JitSupportsSimd()) - return s; - - // Ignore all SIMD register. - return FloatRegisterSet(s.bits() & (Codes::AllPhysMask * Codes::SpreadScalar)); -} -uint32_t -FloatRegister::GetPushSizeInBytes(const FloatRegisterSet &s) -{ - SetType all = s.bits(); - SetType float32x4Set = - (all >> (uint32_t(Codes::Float32x4) * Codes::TotalPhys)) & Codes::AllPhysMask; - SetType int32x4Set = - (all >> (uint32_t(Codes::Int32x4) * Codes::TotalPhys)) & Codes::AllPhysMask; - SetType doubleSet = - (all >> (uint32_t(Codes::Double) * Codes::TotalPhys)) & Codes::AllPhysMask; - SetType singleSet = - (all >> (uint32_t(Codes::Single) * Codes::TotalPhys)) & Codes::AllPhysMask; - - // PushRegsInMask pushes the largest register first, and thus avoids pushing - // aliased registers. So we have to filter out the physical registers which - // are already pushed as part of larger registers. - SetType set128b = int32x4Set | float32x4Set; - SetType set64b = doubleSet & ~set128b; - SetType set32b = singleSet & ~set64b & ~set128b; - - static_assert(Codes::AllPhysMask <= 0xffff, "We can safely use CountPopulation32"); - return mozilla::CountPopulation32(set128b) * (4 * sizeof(int32_t)) - + mozilla::CountPopulation32(set64b) * sizeof(double) - + mozilla::CountPopulation32(set32b) * sizeof(float); -} -uint32_t -FloatRegister::getRegisterDumpOffsetInBytes() -{ - return uint32_t(encoding()) * sizeof(FloatRegisters::RegisterContent); -} diff --git a/js/src/jit/x86/Assembler-x86.h b/js/src/jit/x86/Assembler-x86.h index d5a2e83320..85b05b18fe 100644 --- a/js/src/jit/x86/Assembler-x86.h +++ b/js/src/jit/x86/Assembler-x86.h @@ -13,7 +13,7 @@ #include "jit/IonCode.h" #include "jit/JitCompartment.h" #include "jit/shared/Assembler-shared.h" -#include "jit/shared/Constants-x86-shared.h" +#include "jit/x86-shared/Constants-x86-shared.h" namespace js { namespace jit { @@ -153,7 +153,7 @@ static const Scale ScalePointer = TimesFour; } // namespace jit } // namespace js -#include "jit/shared/Assembler-x86-shared.h" +#include "jit/x86-shared/Assembler-x86-shared.h" namespace js { namespace jit { diff --git a/js/src/jit/x86/BaselineCompiler-x86.h b/js/src/jit/x86/BaselineCompiler-x86.h index c137a31474..a0311bc557 100644 --- a/js/src/jit/x86/BaselineCompiler-x86.h +++ b/js/src/jit/x86/BaselineCompiler-x86.h @@ -7,7 +7,7 @@ #ifndef jit_x86_BaselineCompiler_x86_h #define jit_x86_BaselineCompiler_x86_h -#include "jit/shared/BaselineCompiler-x86-shared.h" +#include "jit/x86-shared/BaselineCompiler-x86-shared.h" namespace js { namespace jit { diff --git a/js/src/jit/x86/CodeGenerator-x86.h b/js/src/jit/x86/CodeGenerator-x86.h index fb5ff06fc2..9ae385d593 100644 --- a/js/src/jit/x86/CodeGenerator-x86.h +++ b/js/src/jit/x86/CodeGenerator-x86.h @@ -7,7 +7,7 @@ #ifndef jit_x86_CodeGenerator_x86_h #define jit_x86_CodeGenerator_x86_h -#include "jit/shared/CodeGenerator-x86-shared.h" +#include "jit/x86-shared/CodeGenerator-x86-shared.h" #include "jit/x86/Assembler-x86.h" namespace js { diff --git a/js/src/jit/x86/Lowering-x86.cpp b/js/src/jit/x86/Lowering-x86.cpp index fed94464cf..7661391297 100644 --- a/js/src/jit/x86/Lowering-x86.cpp +++ b/js/src/jit/x86/Lowering-x86.cpp @@ -15,7 +15,7 @@ using namespace js; using namespace js::jit; void -LIRGeneratorX86::useBoxFixed(LInstruction *lir, size_t n, MDefinition *mir, Register reg1, +LIRGeneratorX86::useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register reg2) { MOZ_ASSERT(mir->type() == MIRType_Value); @@ -226,7 +226,7 @@ LIRGeneratorX86::visitAsmJSStoreHeap(MAsmJSStoreHeap* ins) ? useRegisterAtStart(ptr) : useRegisterOrZeroAtStart(ptr); - LAsmJSStoreHeap *lir = nullptr; + LAsmJSStoreHeap* lir = nullptr; switch (ins->accessType()) { case Scalar::Int8: case Scalar::Uint8: // See comment for LIRGeneratorX86::useByteOpRegister. @@ -272,11 +272,11 @@ LIRGeneratorX86::visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic } void -LIRGeneratorX86::visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap *ins) +LIRGeneratorX86::visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap* ins) { MOZ_ASSERT(ins->accessType() < Scalar::Float32); - MDefinition *ptr = ins->ptr(); + MDefinition* ptr = ins->ptr(); MOZ_ASSERT(ptr->type() == MIRType_Int32); bool byteArray = byteSize(ins->accessType()) == 1; @@ -296,7 +296,7 @@ LIRGeneratorX86::visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap *ins) const LAllocation oldval = useRegister(ins->oldValue()); const LAllocation newval = byteArray ? useFixed(ins->newValue(), ebx) : useRegister(ins->newValue()); - LAsmJSCompareExchangeHeap *lir = + LAsmJSCompareExchangeHeap* lir = new(alloc()) LAsmJSCompareExchangeHeap(useRegister(ptr), oldval, newval); lir->setAddrTemp(temp()); @@ -304,11 +304,11 @@ LIRGeneratorX86::visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap *ins) } void -LIRGeneratorX86::visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap *ins) +LIRGeneratorX86::visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap* ins) { MOZ_ASSERT(ins->accessType() < Scalar::Float32); - MDefinition *ptr = ins->ptr(); + MDefinition* ptr = ins->ptr(); MOZ_ASSERT(ptr->type() == MIRType_Int32); bool byteArray = byteSize(ins->accessType()) == 1; @@ -364,7 +364,7 @@ LIRGeneratorX86::visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap *ins) tempDef = temp(); } - LAsmJSAtomicBinopHeap *lir = + LAsmJSAtomicBinopHeap* lir = new(alloc()) LAsmJSAtomicBinopHeap(useRegister(ptr), value, tempDef); lir->setAddrTemp(temp()); diff --git a/js/src/jit/x86/Lowering-x86.h b/js/src/jit/x86/Lowering-x86.h index 9bd5dc1c85..044b5d4f42 100644 --- a/js/src/jit/x86/Lowering-x86.h +++ b/js/src/jit/x86/Lowering-x86.h @@ -7,7 +7,7 @@ #ifndef jit_x86_Lowering_x86_h #define jit_x86_Lowering_x86_h -#include "jit/shared/Lowering-x86-shared.h" +#include "jit/x86-shared/Lowering-x86-shared.h" namespace js { namespace jit { diff --git a/js/src/jit/x86/MacroAssembler-x86.h b/js/src/jit/x86/MacroAssembler-x86.h index 940b6806b0..c67c6cfd9f 100644 --- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -11,7 +11,7 @@ #include "jit/JitFrames.h" #include "jit/MoveResolver.h" -#include "jit/shared/MacroAssembler-x86-shared.h" +#include "jit/x86-shared/MacroAssembler-x86-shared.h" namespace js { namespace jit { @@ -20,8 +20,8 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared { private: // Perform a downcast. Should be removed by Bug 996602. - MacroAssembler &asMasm(); - const MacroAssembler &asMasm() const; + MacroAssembler& asMasm(); + const MacroAssembler& asMasm() const; private: // Number of bytes the stack is adjusted inside a call to C. Calls to C may diff --git a/js/src/jit/x86/Trampoline-x86.cpp b/js/src/jit/x86/Trampoline-x86.cpp index 15e4349cd8..340a4703b1 100644 --- a/js/src/jit/x86/Trampoline-x86.cpp +++ b/js/src/jit/x86/Trampoline-x86.cpp @@ -25,9 +25,9 @@ using namespace js::jit; // All registers to save and restore. This includes the stack pointer, since we // use the ability to reference register values on the stack by index. -static const RegisterSet AllRegs = - RegisterSet(GeneralRegisterSet(Registers::AllMask), - FloatRegisterSet(FloatRegisters::AllMask)); +static const LiveRegisterSet AllRegs = + LiveRegisterSet(GeneralRegisterSet(Registers::AllMask), + FloatRegisterSet(FloatRegisters::AllMask)); enum EnterJitEbpArgumentOffset { ARG_JITCODE = 2 * sizeof(void*), @@ -142,7 +142,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type) CodeLabel returnLabel; if (type == EnterJitBaseline) { // Handle OSR. - GeneralRegisterSet regs(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); regs.take(JSReturnOperand); regs.takeUnchecked(OsrFrameReg); regs.take(ebp); @@ -510,12 +510,11 @@ PushBailoutFrame(MacroAssembler& masm, uint32_t frameClass, Register spArg) // the float registers to have the maximal possible size // (Simd128DataSize). To work around this, we just spill the double // registers by hand here, using the register dump offset directly. - RegisterSet set = AllRegs; - for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) + for (GeneralRegisterBackwardIterator iter(AllRegs.gprs()); iter.more(); iter++) masm.Push(*iter); masm.reserveStack(sizeof(RegisterDump::FPUArray)); - for (FloatRegisterBackwardIterator iter(set.fpus()); iter.more(); iter++) { + for (FloatRegisterBackwardIterator iter(AllRegs.fpus()); iter.more(); iter++) { FloatRegister reg = *iter; Address spillAddress(StackPointer, reg.getRegisterDumpOffsetInBytes()); masm.storeDouble(reg, spillAddress); @@ -628,7 +627,7 @@ JitRuntime::generateVMWrapper(JSContext* cx, const VMFunction& f) // Avoid conflicts with argument registers while discarding the result after // the function call. - GeneralRegisterSet regs = GeneralRegisterSet(Register::Codes::WrapperMask); + AllocatableGeneralRegisterSet regs(Register::Codes::WrapperMask); // Wrapper register set is a superset of Volatile register set. JS_STATIC_ASSERT((Register::Codes::VolatileMask & ~Register::Codes::WrapperMask) == 0); @@ -798,13 +797,13 @@ JitRuntime::generatePreBarrier(JSContext* cx, MIRType type) { MacroAssembler masm; - RegisterSet save; + LiveRegisterSet save; if (cx->runtime()->jitSupportsFloatingPoint) { - save = RegisterSet(GeneralRegisterSet(Registers::VolatileMask), - FloatRegisterSet(FloatRegisters::VolatileMask)); + save.set() = RegisterSet(GeneralRegisterSet(Registers::VolatileMask), + FloatRegisterSet(FloatRegisters::VolatileMask)); } else { - save = RegisterSet(GeneralRegisterSet(Registers::VolatileMask), - FloatRegisterSet()); + save.set() = RegisterSet(GeneralRegisterSet(Registers::VolatileMask), + FloatRegisterSet()); } masm.PushRegsInMask(save); diff --git a/js/src/js.msg b/js/src/js.msg index 228757dec5..fa1f481845 100644 --- a/js/src/js.msg +++ b/js/src/js.msg @@ -82,6 +82,7 @@ MSG_DEF(JSMSG_EMPTY_ARRAY_REDUCE, 0, JSEXN_TYPEERR, "reduce of empty array MSG_DEF(JSMSG_UNEXPECTED_TYPE, 2, JSEXN_TYPEERR, "{0} is {1}") MSG_DEF(JSMSG_MISSING_FUN_ARG, 2, JSEXN_TYPEERR, "missing argument {0} when calling function {1}") MSG_DEF(JSMSG_NOT_NONNULL_OBJECT, 1, JSEXN_TYPEERR, "{0} is not a non-null object") +MSG_DEF(JSMSG_SET_NON_OBJECT_RECEIVER, 1, JSEXN_TYPEERR, "can't assign to properties of {0}: not an object") MSG_DEF(JSMSG_INVALID_DESCRIPTOR, 0, JSEXN_TYPEERR, "property descriptors must not specify a value or be writable when a getter or setter has been specified") MSG_DEF(JSMSG_OBJECT_NOT_EXTENSIBLE, 1, JSEXN_TYPEERR, "{0} is not extensible") MSG_DEF(JSMSG_CANT_REDEFINE_PROP, 1, JSEXN_TYPEERR, "can't redefine non-configurable property {0}") diff --git a/js/src/jsapi-tests/moz.build b/js/src/jsapi-tests/moz.build index 8a220c4787..4222e94234 100644 --- a/js/src/jsapi-tests/moz.build +++ b/js/src/jsapi-tests/moz.build @@ -96,6 +96,7 @@ if CONFIG['ENABLE_ION']: 'testJitMoveEmitterCycles-mips.cpp', 'testJitMoveEmitterCycles.cpp', 'testJitRangeAnalysis.cpp', + 'testJitRegisterSet.cpp', 'testJitRValueAlloc.cpp', ] diff --git a/js/src/jsapi-tests/testJitRegisterSet.cpp b/js/src/jsapi-tests/testJitRegisterSet.cpp new file mode 100644 index 0000000000..61acf834ce --- /dev/null +++ b/js/src/jsapi-tests/testJitRegisterSet.cpp @@ -0,0 +1,138 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + */ +/* 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/. */ + +#include "jit/RegisterSets.h" + +#include "jsapi-tests/tests.h" + +using namespace js; +using namespace js::jit; + +static bool +CoPrime(size_t a, size_t b) +{ + if (b <= 1) + return a == 1 || b == 1; + return CoPrime(b, a % b); +} + +// This macros are use to iterave over all registers in a large number of +// non-looping sequences, which does not rely on the getFirst / getLast +// functions. +#define BEGIN_INDEX_WALK(RegTotal) \ + static const size_t Total = RegTotal; \ + for (size_t walk = 1; walk < RegTotal; walk += 2) { \ + if (!CoPrime(RegTotal, walk)) \ + continue; \ + for (size_t start = 0; start < RegTotal; start++) { \ + size_t index = start; + +#define END_INDEX_WALK \ + } \ + } + +#define FOR_ALL_REGISTERS(Register, reg) \ + do { \ + Register reg = Register::FromCode(index); + +#define END_FOR_ALL_REGISTERS \ + index = (index + walk) % Total; \ + } while(index != start) + +BEGIN_TEST(testJitRegisterSet_GPR) +{ + BEGIN_INDEX_WALK(Registers::Total) + + LiveGeneralRegisterSet liveRegs; + AllocatableGeneralRegisterSet pool(GeneralRegisterSet::All()); + CHECK(liveRegs.empty()); + CHECK(pool.set() == GeneralRegisterSet::All()); + + FOR_ALL_REGISTERS(Register, reg) { + + CHECK(!pool.has(reg) || !liveRegs.has(reg)); + if (pool.has(reg)) { + CHECK(!liveRegs.has(reg)); + pool.take(reg); + liveRegs.add(reg); + CHECK(liveRegs.has(reg)); + CHECK(!pool.has(reg)); + } + CHECK(!pool.has(reg) || !liveRegs.has(reg)); + + } END_FOR_ALL_REGISTERS; + + CHECK(pool.empty()); + + FOR_ALL_REGISTERS(Register, reg) { + + CHECK(!pool.has(reg) || !liveRegs.has(reg)); + if (liveRegs.has(reg)) { + CHECK(!pool.has(reg)); + liveRegs.take(reg); + pool.add(reg); + CHECK(pool.has(reg)); + CHECK(!liveRegs.has(reg)); + } + CHECK(!pool.has(reg) || !liveRegs.has(reg)); + + } END_FOR_ALL_REGISTERS; + + CHECK(liveRegs.empty()); + CHECK(pool.set() == GeneralRegisterSet::All()); + + END_INDEX_WALK + return true; +} +END_TEST(testJitRegisterSet_GPR) + +BEGIN_TEST(testJitRegisterSet_FPU) +{ + BEGIN_INDEX_WALK(FloatRegisters::Total) + + LiveFloatRegisterSet liveRegs; + AllocatableFloatRegisterSet pool(FloatRegisterSet::All()); + CHECK(liveRegs.empty()); + CHECK(pool.set() == FloatRegisterSet::All()); + + FOR_ALL_REGISTERS(FloatRegister, reg) { + + CHECK(!pool.has(reg) || !liveRegs.has(reg)); + if (pool.has(reg)) { + CHECK(!liveRegs.has(reg)); + pool.take(reg); + liveRegs.add(reg); + CHECK(liveRegs.has(reg)); + CHECK(!pool.has(reg)); + } + CHECK(!pool.has(reg) || !liveRegs.has(reg)); + + } END_FOR_ALL_REGISTERS; + + CHECK(pool.empty()); + + FOR_ALL_REGISTERS(FloatRegister, reg) { + + CHECK(!pool.has(reg) || !liveRegs.has(reg)); + if (liveRegs.has(reg)) { + CHECK(!pool.has(reg)); + liveRegs.take(reg); + pool.add(reg); + CHECK(pool.has(reg)); + CHECK(!liveRegs.has(reg)); + } + CHECK(!pool.has(reg) || !liveRegs.has(reg)); + + } END_FOR_ALL_REGISTERS; + + CHECK(liveRegs.empty()); + CHECK(pool.set() == FloatRegisterSet::All()); + + END_INDEX_WALK + return true; +} +END_TEST(testJitRegisterSet_FPU) diff --git a/js/src/jsapi-tests/testSetPropertyIgnoringNamedGetter.cpp b/js/src/jsapi-tests/testSetPropertyIgnoringNamedGetter.cpp index d0e66efad3..a7e73775c2 100644 --- a/js/src/jsapi-tests/testSetPropertyIgnoringNamedGetter.cpp +++ b/js/src/jsapi-tests/testSetPropertyIgnoringNamedGetter.cpp @@ -27,13 +27,13 @@ class CustomProxyHandler : public DirectProxyHandler { return impl(cx, proxy, id, desc, true); } - bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, - HandleId id, MutableHandleValue vp, ObjectOpResult &result) const override + bool set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, HandleValue receiver, + ObjectOpResult &result) const override { Rooted desc(cx); if (!DirectProxyHandler::getPropertyDescriptor(cx, proxy, id, &desc)) return false; - return SetPropertyIgnoringNamedGetter(cx, proxy, id, vp, receiver, desc, result); + return SetPropertyIgnoringNamedGetter(cx, proxy, id, v, receiver, desc, result); } private: diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index a2ea0711d8..34bde7a907 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -139,7 +139,7 @@ ErrorTakesIdArgument(unsigned msg) } JS_PUBLIC_API(bool) -JS::ObjectOpResult::reportStrictErrorOrWarning(JSContext *cx, HandleObject obj, HandleId id, +JS::ObjectOpResult::reportStrictErrorOrWarning(JSContext* cx, HandleObject obj, HandleId id, bool strict) { static_assert(unsigned(OkCode) == unsigned(JSMSG_NOT_AN_ERROR), @@ -148,7 +148,7 @@ JS::ObjectOpResult::reportStrictErrorOrWarning(JSContext *cx, HandleObject obj, MOZ_ASSERT(!ok()); unsigned flags = strict ? JSREPORT_ERROR : (JSREPORT_WARNING | JSREPORT_STRICT); - if (code_ == JSMSG_OBJECT_NOT_EXTENSIBLE) { + if (code_ == JSMSG_OBJECT_NOT_EXTENSIBLE || code_ == JSMSG_SET_NON_OBJECT_RECEIVER) { RootedValue val(cx, ObjectValue(*obj)); return ReportValueErrorFlags(cx, flags, code_, JSDVG_IGNORE_STACK, val, NullPtr(), nullptr, nullptr); @@ -170,7 +170,7 @@ JS::ObjectOpResult::reportStrictErrorOrWarning(JSContext *cx, HandleObject obj, } JS_PUBLIC_API(bool) -JS::ObjectOpResult::reportStrictErrorOrWarning(JSContext *cx, HandleObject obj, bool strict) +JS::ObjectOpResult::reportStrictErrorOrWarning(JSContext* cx, HandleObject obj, bool strict) { MOZ_ASSERT(code_ != Uninitialized); MOZ_ASSERT(!ok()); @@ -1987,15 +1987,15 @@ JS_NewObject(JSContext *cx, const JSClass *jsclasp) return NewObjectWithClassProto(cx, clasp, NullPtr()); } -JS_PUBLIC_API(JSObject *) -JS_NewObjectWithGivenProto(JSContext *cx, const JSClass *jsclasp, HandleObject proto) +JS_PUBLIC_API(JSObject*) +JS_NewObjectWithGivenProto(JSContext* cx, const JSClass* jsclasp, HandleObject proto) { MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment())); AssertHeapIsIdle(cx); CHECK_REQUEST(cx); assertSameCompartment(cx, proto); - const Class *clasp = Valueify(jsclasp); + const Class* clasp = Valueify(jsclasp); if (!clasp) clasp = &PlainObject::class_; /* default class is Object */ @@ -2223,7 +2223,7 @@ DefinePropertyById(JSContext* cx, HandleObject obj, HandleId id, HandleValue val RootedAtom atom(cx, JSID_IS_ATOM(id) ? JSID_TO_ATOM(id) : nullptr); if (getter && !(attrs & JSPROP_GETTER)) { RootedObject global(cx, (JSObject*) &obj->global()); - JSFunction *getobj = NewNativeFunction(cx, (Native) getter, 0, atom); + JSFunction* getobj = NewNativeFunction(cx, (Native) getter, 0, atom); if (!getobj) return false; @@ -2237,7 +2237,7 @@ DefinePropertyById(JSContext* cx, HandleObject obj, HandleId id, HandleValue val // Root just the getter, since the setter is not yet a JSObject. AutoRooterGetterSetter getRoot(cx, JSPROP_GETTER, &getter, nullptr); RootedObject global(cx, (JSObject*) &obj->global()); - JSFunction *setobj = NewNativeFunction(cx, (Native) setter, 1, atom); + JSFunction* setobj = NewNativeFunction(cx, (Native) setter, 1, atom); if (!setobj) return false; @@ -2336,8 +2336,8 @@ JS_DefinePropertyById(JSContext* cx, HandleObject obj, HandleId id, double value } static bool -DefinePropertyByDescriptor(JSContext *cx, HandleObject obj, HandleId id, - Handle desc, ObjectOpResult &result) +DefinePropertyByDescriptor(JSContext* cx, HandleObject obj, HandleId id, + Handle desc, ObjectOpResult& result) { AssertHeapIsIdle(cx); CHECK_REQUEST(cx); @@ -2347,14 +2347,14 @@ DefinePropertyByDescriptor(JSContext *cx, HandleObject obj, HandleId id, } JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, - Handle desc, ObjectOpResult &result) +JS_DefinePropertyById(JSContext* cx, HandleObject obj, HandleId id, + Handle desc, ObjectOpResult& result) { return DefinePropertyByDescriptor(cx, obj, id, desc, result); } JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, +JS_DefinePropertyById(JSContext* cx, HandleObject obj, HandleId id, Handle desc) { ObjectOpResult result; @@ -2619,11 +2619,11 @@ JS_DefineUCProperty(JSContext* cx, HandleObject obj, const char16_t* name, size_ } JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen, +JS_DefineUCProperty(JSContext* cx, HandleObject obj, const char16_t* name, size_t namelen, Handle desc, - ObjectOpResult &result) + ObjectOpResult& result) { - JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); + JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); if (!atom) return false; RootedId id(cx, AtomToId(atom)); @@ -2631,10 +2631,10 @@ JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_ } JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen, +JS_DefineUCProperty(JSContext* cx, HandleObject obj, const char16_t* name, size_t namelen, Handle desc) { - JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); + JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); if (!atom) return false; RootedId id(cx, AtomToId(atom)); @@ -2771,7 +2771,7 @@ JS_DefineProperties(JSContext* cx, HandleObject obj, const JSPropertySpec* ps) } JS_PUBLIC_API(bool) -JS::ObjectToCompletePropertyDescriptor(JSContext *cx, +JS::ObjectToCompletePropertyDescriptor(JSContext* cx, HandleObject obj, HandleValue descObj, MutableHandle desc) @@ -2794,10 +2794,10 @@ JS_GetOwnPropertyDescriptorById(JSContext* cx, HandleObject obj, HandleId id, } JS_PUBLIC_API(bool) -JS_GetOwnUCPropertyDescriptor(JSContext *cx, HandleObject obj, const char16_t *name, +JS_GetOwnUCPropertyDescriptor(JSContext* cx, HandleObject obj, const char16_t* name, MutableHandle desc) { - JSAtom *atom = AtomizeChars(cx, name, js_strlen(name)); + JSAtom* atom = AtomizeChars(cx, name, js_strlen(name)); if (!atom) return false; RootedId id(cx, AtomToId(atom)); @@ -2891,83 +2891,77 @@ JS_GetUCProperty(JSContext* cx, HandleObject obj, const char16_t* name, size_t n JS_PUBLIC_API(bool) JS_SetPropertyById(JSContext* cx, HandleObject obj, HandleId id, HandleValue v) { - RootedValue value(cx, v); AssertHeapIsIdle(cx); CHECK_REQUEST(cx); assertSameCompartment(cx, obj, id); + RootedValue receiver(cx, ObjectValue(*obj)); ObjectOpResult ignored; - return SetProperty(cx, obj, obj, id, &value, ignored); + return SetProperty(cx, obj, id, v, receiver, ignored); } JS_PUBLIC_API(bool) -JS_ForwardSetPropertyTo(JSContext *cx, HandleObject obj, HandleId id, HandleValue v, - HandleValue receiver, ObjectOpResult &result) +JS_ForwardSetPropertyTo(JSContext* cx, HandleObject obj, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult& result) { AssertHeapIsIdle(cx); CHECK_REQUEST(cx); assertSameCompartment(cx, obj, id, receiver); - // XXX Bug 603201 will eliminate this ToObject. - RootedObject receiverObj(cx, ToObject(cx, receiver)); - if (!receiverObj) - return false; - - RootedValue value(cx, v); - return SetProperty(cx, obj, receiverObj, id, &value, result); + return SetProperty(cx, obj, id, v, receiver, result); } static bool -SetElement(JSContext *cx, HandleObject obj, uint32_t index, MutableHandleValue vp) +SetElement(JSContext* cx, HandleObject obj, uint32_t index, HandleValue v) { AssertHeapIsIdle(cx); CHECK_REQUEST(cx); - assertSameCompartment(cx, obj, vp); + assertSameCompartment(cx, obj, v); + RootedValue receiver(cx, ObjectValue(*obj)); ObjectOpResult ignored; - return SetElement(cx, obj, obj, index, vp, ignored); + return SetElement(cx, obj, index, v, receiver, ignored); } JS_PUBLIC_API(bool) JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue v) { - RootedValue value(cx, v); - return SetElement(cx, obj, index, &value); + return SetElement(cx, obj, index, v); } JS_PUBLIC_API(bool) JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleObject v) { RootedValue value(cx, ObjectOrNullValue(v)); - return SetElement(cx, obj, index, &value); + return SetElement(cx, obj, index, value); } JS_PUBLIC_API(bool) JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleString v) { RootedValue value(cx, StringValue(v)); - return SetElement(cx, obj, index, &value); + return SetElement(cx, obj, index, value); } JS_PUBLIC_API(bool) JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, int32_t v) { RootedValue value(cx, NumberValue(v)); - return SetElement(cx, obj, index, &value); + return SetElement(cx, obj, index, value); } JS_PUBLIC_API(bool) JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, uint32_t v) { RootedValue value(cx, NumberValue(v)); - return SetElement(cx, obj, index, &value); + return SetElement(cx, obj, index, value); } JS_PUBLIC_API(bool) JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, double v) { RootedValue value(cx, NumberValue(v)); - return SetElement(cx, obj, index, &value); + return SetElement(cx, obj, index, value); } JS_PUBLIC_API(bool) @@ -2992,7 +2986,7 @@ JS_SetUCProperty(JSContext* cx, HandleObject obj, const char16_t* name, size_t n } JS_PUBLIC_API(bool) -JS_DeletePropertyById(JSContext *cx, HandleObject obj, HandleId id, ObjectOpResult &result) +JS_DeletePropertyById(JSContext* cx, HandleObject obj, HandleId id, ObjectOpResult& result) { AssertHeapIsIdle(cx); CHECK_REQUEST(cx); @@ -3002,7 +2996,7 @@ JS_DeletePropertyById(JSContext *cx, HandleObject obj, HandleId id, ObjectOpResu } JS_PUBLIC_API(bool) -JS_DeleteElement(JSContext *cx, HandleObject obj, uint32_t index, ObjectOpResult &result) +JS_DeleteElement(JSContext* cx, HandleObject obj, uint32_t index, ObjectOpResult& result) { AssertHeapIsIdle(cx); CHECK_REQUEST(cx); @@ -3220,8 +3214,8 @@ JS_NewFunction(JSContext *cx, JSNative native, unsigned nargs, unsigned flags, : NewNativeFunction(cx, native, nargs, atom); } -JS_PUBLIC_API(JSFunction *) -JS_NewFunctionById(JSContext *cx, JSNative native, unsigned nargs, unsigned flags, +JS_PUBLIC_API(JSFunction*) +JS_NewFunctionById(JSContext* cx, JSNative native, unsigned nargs, unsigned flags, HandleId id) { MOZ_ASSERT(JSID_IS_STRING(id)); @@ -3257,7 +3251,7 @@ JS::GetSelfHostedFunction(JSContext* cx, const char* selfHostedName, HandleId id } static bool -CreateScopeObjectsForScopeChain(JSContext *cx, AutoObjectVector &scopeChain, +CreateScopeObjectsForScopeChain(JSContext* cx, AutoObjectVector& scopeChain, MutableHandleObject dynamicScopeObj, MutableHandleObject staticScopeObj) { @@ -3849,7 +3843,7 @@ JS::Compile(JSContext *cx, const ReadOnlyCompileOptions &options, } bool -JS::Compile(JSContext *cx, const ReadOnlyCompileOptions &options, FILE *fp, +JS::Compile(JSContext* cx, const ReadOnlyCompileOptions& options, FILE* fp, MutableHandleScript script) { FileContents buffer(cx); @@ -3860,7 +3854,7 @@ JS::Compile(JSContext *cx, const ReadOnlyCompileOptions &options, FILE *fp, } bool -JS::Compile(JSContext *cx, const ReadOnlyCompileOptions &optionsArg, const char *filename, +JS::Compile(JSContext* cx, const ReadOnlyCompileOptions& optionsArg, const char* filename, MutableHandleScript script) { AutoFile file; @@ -4018,9 +4012,9 @@ JS_GetFunctionScript(JSContext* cx, HandleFunction fun) * enclosingDynamicScope is a dynamic scope to use, if it's not the global. */ static bool -CompileFunction(JSContext *cx, const ReadOnlyCompileOptions &optionsArg, - const char *name, unsigned nargs, const char *const *argnames, - SourceBufferHolder &srcBuf, +CompileFunction(JSContext* cx, const ReadOnlyCompileOptions& optionsArg, + const char* name, unsigned nargs, const char* const* argnames, + SourceBufferHolder& srcBuf, HandleObject enclosingDynamicScope, HandleObject enclosingStaticScope, MutableHandleFunction fun) @@ -4516,14 +4510,14 @@ JS_RestoreFrameChain(JSContext* cx) } JS::AutoSetAsyncStackForNewCalls::AutoSetAsyncStackForNewCalls( - JSContext *cx, HandleObject stack, HandleString asyncCause) + JSContext* cx, HandleObject stack, HandleString asyncCause) : cx(cx), oldAsyncStack(cx, cx->runtime()->asyncStackForNewActivations), oldAsyncCause(cx, cx->runtime()->asyncCauseForNewActivations) { CHECK_REQUEST(cx); - SavedFrame *asyncStack = &stack->as(); + SavedFrame* asyncStack = &stack->as(); MOZ_ASSERT(!asyncCause->empty()); cx->runtime()->asyncStackForNewActivations = asyncStack; diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp index 42f83dcdfe..87158c34f5 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -364,8 +364,7 @@ SetArrayElement(JSContext* cx, HandleObject obj, double index, HandleValue v) if (!ToId(cx, index, &id)) return false; - RootedValue tmp(cx, v); - return SetProperty(cx, obj, obj, id, &tmp); + return SetProperty(cx, obj, id, v); } /* @@ -434,7 +433,7 @@ bool js::SetLengthProperty(JSContext* cx, HandleObject obj, double length) { RootedValue v(cx, NumberValue(length)); - return SetProperty(cx, obj, obj, cx->names().length, &v); + return SetProperty(cx, obj, cx->names().length, v); } /* @@ -1270,11 +1269,10 @@ InitArrayElements(JSContext *cx, HandleObject obj, uint32_t start, uint32_t coun do { value = *vector++; indexv = DoubleValue(index); - if (!ValueToId(cx, indexv, &id) || - !SetProperty(cx, obj, obj, id, &value)) - { + if (!ValueToId(cx, indexv, &id)) + return false; + if (!SetProperty(cx, obj, id, value)) return false; - } index += 1; } while (vector != end); diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index 876b4eec94..b2752274b7 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -343,8 +343,8 @@ extern JS_FRIEND_API(bool) proxy_GetProperty(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id, JS::MutableHandleValue vp); extern JS_FRIEND_API(bool) -proxy_SetProperty(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id, - JS::MutableHandleValue bp, JS::ObjectOpResult &result); +proxy_SetProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue bp, + JS::HandleValue receiver, JS::ObjectOpResult &result); extern JS_FRIEND_API(bool) proxy_GetOwnPropertyDescriptor(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandle desc); @@ -1396,7 +1396,7 @@ struct MOZ_STACK_CLASS JS_FRIEND_API(ErrorReport) /* Implemented in vm/StructuredClone.cpp. */ extern JS_FRIEND_API(uint64_t) -GetSCOffset(JSStructuredCloneWriter *writer); +GetSCOffset(JSStructuredCloneWriter* writer); namespace Scalar { @@ -2367,11 +2367,11 @@ struct JSTypedMethodJitInfo namespace js { -static MOZ_ALWAYS_INLINE shadow::Function * -FunctionObjectToShadowFunction(JSObject *fun) +static MOZ_ALWAYS_INLINE shadow::Function* +FunctionObjectToShadowFunction(JSObject* fun) { MOZ_ASSERT(GetObjectClass(fun) == FunctionClassPtr); - return reinterpret_cast(fun); + return reinterpret_cast(fun); } /* Statically asserted in jsfun.h. */ @@ -2379,13 +2379,13 @@ static const unsigned JS_FUNCTION_INTERPRETED_BITS = 0x1001; // Return whether the given function object is native. static MOZ_ALWAYS_INLINE bool -FunctionObjectIsNative(JSObject *fun) +FunctionObjectIsNative(JSObject* fun) { return !(FunctionObjectToShadowFunction(fun)->flags & JS_FUNCTION_INTERPRETED_BITS); } static MOZ_ALWAYS_INLINE JSNative -GetFunctionObjectNative(JSObject *fun) +GetFunctionObjectNative(JSObject* fun) { MOZ_ASSERT(FunctionObjectIsNative(fun)); return FunctionObjectToShadowFunction(fun)->native; @@ -2393,7 +2393,7 @@ GetFunctionObjectNative(JSObject *fun) } // namespace js -static MOZ_ALWAYS_INLINE const JSJitInfo * +static MOZ_ALWAYS_INLINE const JSJitInfo* FUNCTION_VALUE_TO_JITINFO(const JS::Value& v) { MOZ_ASSERT(js::FunctionObjectIsNative(&v.toObject())); @@ -2560,8 +2560,8 @@ class JS_FRIEND_API(AutoCTypesActivityCallback) { } }; -typedef JSObject * -(* ObjectMetadataCallback)(JSContext *cx); +typedef JSObject* +(* ObjectMetadataCallback)(JSContext* cx); /* * Specify a callback to invoke when creating each JS object in the current @@ -2604,7 +2604,7 @@ ForwardToNative(JSContext* cx, JSNative native, const JS::CallArgs& args); */ JS_FRIEND_API(bool) SetPropertyIgnoringNamedGetter(JSContext *cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleValue vp, JS::HandleObject receiver, + JS::HandleValue v, JS::HandleValue receiver, JS::Handle ownDesc, JS::ObjectOpResult &result); diff --git a/js/src/jsgc.h b/js/src/jsgc.h index fddc95cf98..dcc2324316 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -145,7 +145,7 @@ IsBackgroundFinalized(AllocKind kind) } static inline bool -CanBeFinalizedInBackground(AllocKind kind, const Class *clasp) +CanBeFinalizedInBackground(AllocKind kind, const Class* clasp) { MOZ_ASSERT(IsObjectAllocKind(kind)); /* If the class has no finalizer or a finalizer that is safe to call on @@ -477,10 +477,10 @@ class ArenaList { return *this; } - ArenaHeader *removeRemainingArenas(ArenaHeader **arenap); - ArenaHeader **pickArenasToRelocate(size_t &arenaTotalOut, size_t &relocTotalOut); - ArenaHeader *relocateArenas(ArenaHeader *toRelocate, ArenaHeader *relocated, - SliceBudget &sliceBudget, gcstats::Statistics& stats); + ArenaHeader* removeRemainingArenas(ArenaHeader** arenap); + ArenaHeader** pickArenasToRelocate(size_t& arenaTotalOut, size_t& relocTotalOut); + ArenaHeader* relocateArenas(ArenaHeader* toRelocate, ArenaHeader* relocated, + SliceBudget& sliceBudget, gcstats::Statistics& stats); }; /* @@ -596,7 +596,7 @@ class ArenaLists AllAllocKindArray backgroundFinalizeState; /* For each arena kind, a list of arenas remaining to be swept. */ - AllAllocKindArray arenaListsToSweep; + AllAllocKindArray arenaListsToSweep; /* During incremental sweeping, a list of the arenas already swept. */ AllocKind incrementalSweptArenaKind; @@ -604,20 +604,20 @@ class ArenaLists // Arena lists which have yet to be swept, but need additional foreground // processing before they are swept. - ArenaHeader *gcShapeArenasToUpdate; - ArenaHeader *gcAccessorShapeArenasToUpdate; - ArenaHeader *gcScriptArenasToUpdate; - ArenaHeader *gcObjectGroupArenasToUpdate; + ArenaHeader* gcShapeArenasToUpdate; + ArenaHeader* gcAccessorShapeArenasToUpdate; + ArenaHeader* gcScriptArenasToUpdate; + ArenaHeader* gcObjectGroupArenasToUpdate; // While sweeping type information, these lists save the arenas for the // objects which have already been finalized in the foreground (which must // happen at the beginning of the GC), so that type sweeping can determine // which of the object pointers are marked. ObjectAllocKindArray savedObjectArenas; - ArenaHeader *savedEmptyObjectArenas; + ArenaHeader* savedEmptyObjectArenas; public: - explicit ArenaLists(JSRuntime *rt) : runtime_(rt) { + explicit ArenaLists(JSRuntime* rt) : runtime_(rt) { for (auto i : AllAllocKinds()) freeLists[i].initAsEmpty(); for (auto i : AllAllocKinds()) @@ -1168,11 +1168,11 @@ class RelocationOverlay next_ = nullptr; } - RelocationOverlay *next() const { + RelocationOverlay* next() const { return next_; } - static bool isCellForwarded(Cell *cell) { + static bool isCellForwarded(Cell* cell) { return fromCell(cell)->isForwarded(); } }; @@ -1261,7 +1261,7 @@ MaybeForwarded(T t) template inline void -CheckGCThingAfterMovingGC(T *t) +CheckGCThingAfterMovingGC(T* t) { MOZ_ASSERT_IF(t, !IsInsideNursery(t)); MOZ_ASSERT_IF(t, !RelocationOverlay::isCellForwarded(t)); diff --git a/js/src/jsgcinlines.h b/js/src/jsgcinlines.h index f9c5e194af..84d4ca964b 100644 --- a/js/src/jsgcinlines.h +++ b/js/src/jsgcinlines.h @@ -19,7 +19,7 @@ class Shape; namespace gc { static inline AllocKind -GetGCObjectKind(const Class *clasp) +GetGCObjectKind(const Class* clasp) { if (clasp == FunctionClassPtr) return JSFunction::FinalizeKind; @@ -30,10 +30,10 @@ GetGCObjectKind(const Class *clasp) } inline JSGCTraceKind -GetGCThingTraceKind(const void *thing) +GetGCThingTraceKind(const void* thing) { MOZ_ASSERT(thing); - const Cell *cell = static_cast(thing); + const Cell* cell = static_cast(thing); if (IsInsideNursery(cell)) return JSTRACE_OBJECT; return MapAllocToTraceKind(cell->asTenured().getAllocKind()); @@ -53,9 +53,9 @@ GCRuntime::poke() class ArenaIter { - ArenaHeader *aheader; - ArenaHeader *unsweptHeader; - ArenaHeader *sweptHeader; + ArenaHeader* aheader; + ArenaHeader* unsweptHeader; + ArenaHeader* sweptHeader; public: ArenaIter() { diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 0bd12307f8..fb20f09514 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -1577,25 +1577,26 @@ js::CreateThisForFunction(JSContext* cx, HandleObject callee, NewObjectKind newK } /* static */ bool -JSObject::nonNativeSetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, - HandleId id, MutableHandleValue vp, ObjectOpResult &result) +JSObject::nonNativeSetProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) { + RootedValue value(cx, v); if (MOZ_UNLIKELY(obj->watched())) { WatchpointMap *wpmap = cx->compartment()->watchpointMap; - if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, vp)) + if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, &value)) return false; } - return obj->getOps()->setProperty(cx, obj, receiver, id, vp, result); + return obj->getOps()->setProperty(cx, obj, id, value, receiver, result); } /* static */ bool -JSObject::nonNativeSetElement(JSContext *cx, HandleObject obj, HandleObject receiver, - uint32_t index, MutableHandleValue vp, ObjectOpResult &result) +JSObject::nonNativeSetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue v, + HandleValue receiver, ObjectOpResult &result) { RootedId id(cx); if (!IndexToId(cx, index, &id)) return false; - return nonNativeSetProperty(cx, obj, receiver, id, vp, result); + return nonNativeSetProperty(cx, obj, id, v, receiver, result); } JS_FRIEND_API(bool) @@ -3261,22 +3262,6 @@ js::DefineElement(ExclusiveContext *cx, HandleObject obj, uint32_t index, Handle return DefineProperty(cx, obj, id, value, getter, setter, attrs); } -bool -js::SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandlePropertyName name, - MutableHandleValue vp) -{ - RootedId id(cx, NameToId(name)); - return SetProperty(cx, obj, receiver, id, vp); -} - -bool -js::PutProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, MutableHandleValue value, - bool strict) -{ - RootedId id(cx, NameToId(name)); - return PutProperty(cx, obj, id, value, strict); -} - /*** SpiderMonkey nonstandard internal methods ***************************************************/ diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 07656f9f01..e6d3b0e542 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -44,16 +44,16 @@ namespace gc { class RelocationOverlay; } // namespace gc -inline JSObject * +inline JSObject* CastAsObject(GetterOp op) { - return JS_FUNC_TO_DATA_PTR(JSObject *, op); + return JS_FUNC_TO_DATA_PTR(JSObject*, op); } -inline JSObject * +inline JSObject* CastAsObject(SetterOp op) { - return JS_FUNC_TO_DATA_PTR(JSObject *, op); + return JS_FUNC_TO_DATA_PTR(JSObject*, op); } inline Value @@ -82,8 +82,8 @@ class SetObject; class StrictArgumentsObject; // Forward declarations, required for later friend declarations. -bool PreventExtensions(JSContext *cx, JS::HandleObject obj, JS::ObjectOpResult &result); -bool SetImmutablePrototype(js::ExclusiveContext *cx, JS::HandleObject obj, bool *succeeded); +bool PreventExtensions(JSContext* cx, JS::HandleObject obj, JS::ObjectOpResult& result); +bool SetImmutablePrototype(js::ExclusiveContext* cx, JS::HandleObject obj, bool* succeeded); } /* namespace js */ @@ -162,18 +162,18 @@ class JSObject : public js::gc::Cell return group_->lazy(); } - JSCompartment *compartment() const { + JSCompartment* compartment() const { return group_->compartment(); } - inline js::Shape *maybeShape() const; - inline js::Shape *ensureShape(js::ExclusiveContext *cx); + inline js::Shape* maybeShape() const; + inline js::Shape* ensureShape(js::ExclusiveContext* cx); /* * Make a non-array object with the specified initial state. This method * takes ownership of any extantSlots it is passed. */ - static inline JSObject *create(js::ExclusiveContext *cx, + static inline JSObject* create(js::ExclusiveContext* cx, js::gc::AllocKind kind, js::gc::InitialHeap heap, js::HandleShape shape, @@ -212,7 +212,7 @@ class JSObject : public js::gc::Cell * (see Purge{Scope,Proto}Chain in jsobj.cpp). */ inline bool isDelegate() const; - bool setDelegate(js::ExclusiveContext *cx) { + bool setDelegate(js::ExclusiveContext* cx) { return setFlags(cx, js::BaseShape::DELEGATE, GENERATE_SHAPE); } @@ -220,18 +220,18 @@ class JSObject : public js::gc::Cell inline bool hasSpecialEquality() const; inline bool watched() const; - bool setWatched(js::ExclusiveContext *cx) { + bool setWatched(js::ExclusiveContext* cx) { return setFlags(cx, js::BaseShape::WATCHED, GENERATE_SHAPE); } /* See InterpreterFrame::varObj. */ inline bool isQualifiedVarObj(); - bool setQualifiedVarObj(js::ExclusiveContext *cx) { + bool setQualifiedVarObj(js::ExclusiveContext* cx) { return setFlags(cx, js::BaseShape::QUALIFIED_VAROBJ); } inline bool isUnqualifiedVarObj(); - bool setUnqualifiedVarObj(js::ExclusiveContext *cx) { + bool setUnqualifiedVarObj(js::ExclusiveContext* cx) { return setFlags(cx, js::BaseShape::UNQUALIFIED_VAROBJ); } @@ -242,7 +242,7 @@ class JSObject : public js::gc::Cell * lookups on the object. */ inline bool hasUncacheableProto() const; - bool setUncacheableProto(js::ExclusiveContext *cx) { + bool setUncacheableProto(js::ExclusiveContext* cx) { return setFlags(cx, js::BaseShape::UNCACHEABLE_PROTO, GENERATE_SHAPE); } @@ -251,7 +251,7 @@ class JSObject : public js::gc::Cell * PropertyTree::MAX_HEIGHT. */ inline bool hadElementsAccess() const; - bool setHadElementsAccess(js::ExclusiveContext *cx) { + bool setHadElementsAccess(js::ExclusiveContext* cx) { return setFlags(cx, js::BaseShape::HAD_ELEMENTS_ACCESS); } @@ -330,7 +330,7 @@ class JSObject : public js::gc::Cell bool uninlinedIsProxy() const; - JSObject *getProto() const { + JSObject* getProto() const { MOZ_ASSERT(!uninlinedIsProxy()); return getTaggedProto().toObjectOrNull(); } @@ -362,7 +362,7 @@ class JSObject : public js::gc::Cell // on proxies with lazy [[Prototype]]! inline bool nonLazyPrototypeIsImmutable() const; - inline void setGroup(js::ObjectGroup *group); + inline void setGroup(js::ObjectGroup* group); /* * Mark an object that has been iterated over and is a singleton. We need @@ -370,7 +370,7 @@ class JSObject : public js::gc::Cell * is purged on GC. */ inline bool isIteratedSingleton() const; - bool setIteratedSingleton(js::ExclusiveContext *cx) { + bool setIteratedSingleton(js::ExclusiveContext* cx) { return setFlags(cx, js::BaseShape::ITERATED_SINGLETON); } @@ -427,9 +427,9 @@ class JSObject : public js::gc::Cell * this will just be the global (the name "enclosing scope" still applies * in this situation because non-scope objects can be on the scope chain). */ - inline JSObject *enclosingScope(); + inline JSObject* enclosingScope(); - inline js::GlobalObject &global() const; + inline js::GlobalObject& global() const; inline bool isOwnGlobal() const; /* @@ -471,17 +471,17 @@ class JSObject : public js::gc::Cell * callable a TypeError will be thrown. On success the value returned by * the call is stored in *vp. */ - bool callMethod(JSContext *cx, js::HandleId id, unsigned argc, js::Value *argv, + bool callMethod(JSContext* cx, js::HandleId id, unsigned argc, js::Value* argv, js::MutableHandleValue vp); - static bool nonNativeSetProperty(JSContext *cx, js::HandleObject obj, - js::HandleObject receiver, js::HandleId id, - js::MutableHandleValue vp, JS::ObjectOpResult &result); - static bool nonNativeSetElement(JSContext *cx, js::HandleObject obj, - js::HandleObject receiver, uint32_t index, - js::MutableHandleValue vp, JS::ObjectOpResult &result); + static bool nonNativeSetProperty(JSContext* cx, js::HandleObject obj, js::HandleId id, + js::HandleValue v, js::HandleValue receiver, + JS::ObjectOpResult& result); + static bool nonNativeSetElement(JSContext* cx, js::HandleObject obj, uint32_t index, + js::HandleValue v, js::HandleValue receiver, + JS::ObjectOpResult& result); - static bool swap(JSContext *cx, JS::HandleObject a, JS::HandleObject b); + static bool swap(JSContext* cx, JS::HandleObject a, JS::HandleObject b); private: void fixDictionaryShapeAfterSwap(); @@ -693,7 +693,7 @@ namespace js { * instead. See the comment on JSObject::getTaggedProto(). */ inline bool -GetPrototype(JSContext *cx, HandleObject obj, MutableHandleObject protop); +GetPrototype(JSContext* cx, HandleObject obj, MutableHandleObject protop); /* * ES6 [[SetPrototypeOf]]. Change obj's prototype to proto. @@ -703,12 +703,12 @@ GetPrototype(JSContext *cx, HandleObject obj, MutableHandleObject protop); * true, because no exception is thrown for this; but *result will be false. */ extern bool -SetPrototype(JSContext *cx, HandleObject obj, HandleObject proto, - ObjectOpResult &result); +SetPrototype(JSContext* cx, HandleObject obj, HandleObject proto, + ObjectOpResult& result); /* Convenience function: like the above, but throw on failure. */ extern bool -SetPrototype(JSContext *cx, HandleObject obj, HandleObject proto); +SetPrototype(JSContext* cx, HandleObject obj, HandleObject proto); /* * ES6 [[IsExtensible]]. Extensible objects can have new properties defined on @@ -724,11 +724,11 @@ IsExtensible(ExclusiveContext* cx, HandleObject obj, bool* extensible); * actual error through the return value. */ extern bool -PreventExtensions(JSContext *cx, HandleObject obj, ObjectOpResult &result); +PreventExtensions(JSContext* cx, HandleObject obj, ObjectOpResult& result); /* Convenience function. As above, but throw on failure. */ extern bool -PreventExtensions(JSContext *cx, HandleObject obj); +PreventExtensions(JSContext* cx, HandleObject obj); /* * ES6 [[GetOwnPropertyDescriptor]]. Get a description of one of obj's own @@ -849,49 +849,52 @@ inline bool GetElementNoGC(JSContext* cx, JSObject* obj, JSObject* receiver, uint32_t index, Value* vp); /* - * ES6 [[Set]]. Carry out the assignment `obj[id] = vp`. + * ES6 [[Set]]. Carry out the assignment `obj[id] = v`. * * The `receiver` argument has to do with how [[Set]] interacts with the * prototype chain and proxies. It's hard to explain and ES6 doesn't really - * try. Long story short, if you just want bog-standard assignment, pass the - * same object as both obj and receiver. + * try. Long story short, if you just want bog-standard assignment, pass + * `ObjectValue(*obj)` as receiver. Or better, use one of the signatures that + * doesn't have a receiver parameter. * - * When obj != receiver, it's a reasonable guess that a proxy is involved, obj - * is the proxy's target, and the proxy is using SetProperty to finish an - * assignment that started out as `receiver[id] = vp`, by delegating it to obj. - * - * Strict errors: ES6 specifies that this method returns a boolean value - * indicating whether assignment "succeeded". We currently take a `strict` - * argument instead, but this has to change. See bug 1113369. + * Callers pass obj != receiver e.g. when a proxy is involved, obj is the + * proxy's target, and the proxy is using SetProperty to finish an assignment + * that started out as `receiver[id] = v`, by delegating it to obj. */ inline bool -SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id, - MutableHandleValue vp, ObjectOpResult &result); +SetProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult& result); inline bool -SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, PropertyName *name, - MutableHandleValue vp, ObjectOpResult &result) +SetProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue v) +{ + RootedValue receiver(cx, ObjectValue(*obj)); + ObjectOpResult result; + return SetProperty(cx, obj, id, v, receiver, result) && + result.checkStrict(cx, obj, id); +} + +inline bool +SetProperty(JSContext* cx, HandleObject obj, PropertyName* name, HandleValue v, + HandleValue receiver, ObjectOpResult& result) { RootedId id(cx, NameToId(name)); - return SetProperty(cx, obj, receiver, id, vp, result); + return SetProperty(cx, obj, id, v, receiver, result); } inline bool -SetElement(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t index, - MutableHandleValue vp, ObjectOpResult &result); - -inline bool -SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id, - MutableHandleValue vp) +SetProperty(JSContext* cx, HandleObject obj, PropertyName* name, HandleValue v) { + RootedId id(cx, NameToId(name)); + RootedValue receiver(cx, ObjectValue(*obj)); ObjectOpResult result; - return SetProperty(cx, obj, receiver, id, vp, result) && - result.checkStrict(cx, receiver, id); + return SetProperty(cx, obj, id, v, receiver, result) && + result.checkStrict(cx, obj, id); } -extern bool -SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandlePropertyName name, - MutableHandleValue vp); +inline bool +SetElement(JSContext* cx, HandleObject obj, uint32_t index, HandleValue v, + HandleValue receiver, ObjectOpResult& result); /* * ES6 draft rev 31 (15 Jan 2015) 7.3.3 Put (O, P, V, Throw), except that on @@ -899,25 +902,22 @@ SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleProper * don't bother doing. */ inline bool -PutProperty(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue value, bool strict) +PutProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue v, bool strict) { + RootedValue receiver(cx, ObjectValue(*obj)); ObjectOpResult result; - return SetProperty(cx, obj, obj, id, value, result) && + return SetProperty(cx, obj, id, v, receiver, result) && result.checkStrictErrorOrWarning(cx, obj, id, strict); } -extern bool -PutProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, MutableHandleValue value, - bool strict); - /* * ES6 [[Delete]]. Equivalent to the JS code `delete obj[id]`. */ inline bool -DeleteProperty(JSContext *cx, HandleObject obj, HandleId id, ObjectOpResult &result); +DeleteProperty(JSContext* cx, HandleObject obj, HandleId id, ObjectOpResult& result); inline bool -DeleteElement(JSContext *cx, HandleObject obj, uint32_t index, ObjectOpResult &result); +DeleteElement(JSContext* cx, HandleObject obj, uint32_t index, ObjectOpResult& result); /*** SpiderMonkey nonstandard internal methods ***************************************************/ @@ -1104,7 +1104,7 @@ extern const char js_lookupSetter_str[]; namespace js { inline gc::InitialHeap -GetInitialHeap(NewObjectKind newKind, const Class *clasp) +GetInitialHeap(NewObjectKind newKind, const Class* clasp) { if (newKind != GenericObject) return gc::TenuredHeap; @@ -1159,7 +1159,7 @@ ToPropertyDescriptor(JSContext *cx, HandleValue descval, bool checkAccessors, * when checkAccessors is false. */ bool -CheckPropertyDescriptorAccessors(JSContext *cx, Handle desc); +CheckPropertyDescriptorAccessors(JSContext* cx, Handle desc); void CompletePropertyDescriptor(MutableHandle desc); diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index 830fee69fe..ebd28443b3 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -182,7 +182,7 @@ js::GetElementNoGC(JSContext* cx, JSObject* obj, JSObject* receiver, uint32_t in } inline bool -js::DeleteProperty(JSContext *cx, HandleObject obj, HandleId id, ObjectOpResult &result) +js::DeleteProperty(JSContext* cx, HandleObject obj, HandleId id, ObjectOpResult& result) { MarkTypePropertyNonData(cx, obj, id); if (DeletePropertyOp op = obj->getOps()->deleteProperty) @@ -191,7 +191,7 @@ js::DeleteProperty(JSContext *cx, HandleObject obj, HandleId id, ObjectOpResult } inline bool -js::DeleteElement(JSContext *cx, HandleObject obj, uint32_t index, ObjectOpResult &result) +js::DeleteElement(JSContext* cx, HandleObject obj, uint32_t index, ObjectOpResult& result) { RootedId id(cx); if (!IndexToId(cx, index, &id)) @@ -234,11 +234,11 @@ ClassCanHaveFixedData(const Class* clasp) } static MOZ_ALWAYS_INLINE void -SetNewObjectMetadata(ExclusiveContext *cxArg, JSObject *obj) +SetNewObjectMetadata(ExclusiveContext* cxArg, JSObject* obj) { // The metadata callback is invoked for each object created on the main // thread, except when analysis/compilation is active, to avoid recursion. - if (JSContext *cx = cxArg->maybeJSContext()) { + if (JSContext* cx = cxArg->maybeJSContext()) { if (MOZ_UNLIKELY((size_t)cx->compartment()->hasObjectMetadataCallback()) && !cx->zone()->types.activeAnalysis) { @@ -253,8 +253,8 @@ SetNewObjectMetadata(ExclusiveContext *cxArg, JSObject *obj) } // namespace js -/* static */ inline JSObject * -JSObject::create(js::ExclusiveContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap heap, +/* static */ inline JSObject* +JSObject::create(js::ExclusiveContext* cx, js::gc::AllocKind kind, js::gc::InitialHeap heap, js::HandleShape shape, js::HandleObjectGroup group) { MOZ_ASSERT(shape && group); @@ -276,11 +276,11 @@ JSObject::create(js::ExclusiveContext *cx, js::gc::AllocKind kind, js::gc::Initi MOZ_ASSERT_IF(!group->clasp()->isNative(), shape->numFixedSlots() == 0); MOZ_ASSERT_IF(!group->clasp()->isNative(), shape->slotSpan() == 0); - const js::Class *clasp = group->clasp(); + const js::Class* clasp = group->clasp(); size_t nDynamicSlots = js::NativeObject::dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan(), clasp); - JSObject *obj = js::Allocate(cx, kind, nDynamicSlots, heap, clasp); + JSObject* obj = js::Allocate(cx, kind, nDynamicSlots, heap, clasp); if (!obj) return nullptr; @@ -355,7 +355,7 @@ inline bool JSObject::hasAllFlags(js::BaseShape::Flag flags) const { MOZ_ASSERT(flags); - if (js::Shape *shape = maybeShape()) + if (js::Shape* shape = maybeShape()) return shape->hasAllObjectFlags(flags); return false; } @@ -562,9 +562,9 @@ ToPrimitive(JSContext* cx, JSType preferredType, MutableHandleValue vp) * or embedding code. */ inline bool -IsInternalFunctionObject(JSObject *funobj) +IsInternalFunctionObject(JSObject* funobj) { - JSFunction *fun = &funobj->as(); + JSFunction* fun = &funobj->as(); MOZ_ASSERT_IF(fun->isLambda(), fun->isInterpreted() || fun->isAsmJSNative()); return fun->isLambda() && fun->isInterpreted() && !fun->environment(); @@ -573,7 +573,7 @@ IsInternalFunctionObject(JSObject *funobj) class AutoPropertyDescriptorVector : public AutoVectorRooter { public: - explicit AutoPropertyDescriptorVector(JSContext *cx + explicit AutoPropertyDescriptorVector(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : AutoVectorRooter(cx, DESCVECTOR) { @@ -587,12 +587,12 @@ class AutoPropertyDescriptorVector : public AutoVectorRooter * Make an object with the specified prototype. If parent is null, it will * default to the prototype's global if the prototype is non-null. */ -JSObject * -NewObjectWithGivenTaggedProto(ExclusiveContext *cx, const Class *clasp, Handle proto, +JSObject* +NewObjectWithGivenTaggedProto(ExclusiveContext* cx, const Class* clasp, Handle proto, gc::AllocKind allocKind, NewObjectKind newKind); -inline JSObject * -NewObjectWithGivenTaggedProto(ExclusiveContext *cx, const Class *clasp, Handle proto, +inline JSObject* +NewObjectWithGivenTaggedProto(ExclusiveContext* cx, const Class* clasp, Handle proto, NewObjectKind newKind = GenericObject) { gc::AllocKind allocKind = gc::GetGCObjectKind(clasp); @@ -600,43 +600,43 @@ NewObjectWithGivenTaggedProto(ExclusiveContext *cx, const Class *clasp, Handle -inline T * -NewObjectWithGivenTaggedProto(ExclusiveContext *cx, Handle proto, +inline T* +NewObjectWithGivenTaggedProto(ExclusiveContext* cx, Handle proto, NewObjectKind newKind = GenericObject) { - JSObject *obj = NewObjectWithGivenTaggedProto(cx, &T::class_, proto, newKind); + JSObject* obj = NewObjectWithGivenTaggedProto(cx, &T::class_, proto, newKind); return obj ? &obj->as() : nullptr; } -inline JSObject * -NewObjectWithGivenProto(ExclusiveContext *cx, const Class *clasp, HandleObject proto, +inline JSObject* +NewObjectWithGivenProto(ExclusiveContext* cx, const Class* clasp, HandleObject proto, gc::AllocKind allocKind, NewObjectKind newKind) { return NewObjectWithGivenTaggedProto(cx, clasp, AsTaggedProto(proto), allocKind, newKind); } -inline JSObject * -NewObjectWithGivenProto(ExclusiveContext *cx, const Class *clasp, HandleObject proto, +inline JSObject* +NewObjectWithGivenProto(ExclusiveContext* cx, const Class* clasp, HandleObject proto, NewObjectKind newKind = GenericObject) { return NewObjectWithGivenTaggedProto(cx, clasp, AsTaggedProto(proto), newKind); } template -inline T * -NewObjectWithGivenProto(ExclusiveContext *cx, HandleObject proto, +inline T* +NewObjectWithGivenProto(ExclusiveContext* cx, HandleObject proto, NewObjectKind newKind = GenericObject) { return NewObjectWithGivenTaggedProto(cx, AsTaggedProto(proto), newKind); } template -inline T * -NewObjectWithGivenProto(ExclusiveContext *cx, HandleObject proto, +inline T* +NewObjectWithGivenProto(ExclusiveContext* cx, HandleObject proto, gc::AllocKind allocKind, NewObjectKind newKind = GenericObject) { - JSObject *obj = NewObjectWithGivenTaggedProto(cx, &T::class_, AsTaggedProto(proto), + JSObject* obj = NewObjectWithGivenTaggedProto(cx, &T::class_, AsTaggedProto(proto), allocKind, newKind); return obj ? &obj->as() : nullptr; } @@ -658,19 +658,19 @@ NewObjectWithGivenProto(ExclusiveContext *cx, HandleObject proto, * null, the context's active global will be used, and the resulting object's * parent will be that global. */ -JSObject * -NewObjectWithClassProtoCommon(ExclusiveContext *cx, const Class *clasp, HandleObject proto, +JSObject* +NewObjectWithClassProtoCommon(ExclusiveContext* cx, const Class* clasp, HandleObject proto, gc::AllocKind allocKind, NewObjectKind newKind); -inline JSObject * -NewObjectWithClassProto(ExclusiveContext *cx, const Class *clasp, HandleObject proto, +inline JSObject* +NewObjectWithClassProto(ExclusiveContext* cx, const Class* clasp, HandleObject proto, gc::AllocKind allocKind, NewObjectKind newKind = GenericObject) { return NewObjectWithClassProtoCommon(cx, clasp, proto, allocKind, newKind); } -inline JSObject * -NewObjectWithClassProto(ExclusiveContext *cx, const Class *clasp, HandleObject proto, +inline JSObject* +NewObjectWithClassProto(ExclusiveContext* cx, const Class* clasp, HandleObject proto, NewObjectKind newKind = GenericObject) { gc::AllocKind allocKind = gc::GetGCObjectKind(clasp); @@ -678,20 +678,20 @@ NewObjectWithClassProto(ExclusiveContext *cx, const Class *clasp, HandleObject p } template -inline T * -NewObjectWithProto(ExclusiveContext *cx, HandleObject proto, +inline T* +NewObjectWithProto(ExclusiveContext* cx, HandleObject proto, gc::AllocKind allocKind, NewObjectKind newKind = GenericObject) { - JSObject *obj = NewObjectWithClassProto(cx, &T::class_, proto, allocKind, newKind); + JSObject* obj = NewObjectWithClassProto(cx, &T::class_, proto, allocKind, newKind); return obj ? &obj->as() : nullptr; } template -inline T * -NewObjectWithProto(ExclusiveContext *cx, HandleObject proto, +inline T* +NewObjectWithProto(ExclusiveContext* cx, HandleObject proto, NewObjectKind newKind = GenericObject) { - JSObject *obj = NewObjectWithClassProto(cx, &T::class_, proto, newKind); + JSObject* obj = NewObjectWithClassProto(cx, &T::class_, proto, newKind); return obj ? &obj->as() : nullptr; } diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index 96532f993d..692355b930 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -1567,7 +1567,7 @@ str_includes(JSContext* cx, unsigned argc, Value* vp) /* ES6 draft names().lastIndex, &zero); + return SetProperty(cx, obj_, cx->names().lastIndex, zero); } RegExpShared& regExp() { return *re_; } @@ -3085,10 +3085,10 @@ struct StringRange template static void -CopySubstringsToFatInline(JSFatInlineString *dest, const CharT *src, const StringRange *ranges, +CopySubstringsToFatInline(JSFatInlineString* dest, const CharT* src, const StringRange* ranges, size_t rangesLen, size_t outputLen) { - CharT *buf = dest->init(outputLen); + CharT* buf = dest->init(outputLen); size_t pos = 0; for (size_t i = 0; i < rangesLen; i++) { PodCopy(buf + pos, src + ranges[i].start, ranges[i].length); @@ -3099,11 +3099,11 @@ CopySubstringsToFatInline(JSFatInlineString *dest, const CharT *src, const Strin buf[outputLen] = 0; } -static inline JSFatInlineString * -FlattenSubstrings(JSContext *cx, HandleLinearString str, const StringRange *ranges, +static inline JSFatInlineString* +FlattenSubstrings(JSContext* cx, HandleLinearString str, const StringRange* ranges, size_t rangesLen, size_t outputLen) { - JSFatInlineString *result = Allocate(cx); + JSFatInlineString* result = Allocate(cx); if (!result) return nullptr; diff --git a/js/src/jswrapper.h b/js/src/jswrapper.h index 25eeede78f..57150d5cac 100644 --- a/js/src/jswrapper.h +++ b/js/src/jswrapper.h @@ -137,8 +137,8 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper virtual bool has(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const override; virtual bool get(JSContext *cx, HandleObject wrapper, HandleObject receiver, HandleId id, MutableHandleValue vp) const override; - virtual bool set(JSContext *cx, HandleObject wrapper, HandleObject receiver, HandleId id, - MutableHandleValue vp, ObjectOpResult &result) const override; + virtual bool set(JSContext *cx, HandleObject wrapper, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) const override; virtual bool call(JSContext *cx, HandleObject wrapper, const CallArgs &args) const override; virtual bool construct(JSContext* cx, HandleObject wrapper, const CallArgs &args) const override; diff --git a/js/src/moz.build b/js/src/moz.build index d99a8e0022..ceb1a51c97 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -323,15 +323,16 @@ if not CONFIG['ENABLE_ION']: ] elif CONFIG['JS_CODEGEN_X86'] or CONFIG['JS_CODEGEN_X64']: UNIFIED_SOURCES += [ - 'jit/shared/Assembler-x86-shared.cpp', - 'jit/shared/AssemblerBuffer-x86-shared.cpp', - 'jit/shared/BaselineCompiler-x86-shared.cpp', - 'jit/shared/BaselineIC-x86-shared.cpp', - 'jit/shared/CodeGenerator-x86-shared.cpp', - 'jit/shared/Disassembler-x86-shared.cpp', - 'jit/shared/Lowering-x86-shared.cpp', - 'jit/shared/MacroAssembler-x86-shared.cpp', - 'jit/shared/MoveEmitter-x86-shared.cpp', + 'jit/x86-shared/Architecture-x86-shared.cpp', + 'jit/x86-shared/Assembler-x86-shared.cpp', + 'jit/x86-shared/AssemblerBuffer-x86-shared.cpp', + 'jit/x86-shared/BaselineCompiler-x86-shared.cpp', + 'jit/x86-shared/BaselineIC-x86-shared.cpp', + 'jit/x86-shared/CodeGenerator-x86-shared.cpp', + 'jit/x86-shared/Disassembler-x86-shared.cpp', + 'jit/x86-shared/Lowering-x86-shared.cpp', + 'jit/x86-shared/MacroAssembler-x86-shared.cpp', + 'jit/x86-shared/MoveEmitter-x86-shared.cpp', ] if CONFIG['JS_CODEGEN_X64']: UNIFIED_SOURCES += [ diff --git a/js/src/proxy/BaseProxyHandler.cpp b/js/src/proxy/BaseProxyHandler.cpp index edb59c3470..b0676eed17 100644 --- a/js/src/proxy/BaseProxyHandler.cpp +++ b/js/src/proxy/BaseProxyHandler.cpp @@ -61,8 +61,7 @@ BaseProxyHandler::get(JSContext* cx, HandleObject proxy, HandleObject receiver, return true; } if (desc.hasGetterObject()) - return InvokeGetterOrSetter(cx, receiver, ObjectValue(*desc.getterObject()), - 0, nullptr, vp); + return InvokeGetter(cx, receiver, ObjectValue(*desc.getterObject()), vp); if (!desc.isShared()) vp.set(desc.value()); else @@ -72,8 +71,8 @@ BaseProxyHandler::get(JSContext* cx, HandleObject proxy, HandleObject receiver, } bool -BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver, - HandleId id, MutableHandleValue vp, ObjectOpResult &result) const +BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) const { assertEnteredPolicy(cx, proxy, id, SET); @@ -88,13 +87,12 @@ BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver, // The rest is factored out into a separate function with a weird name. // This algorithm continues just below. - return SetPropertyIgnoringNamedGetter(cx, proxy, id, vp, receiver, ownDesc, result); + return SetPropertyIgnoringNamedGetter(cx, proxy, id, v, receiver, ownDesc, result); } bool -js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id, - MutableHandleValue vp, HandleObject receiver, - Handle ownDesc_, +js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id, HandleValue v, + HandleValue receiver, Handle ownDesc_, ObjectOpResult &result) { Rooted ownDesc(cx, ownDesc_); @@ -107,7 +105,7 @@ js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id, if (!GetPrototype(cx, obj, &proto)) return false; if (proto) - return SetProperty(cx, proto, receiver, id, vp, result); + return SetProperty(cx, proto, id, v, receiver, result); // Step 4.d. ownDesc.setDataDescriptor(UndefinedHandleValue, JSPROP_ENUMERATE); @@ -118,17 +116,22 @@ js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id, // Steps 5.a-b. if (!ownDesc.writable()) return result.fail(JSMSG_READ_ONLY); + if (!receiver.isObject()) + return result.fail(JSMSG_SET_NON_OBJECT_RECEIVER); + RootedObject receiverObj(cx, &receiver.toObject()); // Nonstandard SpiderMonkey special case: setter ops. SetterOp setter = ownDesc.setter(); MOZ_ASSERT(setter != JS_StrictPropertyStub); - if (setter && setter != JS_StrictPropertyStub) - return CallJSSetterOp(cx, setter, receiver, id, vp, result); + if (setter && setter != JS_StrictPropertyStub) { + RootedValue valCopy(cx, v); + return CallJSSetterOp(cx, setter, receiverObj, id, &valCopy, result); + } // Steps 5.c-d. Adapt for SpiderMonkey by using HasOwnProperty instead // of the standard [[GetOwnProperty]]. bool existingDescriptor; - if (!HasOwnProperty(cx, receiver, id, &existingDescriptor)) + if (!HasOwnProperty(cx, receiverObj, id, &existingDescriptor)) return false; // Steps 5.e-f. @@ -139,10 +142,10 @@ js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id, // A very old nonstandard SpiderMonkey extension: default to the Class // getter and setter ops. - const Class *clasp = receiver->getClass(); + const Class *clasp = receiverObj->getClass(); MOZ_ASSERT(clasp->getProperty != JS_PropertyStub); MOZ_ASSERT(clasp->setProperty != JS_StrictPropertyStub); - return DefineProperty(cx, receiver, id, vp, clasp->getProperty, clasp->setProperty, + return DefineProperty(cx, receiverObj, id, v, clasp->getProperty, clasp->setProperty, attrs, result); } @@ -154,7 +157,7 @@ js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id, if (!setter) return result.fail(JSMSG_GETTER_ONLY); RootedValue setterValue(cx, ObjectValue(*setter)); - if (!InvokeGetterOrSetter(cx, receiver, setterValue, 1, vp.address(), vp)) + if (!InvokeSetter(cx, receiver, setterValue, v)) return false; return result.succeed(); } diff --git a/js/src/proxy/CrossCompartmentWrapper.cpp b/js/src/proxy/CrossCompartmentWrapper.cpp index 3dcb25566f..db040ea4c5 100644 --- a/js/src/proxy/CrossCompartmentWrapper.cpp +++ b/js/src/proxy/CrossCompartmentWrapper.cpp @@ -169,14 +169,15 @@ CrossCompartmentWrapper::get(JSContext* cx, HandleObject wrapper, HandleObject r } bool -CrossCompartmentWrapper::set(JSContext *cx, HandleObject wrapper, HandleObject receiver, - HandleId id, MutableHandleValue vp, ObjectOpResult &result) const +CrossCompartmentWrapper::set(JSContext *cx, HandleObject wrapper, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) const { - RootedObject receiverCopy(cx, receiver); + RootedValue valCopy(cx, v); + RootedValue receiverCopy(cx, receiver); PIERCE(cx, wrapper, - cx->compartment()->wrap(cx, &receiverCopy) && - cx->compartment()->wrap(cx, vp), - Wrapper::set(cx, wrapper, receiverCopy, id, vp, result), + cx->compartment()->wrap(cx, &valCopy) && + cx->compartment()->wrap(cx, &receiverCopy), + Wrapper::set(cx, wrapper, id, valCopy, receiverCopy, result), NOTHING); } diff --git a/js/src/proxy/DeadObjectProxy.cpp b/js/src/proxy/DeadObjectProxy.cpp index 4da21eacc7..c89065c4a1 100644 --- a/js/src/proxy/DeadObjectProxy.cpp +++ b/js/src/proxy/DeadObjectProxy.cpp @@ -15,7 +15,7 @@ using namespace js; using namespace js::gc; bool -DeadObjectProxy::getPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id, +DeadObjectProxy::getPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id, MutableHandle desc) const { JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT); @@ -23,7 +23,7 @@ DeadObjectProxy::getPropertyDescriptor(JSContext *cx, HandleObject wrapper, Hand } bool -DeadObjectProxy::getOwnPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id, +DeadObjectProxy::getOwnPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id, MutableHandle desc) const { JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT); diff --git a/js/src/proxy/DirectProxyHandler.cpp b/js/src/proxy/DirectProxyHandler.cpp index ef1a995cd1..c0832a516f 100644 --- a/js/src/proxy/DirectProxyHandler.cpp +++ b/js/src/proxy/DirectProxyHandler.cpp @@ -216,12 +216,12 @@ DirectProxyHandler::get(JSContext* cx, HandleObject proxy, HandleObject receiver } bool -DirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver, - HandleId id, MutableHandleValue vp, ObjectOpResult &result) const +DirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) const { assertEnteredPolicy(cx, proxy, id, SET); RootedObject target(cx, proxy->as().target()); - return SetProperty(cx, target, receiver, id, vp, result); + return SetProperty(cx, target, id, v, receiver, result); } bool diff --git a/js/src/proxy/Proxy.cpp b/js/src/proxy/Proxy.cpp index f284a7742c..5970548e45 100644 --- a/js/src/proxy/Proxy.cpp +++ b/js/src/proxy/Proxy.cpp @@ -307,8 +307,8 @@ Proxy::callProp(JSContext* cx, HandleObject proxy, HandleObject receiver, Handle } bool -Proxy::set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, - MutableHandleValue vp, ObjectOpResult &result) +Proxy::set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, HandleValue receiver, + ObjectOpResult &result) { JS_CHECK_RECURSION(cx, return false); const BaseProxyHandler* handler = proxy->as().handler(); @@ -321,9 +321,9 @@ Proxy::set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id // Special case. See the comment on BaseProxyHandler::mHasPrototype. if (handler->hasPrototype()) - return handler->BaseProxyHandler::set(cx, proxy, receiver, id, vp, result); + return handler->BaseProxyHandler::set(cx, proxy, id, v, receiver, result); - return handler->set(cx, proxy, receiver, id, vp, result); + return handler->set(cx, proxy, id, v, receiver, result); } bool @@ -580,10 +580,10 @@ js::proxy_GetProperty(JSContext* cx, HandleObject obj, HandleObject receiver, Ha } bool -js::proxy_SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id, - MutableHandleValue vp, ObjectOpResult &result) +js::proxy_SetProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) { - return Proxy::set(cx, obj, receiver, id, vp, result); + return Proxy::set(cx, obj, id, v, receiver, result); } bool diff --git a/js/src/proxy/Proxy.h b/js/src/proxy/Proxy.h index 2eb4e206cc..30037eee7f 100644 --- a/js/src/proxy/Proxy.h +++ b/js/src/proxy/Proxy.h @@ -42,8 +42,8 @@ class Proxy static bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp); static bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, MutableHandleValue vp); - static bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, - MutableHandleValue vp, ObjectOpResult &result); + static bool set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result); static bool call(JSContext *cx, HandleObject proxy, const CallArgs &args); static bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args); diff --git a/js/src/proxy/ScriptedDirectProxyHandler.cpp b/js/src/proxy/ScriptedDirectProxyHandler.cpp index 51f3579a4a..55dadeba74 100644 --- a/js/src/proxy/ScriptedDirectProxyHandler.cpp +++ b/js/src/proxy/ScriptedDirectProxyHandler.cpp @@ -922,8 +922,8 @@ ScriptedDirectProxyHandler::get(JSContext* cx, HandleObject proxy, HandleObject // ES6 draft rev 32 (2015 Feb 2) 9.5.9 Proxy.[[Set]](P, V, Receiver) bool -ScriptedDirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver, - HandleId id, MutableHandleValue vp, ObjectOpResult &result) const +ScriptedDirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) const { // step 2-3 (Steps 1 and 4 are irrelevant assertions.) RootedObject handler(cx, GetDirectProxyHandlerObject(proxy)); @@ -940,7 +940,7 @@ ScriptedDirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject // step 8 if (trap.isUndefined()) - return SetProperty(cx, target, receiver, id, vp, result); + return SetProperty(cx, target, id, v, receiver, result); // step 9-10 RootedValue value(cx); @@ -949,8 +949,8 @@ ScriptedDirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject Value argv[] = { ObjectOrNullValue(target), value, - vp.get(), - ObjectValue(*receiver) + v.get(), + receiver.get() }; RootedValue trapResult(cx); if (!Invoke(cx, ObjectValue(*handler), trap, ArrayLength(argv), argv, &trapResult)) @@ -969,7 +969,7 @@ ScriptedDirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject if (desc.object()) { if (desc.isDataDescriptor() && !desc.configurable() && !desc.writable()) { bool same; - if (!SameValue(cx, vp, desc.value(), &same)) + if (!SameValue(cx, v, desc.value(), &same)) return false; if (!same) { JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_SET_NW_NC); diff --git a/js/src/proxy/ScriptedDirectProxyHandler.h b/js/src/proxy/ScriptedDirectProxyHandler.h index 8c2f6adbb1..8578b8014a 100644 --- a/js/src/proxy/ScriptedDirectProxyHandler.h +++ b/js/src/proxy/ScriptedDirectProxyHandler.h @@ -46,8 +46,8 @@ class ScriptedDirectProxyHandler : public BaseProxyHandler { virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const override; virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, MutableHandleValue vp) const override; - virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, - MutableHandleValue vp, ObjectOpResult &result) const override; + virtual bool set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) const override; virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) const override; virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const override; diff --git a/js/src/proxy/ScriptedIndirectProxyHandler.cpp b/js/src/proxy/ScriptedIndirectProxyHandler.cpp index f7a6f8c5e2..dcd21adb7b 100644 --- a/js/src/proxy/ScriptedIndirectProxyHandler.cpp +++ b/js/src/proxy/ScriptedIndirectProxyHandler.cpp @@ -304,34 +304,34 @@ ScriptedIndirectProxyHandler::get(JSContext* cx, HandleObject proxy, HandleObjec } bool -ScriptedIndirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver, - HandleId id, MutableHandleValue vp, ObjectOpResult &result) const +ScriptedIndirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) const { RootedObject handler(cx, GetIndirectProxyHandlerObject(proxy)); RootedValue idv(cx); if (!IdToStringOrSymbol(cx, id, &idv)) return false; JS::AutoValueArray<3> argv(cx); - argv[0].setObjectOrNull(receiver); + argv[0].set(receiver); argv[1].set(idv); - argv[2].set(vp); + argv[2].set(v); RootedValue fval(cx); if (!GetDerivedTrap(cx, handler, cx->names().set, &fval)) return false; if (!IsCallable(fval)) - return derivedSet(cx, proxy, receiver, id, vp, result); + return derivedSet(cx, proxy, id, v, receiver, result); if (!Trap(cx, handler, fval, 3, argv.begin(), &idv)) return false; return result.succeed(); } static bool -CallSetter(JSContext *cx, HandleObject obj, HandleId id, SetterOp op, unsigned attrs, - MutableHandleValue vp, ObjectOpResult &result) +CallSetter(JSContext *cx, HandleValue receiver, HandleId id, SetterOp op, unsigned attrs, + HandleValue v, ObjectOpResult &result) { if (attrs & JSPROP_SETTER) { - RootedValue opv(cx, CastAsObjectJsval(op)); - if (!InvokeGetterOrSetter(cx, obj, opv, 1, vp.address(), vp)) + RootedValue fval(cx, CastAsObjectJsval(op)); + if (!InvokeSetter(cx, receiver, fval, v)) return false; return result.succeed(); } @@ -339,15 +339,20 @@ CallSetter(JSContext *cx, HandleObject obj, HandleId id, SetterOp op, unsigned a if (attrs & JSPROP_GETTER) return result.fail(JSMSG_GETTER_ONLY); + if (!receiver.isObject()) + return result.fail(JSMSG_SET_NON_OBJECT_RECEIVER); + RootedObject receiverObj(cx, &receiver.toObject()); + if (!op) return result.succeed(); - return CallJSSetterOp(cx, op, obj, id, vp, result); + RootedValue valCopy(cx, v); + return CallJSSetterOp(cx, op, receiverObj, id, &valCopy, result); } bool -ScriptedIndirectProxyHandler::derivedSet(JSContext* cx, HandleObject proxy, HandleObject receiver, - HandleId id, MutableHandleValue vp, +ScriptedIndirectProxyHandler::derivedSet(JSContext *cx, HandleObject proxy, HandleId id, + HandleValue v, HandleValue receiver, ObjectOpResult &result) const { // Find an own or inherited property. The code here is strange for maximum @@ -378,7 +383,7 @@ ScriptedIndirectProxyHandler::derivedSet(JSContext* cx, HandleObject proxy, Hand return result.fail(descIsOwn ? JSMSG_READ_ONLY : JSMSG_CANT_REDEFINE_PROP); if (desc.hasSetterObject() || desc.setter()) { - if (!CallSetter(cx, receiver, id, desc.setter(), desc.attributes(), vp, result)) + if (!CallSetter(cx, receiver, id, desc.setter(), desc.attributes(), v, result)) return false; if (!result) return true; @@ -389,22 +394,21 @@ ScriptedIndirectProxyHandler::derivedSet(JSContext* cx, HandleObject proxy, Hand return result.succeed(); } } - desc.value().set(vp.get()); + desc.value().set(v); if (descIsOwn) { MOZ_ASSERT(desc.object() == proxy); return this->defineProperty(cx, proxy, id, desc, result); } - return DefineProperty(cx, receiver, id, desc.value(), desc.getter(), desc.setter(), - desc.attributes(), result); + } else { + desc.setDataDescriptor(v, JSPROP_ENUMERATE); } - desc.object().set(receiver); - desc.value().set(vp.get()); - desc.setAttributes(JSPROP_ENUMERATE); - desc.setGetter(nullptr); - desc.setSetter(nullptr); // Pick up the class getter/setter. - return DefineProperty(cx, receiver, id, desc.value(), nullptr, nullptr, JSPROP_ENUMERATE, - result); + + if (!receiver.isObject()) + return result.fail(JSMSG_SET_NON_OBJECT_RECEIVER); + RootedObject receiverObj(cx, &receiver.toObject()); + desc.object().set(receiverObj); + return DefineProperty(cx, receiverObj, id, desc, result); } bool diff --git a/js/src/proxy/ScriptedIndirectProxyHandler.h b/js/src/proxy/ScriptedIndirectProxyHandler.h index 1648e7c57c..83506e97bc 100644 --- a/js/src/proxy/ScriptedIndirectProxyHandler.h +++ b/js/src/proxy/ScriptedIndirectProxyHandler.h @@ -37,8 +37,8 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const override; virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, MutableHandleValue vp) const override; - virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, - MutableHandleValue vp, ObjectOpResult &result) const override; + virtual bool set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) const override; /* SpiderMonkey extensions. */ virtual bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id, @@ -55,8 +55,8 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler static const ScriptedIndirectProxyHandler singleton; private: - bool derivedSet(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, - MutableHandleValue vp, ObjectOpResult &result) const; + bool derivedSet(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) const; }; /* Derived class to handle Proxy.createFunction() */ diff --git a/js/src/shell/jsoptparse.cpp b/js/src/shell/jsoptparse.cpp index 04cffd45f4..5705c2cf92 100644 --- a/js/src/shell/jsoptparse.cpp +++ b/js/src/shell/jsoptparse.cpp @@ -81,11 +81,11 @@ OptionParser::error(const char* fmt, ...) /* Quick and dirty paragraph printer. */ static void -PrintParagraph(const char *text, unsigned startColno, const unsigned limitColno, bool padFirstLine) +PrintParagraph(const char* text, unsigned startColno, const unsigned limitColno, bool padFirstLine) { unsigned colno = startColno; unsigned indent = 0; - const char *it = text; + const char* it = text; if (padFirstLine) printf("%*s", startColno, ""); @@ -147,8 +147,8 @@ PrintParagraph(const char *text, unsigned startColno, const unsigned limitColno, } } -static const char * -OptionFlagsToFormatInfo(char shortflag, bool isValued, size_t *length) +static const char* +OptionFlagsToFormatInfo(char shortflag, bool isValued, size_t* length) { static const char * const fmt[4] = { " -%c --%s ", " --%s ", diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index ea0d9377ab..9f3afe2343 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -7647,7 +7647,7 @@ DebuggerEnv_setVariable(JSContext* cx, unsigned argc, Value* vp) } /* Just set the property. */ - if (!SetProperty(cx, env, env, id, &v)) + if (!SetProperty(cx, env, id, v)) return false; } diff --git a/js/src/vm/DebuggerMemory.h b/js/src/vm/DebuggerMemory.h index 632cdad919..9ce2cffaa5 100644 --- a/js/src/vm/DebuggerMemory.h +++ b/js/src/vm/DebuggerMemory.h @@ -18,37 +18,37 @@ namespace js { class DebuggerMemory : public NativeObject { friend class Debugger; - static DebuggerMemory *checkThis(JSContext *cx, CallArgs &args, const char *fnName); + static DebuggerMemory* checkThis(JSContext* cx, CallArgs& args, const char* fnName); - Debugger *getDebugger(); + Debugger* getDebugger(); public: - static DebuggerMemory *create(JSContext *cx, Debugger *dbg); + static DebuggerMemory* create(JSContext* cx, Debugger* dbg); enum { JSSLOT_DEBUGGER, JSSLOT_COUNT }; - static bool construct(JSContext *cx, unsigned argc, Value *vp); + static bool construct(JSContext* cx, unsigned argc, Value* vp); static const Class class_; static const JSPropertySpec properties[]; static const JSFunctionSpec methods[]; // Accessor properties of Debugger.Memory.prototype. - static bool setTrackingAllocationSites(JSContext *cx, unsigned argc, Value *vp); - static bool getTrackingAllocationSites(JSContext *cx, unsigned argc, Value *vp); - static bool setMaxAllocationsLogLength(JSContext *cx, unsigned argc, Value *vp); - static bool getMaxAllocationsLogLength(JSContext *cx, unsigned argc, Value *vp); - static bool setAllocationSamplingProbability(JSContext *cx, unsigned argc, Value *vp); - static bool getAllocationSamplingProbability(JSContext *cx, unsigned argc, Value *vp); - static bool getAllocationsLogOverflowed(JSContext *cx, unsigned argc, Value *vp); - static bool getOnGarbageCollection(JSContext *cx, unsigned argc, Value *vp); - static bool setOnGarbageCollection(JSContext *cx, unsigned argc, Value *vp); + static bool setTrackingAllocationSites(JSContext* cx, unsigned argc, Value* vp); + static bool getTrackingAllocationSites(JSContext* cx, unsigned argc, Value* vp); + static bool setMaxAllocationsLogLength(JSContext* cx, unsigned argc, Value* vp); + static bool getMaxAllocationsLogLength(JSContext* cx, unsigned argc, Value* vp); + static bool setAllocationSamplingProbability(JSContext* cx, unsigned argc, Value* vp); + static bool getAllocationSamplingProbability(JSContext* cx, unsigned argc, Value* vp); + static bool getAllocationsLogOverflowed(JSContext* cx, unsigned argc, Value* vp); + static bool getOnGarbageCollection(JSContext* cx, unsigned argc, Value* vp); + static bool setOnGarbageCollection(JSContext* cx, unsigned argc, Value* vp); // Function properties of Debugger.Memory.prototype. - static bool takeCensus(JSContext *cx, unsigned argc, Value *vp); - static bool drainAllocationsLog(JSContext *cx, unsigned argc, Value *vp); + static bool takeCensus(JSContext* cx, unsigned argc, Value* vp); + static bool drainAllocationsLog(JSContext* cx, unsigned argc, Value* vp); }; } /* namespace js */ diff --git a/js/src/vm/GlobalObject.h b/js/src/vm/GlobalObject.h index 56ba00cb9a..197d4f8264 100644 --- a/js/src/vm/GlobalObject.h +++ b/js/src/vm/GlobalObject.h @@ -606,11 +606,7 @@ class GlobalObject : public NativeObject MOZ_ASSERT(cx->runtime()->isSelfHostingGlobal(self)); #endif RootedObject holder(cx, intrinsicsHolder()); - RootedValue valCopy(cx, value); - ObjectOpResult result; - bool ok = SetProperty(cx, holder, holder, name, &valCopy, result); - MOZ_ASSERT_IF(ok, result); - return ok; + return SetProperty(cx, holder, name, value); } bool getSelfHostedFunction(JSContext* cx, HandleAtom selfHostedName, HandleAtom name, diff --git a/js/src/vm/Interpreter-inl.h b/js/src/vm/Interpreter-inl.h index 6e4ef1caf7..a1be6701f5 100644 --- a/js/src/vm/Interpreter-inl.h +++ b/js/src/vm/Interpreter-inl.h @@ -310,7 +310,6 @@ SetNameOperation(JSContext* cx, JSScript* script, jsbytecode* pc, HandleObject s bool strict = *pc == JSOP_STRICTSETNAME || *pc == JSOP_STRICTSETGNAME; RootedPropertyName name(cx, script->getName(pc)); - RootedValue valCopy(cx, val); // In strict mode, assigning to an undeclared global variable is an // error. To detect this, we call NativeSetProperty directly and pass @@ -318,12 +317,13 @@ SetNameOperation(JSContext* cx, JSScript* script, jsbytecode* pc, HandleObject s bool ok; ObjectOpResult result; RootedId id(cx, NameToId(name)); + RootedValue receiver(cx, ObjectValue(*scope)); if (scope->isUnqualifiedVarObj()) { MOZ_ASSERT(!scope->getOps()->setProperty); - ok = NativeSetProperty(cx, scope.as(), scope.as(), id, - Unqualified, &valCopy, result); + ok = NativeSetProperty(cx, scope.as(), id, val, receiver, Unqualified, + result); } else { - ok = SetProperty(cx, scope, scope, id, &valCopy, result); + ok = SetProperty(cx, scope, id, val, receiver, result); } return ok && result.checkStrictErrorOrWarning(cx, scope, id, strict); } @@ -338,8 +338,7 @@ InitPropertyOperation(JSContext *cx, JSOp op, HandleObject obj, HandleId id, Han } MOZ_ASSERT(obj->as().layout().lookup(id)); - RootedValue v(cx, rhs); - return PutProperty(cx, obj, id, &v, false); + return PutProperty(cx, obj, id, rhs, false); } inline bool diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index 97a9e89679..36c7d7e243 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -317,52 +317,20 @@ GetNameOperation(JSContext *cx, InterpreterFrame *fp, jsbytecode *pc, MutableHan } static bool -SetObjectProperty(JSContext *cx, JSOp op, HandleValue lval, HandleId id, MutableHandleValue rref) +SetPropertyOperation(JSContext *cx, JSOp op, HandleValue lval, HandleId id, HandleValue rval) { - MOZ_ASSERT(lval.isObject()); - - RootedObject obj(cx, &lval.toObject()); - - ObjectOpResult result; - if (MOZ_LIKELY(!obj->getOps()->setProperty)) { - if (!NativeSetProperty(cx, obj.as(), obj.as(), id, - Qualified, rref, result)) - { - return false; - } - } else { - if (!SetProperty(cx, obj, obj, id, rref, result)) - return false; - } - - return result.checkStrictErrorOrWarning(cx, obj, id, op == JSOP_STRICTSETPROP); -} - -static bool -SetPrimitiveProperty(JSContext *cx, JSOp op, HandleValue lval, HandleId id, - MutableHandleValue rref) -{ - MOZ_ASSERT(lval.isPrimitive()); + MOZ_ASSERT(op == JSOP_SETPROP || op == JSOP_STRICTSETPROP); RootedObject obj(cx, ToObjectFromStack(cx, lval)); if (!obj) return false; + // Note: ES6 specifies that the value lval, not obj, is passed as receiver + // to obj's [[Set]] internal method. See bug 603201. RootedValue receiver(cx, ObjectValue(*obj)); - return SetObjectProperty(cx, op, receiver, id, rref); -} - -static bool -SetPropertyOperation(JSContext *cx, JSOp op, HandleValue lval, HandleId id, HandleValue rval) -{ - MOZ_ASSERT(op == JSOP_SETPROP || op == JSOP_STRICTSETPROP); - - RootedValue rref(cx, rval); - - if (lval.isPrimitive()) - return SetPrimitiveProperty(cx, op, lval, id, &rref); - - return SetObjectProperty(cx, op, lval, id, &rref); + ObjectOpResult result; + return SetProperty(cx, obj, id, rval, receiver, result) && + result.checkStrictErrorOrWarning(cx, obj, id, op == JSOP_STRICTSETPROP); } bool @@ -842,8 +810,7 @@ js::InvokeConstructor(JSContext* cx, Value fval, unsigned argc, const Value* arg } bool -js::InvokeGetterOrSetter(JSContext *cx, JSObject *obj, Value fval, unsigned argc, - Value *argv, MutableHandleValue rval) +js::InvokeGetter(JSContext *cx, JSObject *obj, Value fval, MutableHandleValue rval) { /* * Invoke could result in another try to get or set the same id again, see @@ -851,7 +818,16 @@ js::InvokeGetterOrSetter(JSContext *cx, JSObject *obj, Value fval, unsigned argc */ JS_CHECK_RECURSION(cx, return false); - return Invoke(cx, ObjectValue(*obj), fval, argc, argv, rval); + return Invoke(cx, ObjectValue(*obj), fval, 0, nullptr, rval); +} + +bool +js::InvokeSetter(JSContext *cx, const Value &thisv, Value fval, HandleValue v) +{ + JS_CHECK_RECURSION(cx, return false); + + RootedValue ignored(cx); + return Invoke(cx, thisv, fval, 1, v.address(), &ignored); } bool @@ -1668,7 +1644,7 @@ SetObjectElementOperation(JSContext* cx, Handle obj, HandleId id, con return false; RootedValue tmp(cx, value); - return PutProperty(cx, obj, id, &tmp, strict); + return PutProperty(cx, obj, id, tmp, strict); } static MOZ_NEVER_INLINE bool @@ -4177,7 +4153,8 @@ js::DefFunOperation(JSContext* cx, HandleScript script, HandleObject scopeChain, */ /* Step 5f. */ - return PutProperty(cx, parent, name, &rval, script->strict()); + RootedId id(cx, NameToId(name)); + return PutProperty(cx, parent, id, rval, script->strict()); } bool diff --git a/js/src/vm/Interpreter.h b/js/src/vm/Interpreter.h index 48bf89acf0..c277286e2e 100644 --- a/js/src/vm/Interpreter.h +++ b/js/src/vm/Interpreter.h @@ -76,12 +76,14 @@ Invoke(JSContext* cx, const Value& thisv, const Value& fval, unsigned argc, cons MutableHandleValue rval); /* - * This helper takes care of the infinite-recursion check necessary for + * These helpers take care of the infinite-recursion check necessary for * getter/setter calls. */ extern bool -InvokeGetterOrSetter(JSContext *cx, JSObject *obj, Value fval, unsigned argc, Value *argv, - MutableHandleValue rval); +InvokeGetter(JSContext *cx, JSObject *obj, Value fval, MutableHandleValue rval); + +extern bool +InvokeSetter(JSContext *cx, const Value &thisv, Value fval, HandleValue v); /* * InvokeConstructor implement a function call from a constructor context diff --git a/js/src/vm/NativeObject-inl.h b/js/src/vm/NativeObject-inl.h index 7deff11e20..e7c2fb22b4 100644 --- a/js/src/vm/NativeObject-inl.h +++ b/js/src/vm/NativeObject-inl.h @@ -72,8 +72,7 @@ NativeObject::clearShouldConvertDoubleElements() } inline void -NativeObject::setDenseElementWithType(ExclusiveContext *cx, uint32_t index, - const Value &val) +NativeObject::setDenseElementWithType(ExclusiveContext *cx, uint32_t index, const Value &val) { // Avoid a slow AddTypePropertyId call if the type is the same as the type // of the previous element. @@ -84,8 +83,7 @@ NativeObject::setDenseElementWithType(ExclusiveContext *cx, uint32_t index, } inline void -NativeObject::initDenseElementWithType(ExclusiveContext *cx, uint32_t index, - const Value &val) +NativeObject::initDenseElementWithType(ExclusiveContext *cx, uint32_t index, const Value &val) { MOZ_ASSERT(!shouldConvertDoubleElements()); AddTypePropertyId(cx, this, JSID_VOID, val); diff --git a/js/src/vm/NativeObject.cpp b/js/src/vm/NativeObject.cpp index ab6547b2e9..f23d83a3df 100644 --- a/js/src/vm/NativeObject.cpp +++ b/js/src/vm/NativeObject.cpp @@ -1130,8 +1130,8 @@ UpdateShapeTypeAndValue(ExclusiveContext* cx, NativeObject* obj, Shape* shape, c } static bool -NativeSet(JSContext *cx, HandleNativeObject obj, HandleObject receiver, - HandleShape shape, MutableHandleValue vp, ObjectOpResult &result); +NativeSetExistingDataProperty(JSContext *cx, HandleNativeObject obj, HandleShape shape, + HandleValue v, HandleValue receiver, ObjectOpResult &result); static inline bool DefinePropertyOrElement(ExclusiveContext *cx, HandleNativeObject obj, HandleId id, @@ -1221,10 +1221,13 @@ DefinePropertyOrElement(ExclusiveContext *cx, HandleNativeObject obj, HandleId i return false; if (callSetterAfterwards && setter) { + MOZ_ASSERT(!(attrs & JSPROP_GETTER)); + MOZ_ASSERT(!(attrs & JSPROP_SETTER)); if (!cx->shouldBeJSContext()) return false; - RootedValue nvalue(cx, value); - return NativeSet(cx->asJSContext(), obj, obj, shape, &nvalue, result); + RootedValue receiver(cx, ObjectValue(*obj)); + return NativeSetExistingDataProperty(cx->asJSContext(), obj, shape, value, receiver, + result); } return result.succeed(); @@ -1457,8 +1460,8 @@ js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId attrs = ApplyOrDefaultAttributes(attrs, shape); if (shape->isAccessorDescriptor() && !(attrs & JSPROP_IGNORE_READONLY)) { - // ES6 draft 2014-10-14 9.1.6.3 step 7.c: Since [[Writable]] - // is present, change the existing accessor property to a data + // ES6 draft 2014-10-14 9.1.6.3 step 7.c: Since [[Writable]] + // is present, change the existing accessor property to a data // property. updateValue = UndefinedValue(); } else { @@ -1620,6 +1623,7 @@ js::NativeHasProperty(JSContext* cx, HandleNativeObject obj, HandleId id, bool* } } + /*** [[Get]] *************************************************************************************/ static inline bool @@ -1629,7 +1633,7 @@ CallGetter(JSContext* cx, HandleObject receiver, HandleShape shape, MutableHandl if (shape->hasGetterValue()) { Value fval = shape->getterValue(); - return InvokeGetterOrSetter(cx, receiver, fval, 0, 0, vp); + return InvokeGetter(cx, receiver, fval, vp); } RootedId id(cx, shape->propid()); @@ -1945,6 +1949,7 @@ js::GetPropertyForNameLookup(JSContext* cx, HandleObject obj, HandleId id, Mutab return NativeGetPropertyInline(cx, obj.as(), obj, id, NameLookup, vp); } + /*** [[Set]] *************************************************************************************/ static bool @@ -1976,13 +1981,18 @@ MaybeReportUndeclaredVarAssignment(JSContext* cx, JSString* propname) * or finds a writable data property on the prototype chain, we end up here. * Finish the [[Set]] by defining a new property on receiver. * - * This implements ES6 draft rev 28, 9.1.9 [[Set]] steps 5.c-f, but it + * This implements ES6 draft rev 28, 9.1.9 [[Set]] steps 5.b-f, but it * is really old code and there are a few barnacles. */ bool -js::SetPropertyByDefining(JSContext* cx, HandleObject obj, HandleObject receiver, - HandleId id, HandleValue v, bool objHasOwn, ObjectOpResult &result) +js::SetPropertyByDefining(JSContext *cx, HandleObject obj, HandleId id, HandleValue v, + HandleValue receiverValue, bool objHasOwn, ObjectOpResult &result) { + // Step 5.b. + if (!receiverValue.isObject()) + return result.fail(JSMSG_SET_NON_OBJECT_RECEIVER); + RootedObject receiver(cx, &receiverValue.toObject()); + // Step 5.c-d: Test whether receiver has an existing own property // receiver[id]. The spec calls [[GetOwnProperty]]; js::HasOwnProperty is // the same thing except faster in the non-proxy case. Sometimes we can @@ -2035,6 +2045,8 @@ js::SetPropertyByDefining(JSContext* cx, HandleObject obj, HandleObject receiver if (!receiver->is()) return DefineProperty(cx, receiver, id, v, getter, setter, attrs, result); + // If the receiver is native, there is one more legacy wrinkle: the class + // JSSetterOp is called after defining the new property. Rooted nativeReceiver(cx, &receiver->as()); return DefinePropertyOrElement(cx, nativeReceiver, id, getter, setter, attrs, v, true, result); } @@ -2042,15 +2054,15 @@ js::SetPropertyByDefining(JSContext* cx, HandleObject obj, HandleObject receiver // When setting |id| for |receiver| and |obj| has no property for id, continue // the search up the prototype chain. bool -js::SetPropertyOnProto(JSContext* cx, HandleObject obj, HandleObject receiver, - HandleId id, MutableHandleValue vp, ObjectOpResult &result) +js::SetPropertyOnProto(JSContext *cx, HandleObject obj, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) { MOZ_ASSERT(!obj->is()); RootedObject proto(cx, obj->getProto()); if (proto) - return SetProperty(cx, proto, receiver, id, vp, result); - return SetPropertyByDefining(cx, obj, receiver, id, vp, false, result); + return SetProperty(cx, proto, id, v, receiver, result); + return SetPropertyByDefining(cx, obj, id, v, receiver, false, result); } /* @@ -2059,22 +2071,20 @@ js::SetPropertyOnProto(JSContext* cx, HandleObject obj, HandleObject receiver, * * FIXME: This should be updated to follow ES6 draft rev 28, section 9.1.9, * steps 4.d.i and 5. - * - * Note that receiver is not necessarily native. */ static bool -SetNonexistentProperty(JSContext* cx, HandleNativeObject obj, HandleObject receiver, HandleId id, - QualifiedBool qualified, HandleValue v, ObjectOpResult &result) +SetNonexistentProperty(JSContext *cx, HandleNativeObject obj, HandleId id, HandleValue v, + HandleValue receiver, QualifiedBool qualified, ObjectOpResult &result) { // We should never add properties to lexical blocks. - MOZ_ASSERT(!receiver->is()); + MOZ_ASSERT_IF(receiver.isObject(), !receiver.toObject().is()); - if (receiver->isUnqualifiedVarObj() && !qualified) { + if (!qualified && receiver.isObject() && receiver.toObject().isUnqualifiedVarObj()) { if (!MaybeReportUndeclaredVarAssignment(cx, JSID_TO_STRING(id))) return false; } - return SetPropertyByDefining(cx, obj, receiver, id, v, false, result); + return SetPropertyByDefining(cx, obj, id, v, receiver, false, result); } /* @@ -2082,12 +2092,12 @@ SetNonexistentProperty(JSContext* cx, HandleNativeObject obj, HandleObject recei * array element. */ static bool -SetDenseOrTypedArrayElement(JSContext* cx, HandleNativeObject obj, uint32_t index, - MutableHandleValue vp, ObjectOpResult &result) +SetDenseOrTypedArrayElement(JSContext *cx, HandleNativeObject obj, uint32_t index, HandleValue v, + ObjectOpResult &result) { if (IsAnyTypedArray(obj)) { double d; - if (!ToNumber(cx, vp, &d)) + if (!ToNumber(cx, v, &d)) return false; // Silently do nothing for out-of-bounds sets, for consistency with @@ -2109,129 +2119,152 @@ SetDenseOrTypedArrayElement(JSContext* cx, HandleNativeObject obj, uint32_t inde if (!obj->maybeCopyElementsForWrite(cx)) return false; - obj->setDenseElementWithType(cx, index, vp); + obj->setDenseElementWithType(cx, index, v); return result.succeed(); } /* - * Finish assignment to a shapeful property of a native object obj. This + * Finish assignment to a shapeful data property of a native object obj. This * conforms to no standard and there is a lot of legacy baggage here. */ static bool -NativeSet(JSContext *cx, HandleNativeObject obj, HandleObject receiver, - HandleShape shape, MutableHandleValue vp, ObjectOpResult &result) +NativeSetExistingDataProperty(JSContext *cx, HandleNativeObject obj, HandleShape shape, + HandleValue v, HandleValue receiver, ObjectOpResult &result) { MOZ_ASSERT(obj->isNative()); + MOZ_ASSERT(shape->isDataDescriptor()); + + if (shape->hasDefaultSetter()) { + if (shape->hasSlot()) { + // The common path. Standard data property. - if (shape->hasSlot()) { - /* If shape has a stub setter, just store vp. */ - if (shape->hasDefaultSetter()) { // Global properties declared with 'var' will be initially // defined with an undefined value, so don't treat the initial // assignments to such properties as overwrites. bool overwriting = !obj->is() || !obj->getSlot(shape->slot()).isUndefined(); - obj->setSlotWithType(cx, shape, vp, overwriting); + obj->setSlotWithType(cx, shape, v, overwriting); return result.succeed(); } + + // Bizarre: shared (slotless) property that's writable but has no + // JSSetterOp. JS code can't define such a property, but it can be done + // through the JSAPI. Treat it as non-writable. + return result.fail(JSMSG_GETTER_ONLY); } - if (!shape->hasSlot()) { - /* - * Allow API consumers to create shared properties with stub setters. - * Such properties effectively function as data descriptors which are - * not writable, so attempting to set such a property should do nothing - * or throw if we're in strict mode. - */ - if (!shape->hasGetterValue() && shape->hasDefaultSetter()) - return result.fail(JSMSG_GETTER_ONLY); - } - - RootedValue ovp(cx, vp); + MOZ_ASSERT(!obj->is()); // See bug 1128681. uint32_t sample = cx->runtime()->propertyRemovals; - if (!shape->set(cx, obj, receiver, vp, result)) + RootedId id(cx, shape->propid()); + RootedValue value(cx, v); + if (!CallJSSetterOp(cx, shape->setterOp(), obj, id, &value, result)) return false; - /* - * Update any slot for the shape with the value produced by the setter, - * unless the setter deleted the shape. - */ + // Update any slot for the shape with the value produced by the setter, + // unless the setter deleted the shape. if (shape->hasSlot() && (MOZ_LIKELY(cx->runtime()->propertyRemovals == sample) || obj->contains(cx, shape))) { - obj->setSlot(shape->slot(), vp); + obj->setSlot(shape->slot(), value); } - return true; // result is populated by shape->set() above. + return true; // result is populated by CallJSSetterOp above. } /* - * Implement "the rest of" assignment to receiver[id] when an existing property - * (shape) has been found on a native object (pobj). + * Finish the assignment `receiver[id] = v` when an existing property (shape) + * has been found on a native object (pobj). This implements ES6 draft rev 32 + * (2015 Feb 2) 9.1.9 steps 5 and 6. * * It is necessary to pass both id and shape because shape could be an implicit * dense or typed array element (i.e. not actually a pointer to a Shape). */ static bool -SetExistingProperty(JSContext* cx, HandleNativeObject obj, HandleObject receiver, HandleId id, - HandleNativeObject pobj, HandleShape shape, MutableHandleValue vp, +SetExistingProperty(JSContext *cx, HandleNativeObject obj, HandleId id, HandleValue v, + HandleValue receiver, HandleNativeObject pobj, HandleShape shape, ObjectOpResult &result) { + // Step 5 for dense elements. if (IsImplicitDenseOrTypedArrayElement(shape)) { - /* ES5 8.12.4 [[Put]] step 2, for a dense data property on pobj. */ - if (pobj == receiver) - return SetDenseOrTypedArrayElement(cx, pobj, JSID_TO_INT(id), vp, result); - } else { - /* ES5 8.12.4 [[Put]] step 2. */ - if (shape->isAccessorDescriptor()) { - if (shape->hasDefaultSetter()) - return result.fail(JSMSG_GETTER_ONLY); - } else { - MOZ_ASSERT(shape->isDataDescriptor()); + // Step 5.a is a no-op: all dense elements are writable. - if (!shape->writable()) - return result.fail(JSMSG_READ_ONLY); - } + // Pure optimization for the common case: + if (receiver.isObject() && pobj == &receiver.toObject()) + return SetDenseOrTypedArrayElement(cx, pobj, JSID_TO_INT(id), v, result); - if (pobj == receiver) { - if (pobj->is() && id == NameToId(cx->names().length)) { - Rooted arr(cx, &pobj->as()); - return ArraySetLength(cx, arr, id, shape->attributes(), vp, result); - } - return NativeSet(cx, obj, receiver, shape, vp, result); - } - - // pobj[id] is not an own property of receiver. Call the setter or shadow it. - if (!shape->shadowable() && - !(pobj->is() && id == NameToId(cx->names().length))) - { - // Weird special case: slotless property with default setter. - if (shape->hasDefaultSetter() && !shape->hasGetterValue()) - return result.succeed(); - - return shape->set(cx, obj, receiver, vp, result); - } + // Steps 5.b-f. + return SetPropertyByDefining(cx, obj, id, v, receiver, obj == pobj, result); } - // Shadow pobj[id] by defining a new data property receiver[id]. - return SetPropertyByDefining(cx, obj, receiver, id, vp, obj == pobj, result); + // Step 5 for all other properties. + if (shape->isDataDescriptor()) { + // Step 5.a. + if (!shape->writable()) + return result.fail(JSMSG_READ_ONLY); + + // steps 5.c-f. + if (receiver.isObject() && pobj == &receiver.toObject()) { + // Pure optimization for the common case. There's no point performing + // the lookup in step 5.c again, as our caller just did it for us. The + // result is |shape|. + + // Steps 5.e.i-ii. + if (pobj->is() && id == NameToId(cx->names().length)) { + Rooted arr(cx, &pobj->as()); + return ArraySetLength(cx, arr, id, shape->attributes(), v, result); + } + return NativeSetExistingDataProperty(cx, obj, shape, v, receiver, result); + } + + // SpiderMonkey special case: assigning to an inherited slotless + // property causes the setter to be called, instead of shadowing, + // unless the existing property is JSPROP_SHADOWABLE (see bug 552432) + // or it's the array length property. + if (!shape->hasSlot() && + !shape->hasShadowable() && + !(pobj->is() && id == NameToId(cx->names().length))) + { + // Even weirder sub-special-case: inherited slotless data property + // with default setter. Wut. + if (shape->hasDefaultSetter()) + return result.succeed(); + + RootedValue valCopy(cx, v); + return CallJSSetterOp(cx, shape->setterOp(), obj, id, &valCopy, result); + } + + // Shadow pobj[id] by defining a new data property receiver[id]. + // Delegate everything to SetPropertyByDefining. + return SetPropertyByDefining(cx, obj, id, v, receiver, obj == pobj, result); + } + + // Steps 6-11. + MOZ_ASSERT(shape->isAccessorDescriptor()); + MOZ_ASSERT_IF(!shape->hasSetterObject(), shape->hasDefaultSetter()); + if (shape->hasDefaultSetter()) + return result.fail(JSMSG_GETTER_ONLY); + Value setter = ObjectValue(*shape->setterObject()); + if (!InvokeSetter(cx, receiver, setter, v)) + return false; + return result.succeed(); } bool -js::NativeSetProperty(JSContext* cx, HandleNativeObject obj, HandleObject receiver, HandleId id, - QualifiedBool qualified, MutableHandleValue vp, ObjectOpResult &result) +js::NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleId id, HandleValue value, + HandleValue receiver, QualifiedBool qualified, ObjectOpResult &result) { // Fire watchpoints, if any. + RootedValue v(cx, value); if (MOZ_UNLIKELY(obj->watched())) { - WatchpointMap* wpmap = cx->compartment()->watchpointMap; - if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, vp)) + WatchpointMap *wpmap = cx->compartment()->watchpointMap; + if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, &v)) return false; } // Step numbers below reference ES6 rev 27 9.1.9, the [[Set]] internal // method for ordinary objects. We substitute our own names for these names - // used in the spec: O -> pobj, P -> id, V -> *vp, ownDesc -> shape. + // used in the spec: O -> pobj, P -> id, ownDesc -> shape. RootedShape shape(cx); RootedNativeObject pobj(cx, obj); @@ -2246,7 +2279,7 @@ js::NativeSetProperty(JSContext* cx, HandleNativeObject obj, HandleObject receiv if (shape) { // Steps 5-6. - return SetExistingProperty(cx, obj, receiver, id, pobj, shape, vp, result); + return SetExistingProperty(cx, obj, id, v, receiver, pobj, shape, result); } // Steps 4.a-b. The check for 'done' on this next line is tricky. @@ -2260,7 +2293,7 @@ js::NativeSetProperty(JSContext* cx, HandleNativeObject obj, HandleObject receiv RootedObject proto(cx, done ? nullptr : pobj->getProto()); if (!proto) { // Step 4.d.i (and step 5). - return SetNonexistentProperty(cx, obj, receiver, id, qualified, vp, result); + return SetNonexistentProperty(cx, obj, id, v, receiver, qualified, result); } // Step 4.c.i. If the prototype is also native, this step is a @@ -2277,23 +2310,23 @@ js::NativeSetProperty(JSContext* cx, HandleNativeObject obj, HandleObject receiv if (!HasProperty(cx, proto, id, &found)) return false; if (!found) - return SetNonexistentProperty(cx, obj, receiver, id, qualified, vp, result); + return SetNonexistentProperty(cx, obj, id, v, receiver, qualified, result); } - return SetProperty(cx, proto, receiver, id, vp, result); + return SetProperty(cx, proto, id, v, receiver, result); } pobj = &proto->as(); } } bool -js::NativeSetElement(JSContext* cx, HandleNativeObject obj, HandleObject receiver, uint32_t index, - MutableHandleValue vp, ObjectOpResult &result) +js::NativeSetElement(JSContext *cx, HandleNativeObject obj, uint32_t index, HandleValue v, + HandleValue receiver, ObjectOpResult &result) { RootedId id(cx); if (!IndexToId(cx, index, &id)) return false; - return NativeSetProperty(cx, obj, receiver, id, Qualified, vp, result); + return NativeSetProperty(cx, obj, id, v, receiver, Qualified, result); } /*** [[Delete]] **********************************************************************************/ diff --git a/js/src/vm/NativeObject.h b/js/src/vm/NativeObject.h index 4c82339ca1..05ce5043af 100644 --- a/js/src/vm/NativeObject.h +++ b/js/src/vm/NativeObject.h @@ -1313,12 +1313,12 @@ NativeGetElement(JSContext* cx, HandleNativeObject obj, uint32_t index, MutableH } bool -SetPropertyByDefining(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id, - HandleValue v, bool objHasOwn, ObjectOpResult &result); +SetPropertyByDefining(JSContext *cx, HandleObject obj, HandleId id, HandleValue v, + HandleValue receiver, bool objHasOwn, ObjectOpResult &result); bool -SetPropertyOnProto(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id, - MutableHandleValue vp, ObjectOpResult &result); +SetPropertyOnProto(JSContext *cx, HandleObject obj, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result); /* * Indicates whether an assignment operation is qualified (`x.y = 0`) or @@ -1333,12 +1333,12 @@ enum QualifiedBool { }; extern bool -NativeSetProperty(JSContext* cx, HandleNativeObject obj, HandleObject receiver, HandleId id, - QualifiedBool qualified, MutableHandleValue vp, ObjectOpResult &result); +NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleId id, HandleValue v, + HandleValue receiver, QualifiedBool qualified, ObjectOpResult &result); extern bool -NativeSetElement(JSContext* cx, HandleNativeObject obj, HandleObject receiver, uint32_t index, - MutableHandleValue vp, ObjectOpResult &result); +NativeSetElement(JSContext *cx, HandleNativeObject obj, uint32_t index, HandleValue v, + HandleValue receiver, ObjectOpResult &result); extern bool NativeDeleteProperty(JSContext *cx, HandleNativeObject obj, HandleId id, ObjectOpResult &result); @@ -1449,21 +1449,21 @@ js::GetPropertyNoGC(JSContext* cx, JSObject* obj, JSObject* receiver, jsid id, V } inline bool -js::SetProperty(JSContext* cx, HandleObject obj, HandleObject receiver, - HandleId id, MutableHandleValue vp, ObjectOpResult &result) +js::SetProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) { if (obj->getOps()->setProperty) - return JSObject::nonNativeSetProperty(cx, obj, receiver, id, vp, result); - return NativeSetProperty(cx, obj.as(), receiver, id, Qualified, vp, result); + return JSObject::nonNativeSetProperty(cx, obj, id, v, receiver, result); + return NativeSetProperty(cx, obj.as(), id, v, receiver, Qualified, result); } inline bool -js::SetElement(JSContext* cx, HandleObject obj, HandleObject receiver, uint32_t index, - MutableHandleValue vp, ObjectOpResult &result) +js::SetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue v, + HandleValue receiver, ObjectOpResult &result) { if (obj->getOps()->setProperty) - return JSObject::nonNativeSetElement(cx, obj, receiver, index, vp, result); - return NativeSetElement(cx, obj.as(), receiver, index, vp, result); + return JSObject::nonNativeSetElement(cx, obj, index, v, receiver, result); + return NativeSetElement(cx, obj.as(), index, v, receiver, result); } #endif /* vm_NativeObject_h */ diff --git a/js/src/vm/ObjectGroup.cpp b/js/src/vm/ObjectGroup.cpp index 5e5db3be10..2f0faeacf5 100644 --- a/js/src/vm/ObjectGroup.cpp +++ b/js/src/vm/ObjectGroup.cpp @@ -24,7 +24,7 @@ using mozilla::PodZero; // ObjectGroup ///////////////////////////////////////////////////////////////////// -ObjectGroup::ObjectGroup(const Class *clasp, TaggedProto proto, JSCompartment *comp, +ObjectGroup::ObjectGroup(const Class* clasp, TaggedProto proto, JSCompartment* comp, ObjectGroupFlags initialFlags) { PodZero(this); @@ -291,8 +291,8 @@ JSObject::splicePrototype(JSContext* cx, const Class* clasp, Handle return true; } -/* static */ ObjectGroup * -JSObject::makeLazyGroup(JSContext *cx, HandleObject obj) +/* static */ ObjectGroup* +JSObject::makeLazyGroup(JSContext* cx, HandleObject obj) { MOZ_ASSERT(obj->hasLazyGroup()); MOZ_ASSERT(cx->compartment() == obj->compartment()); @@ -311,7 +311,7 @@ JSObject::makeLazyGroup(JSContext *cx, HandleObject obj) initialFlags |= OBJECT_FLAG_LENGTH_OVERFLOW; Rooted proto(cx, obj->getTaggedProto()); - ObjectGroup *group = ObjectGroupCompartment::makeGroup(cx, obj->getClass(), proto, + ObjectGroup* group = ObjectGroupCompartment::makeGroup(cx, obj->getClass(), proto, initialFlags); if (!group) return nullptr; @@ -586,7 +586,7 @@ ObjectGroup::lazySingletonGroup(ExclusiveContext* cx, const Class* clasp, Tagged AutoEnterAnalysis enter(cx); Rooted protoRoot(cx, proto); - ObjectGroup *group = + ObjectGroup* group = ObjectGroupCompartment::makeGroup(cx, clasp, protoRoot, OBJECT_FLAG_SINGLETON | OBJECT_FLAG_LAZY_SINGLETON); if (!group) @@ -791,12 +791,12 @@ ObjectGroup::fixRestArgumentsGroup(ExclusiveContext* cx, ArrayObject* obj) } /* static */ void -ObjectGroup::setGroupToHomogenousArray(ExclusiveContext *cx, JSObject *obj, +ObjectGroup::setGroupToHomogenousArray(ExclusiveContext* cx, JSObject* obj, TypeSet::Type elementType) { MOZ_ASSERT(cx->zone()->types.activeAnalysis); - ObjectGroupCompartment::ArrayObjectTable *&table = + ObjectGroupCompartment::ArrayObjectTable*& table = cx->compartment()->objectGroups.arrayObjectTable; if (!table) { @@ -834,24 +834,24 @@ ObjectGroup::setGroupToHomogenousArray(ExclusiveContext *cx, JSObject *obj, struct ObjectGroupCompartment::PlainObjectKey { - jsid *properties; + jsid* properties; uint32_t nproperties; struct Lookup { - IdValuePair *properties; + IdValuePair* properties; uint32_t nproperties; - Lookup(IdValuePair *properties, uint32_t nproperties) + Lookup(IdValuePair* properties, uint32_t nproperties) : properties(properties), nproperties(nproperties) {} }; - static inline HashNumber hash(const Lookup &lookup) { + static inline HashNumber hash(const Lookup& lookup) { return (HashNumber) (JSID_BITS(lookup.properties[lookup.nproperties - 1].id) ^ lookup.nproperties); } - static inline bool match(const PlainObjectKey &v, const Lookup &lookup) { + static inline bool match(const PlainObjectKey& v, const Lookup& lookup) { if (lookup.nproperties != v.nproperties) return false; for (size_t i = 0; i < lookup.nproperties; i++) { @@ -883,8 +883,8 @@ CanShareObjectGroup(IdValuePair *properties, size_t nproperties) } static bool -AddPlainObjectProperties(ExclusiveContext *cx, HandlePlainObject obj, - IdValuePair *properties, size_t nproperties) +AddPlainObjectProperties(ExclusiveContext* cx, HandlePlainObject obj, + IdValuePair* properties, size_t nproperties) { RootedId propid(cx); RootedValue value(cx); @@ -899,8 +899,8 @@ AddPlainObjectProperties(ExclusiveContext *cx, HandlePlainObject obj, return true; } -PlainObject * -js::NewPlainObjectWithProperties(ExclusiveContext *cx, IdValuePair *properties, size_t nproperties, +PlainObject* +js::NewPlainObjectWithProperties(ExclusiveContext* cx, IdValuePair* properties, size_t nproperties, NewObjectKind newKind) { gc::AllocKind allocKind = gc::GetGCObjectKind(nproperties); @@ -910,15 +910,15 @@ js::NewPlainObjectWithProperties(ExclusiveContext *cx, IdValuePair *properties, return obj; } -/* static */ JSObject * -ObjectGroup::newPlainObject(ExclusiveContext *cx, IdValuePair *properties, size_t nproperties, +/* static */ JSObject* +ObjectGroup::newPlainObject(ExclusiveContext* cx, IdValuePair* properties, size_t nproperties, NewObjectKind newKind) { // Watch for simple cases where we don't try to reuse plain object groups. if (newKind == SingletonObject || nproperties == 0 || nproperties >= PropertyTree::MAX_HEIGHT) return NewPlainObjectWithProperties(cx, properties, nproperties, newKind); - ObjectGroupCompartment::PlainObjectTable *&table = + ObjectGroupCompartment::PlainObjectTable*& table = cx->compartment()->objectGroups.plainObjectTable; if (!table) { @@ -959,7 +959,7 @@ ObjectGroup::newPlainObject(ExclusiveContext *cx, IdValuePair *properties, size_ // default (which will have unknown properties) so that the group we // just created will be collected by the GC. if (obj->slotSpan() != nproperties) { - ObjectGroup *group = defaultNewGroup(cx, obj->getClass(), obj->getTaggedProto()); + ObjectGroup* group = defaultNewGroup(cx, obj->getClass(), obj->getTaggedProto()); if (!group) return nullptr; obj->setGroup(group); @@ -969,7 +969,7 @@ ObjectGroup::newPlainObject(ExclusiveContext *cx, IdValuePair *properties, size_ // Keep track of the initial objects we create with this type. // If the initial ones have a consistent shape and property types, we // will try to use an unboxed layout for the group. - PreliminaryObjectArrayWithTemplate *preliminaryObjects = + PreliminaryObjectArrayWithTemplate* preliminaryObjects = cx->new_(obj->lastProperty()); if (!preliminaryObjects) return nullptr; @@ -1137,9 +1137,9 @@ ObjectGroup::allocationSiteGroup(JSContext* cx, JSScript* script, jsbytecode* pc if (JSOp(*pc) == JSOP_NEWOBJECT) { // Keep track of the preliminary objects with this group, so we can try // to use an unboxed layout for the object once some are allocated. - Shape *shape = script->getObject(pc)->as().lastProperty(); + Shape* shape = script->getObject(pc)->as().lastProperty(); if (!shape->isEmptyShape()) { - PreliminaryObjectArrayWithTemplate *preliminaryObjects = + PreliminaryObjectArrayWithTemplate* preliminaryObjects = cx->new_(shape); if (preliminaryObjects) res->setPreliminaryObjects(preliminaryObjects); @@ -1154,10 +1154,10 @@ ObjectGroup::allocationSiteGroup(JSContext* cx, JSScript* script, jsbytecode* pc return res; } -/* static */ ObjectGroup * -ObjectGroup::callingAllocationSiteGroup(JSContext *cx, JSProtoKey key) +/* static */ ObjectGroup* +ObjectGroup::callingAllocationSiteGroup(JSContext* cx, JSProtoKey key) { - jsbytecode *pc; + jsbytecode* pc; RootedScript script(cx, cx->currentScript(&pc)); if (script) return allocationSiteGroup(cx, script, pc, key); @@ -1192,8 +1192,8 @@ ObjectGroup::setAllocationSiteObjectGroup(JSContext* cx, return true; } -/* static */ ArrayObject * -ObjectGroup::getOrFixupCopyOnWriteObject(JSContext *cx, HandleScript script, jsbytecode *pc) +/* static */ ArrayObject* +ObjectGroup::getOrFixupCopyOnWriteObject(JSContext* cx, HandleScript script, jsbytecode* pc) { // Make sure that the template object for script/pc has a type indicating // that the object and its copies have copy on write elements. @@ -1214,7 +1214,7 @@ ObjectGroup::getOrFixupCopyOnWriteObject(JSContext *cx, HandleScript script, jsb // Update type information in the initializer object group. MOZ_ASSERT(obj->slotSpan() == 0); for (size_t i = 0; i < obj->getDenseInitializedLength(); i++) { - const Value &v = obj->getDenseElement(i); + const Value& v = obj->getDenseElement(i); AddTypePropertyId(cx, group, nullptr, JSID_VOID, v); } @@ -1304,14 +1304,14 @@ ObjectGroupCompartment::replaceDefaultNewGroup(const Class* clasp, TaggedProto p } /* static */ -ObjectGroup * -ObjectGroupCompartment::makeGroup(ExclusiveContext *cx, const Class *clasp, +ObjectGroup* +ObjectGroupCompartment::makeGroup(ExclusiveContext* cx, const Class* clasp, Handle proto, ObjectGroupFlags initialFlags /* = 0 */) { MOZ_ASSERT_IF(proto.isObject(), cx->isInsideCurrentCompartment(proto.toObject())); - ObjectGroup *group = Allocate(cx); + ObjectGroup* group = Allocate(cx); if (!group) return nullptr; new(group) ObjectGroup(clasp, proto, cx->compartment(), initialFlags); @@ -1363,8 +1363,8 @@ ObjectGroupCompartment::clearTables() arrayObjectTable->clear(); if (plainObjectTable && plainObjectTable->initialized()) { for (PlainObjectTable::Enum e(*plainObjectTable); !e.empty(); e.popFront()) { - const PlainObjectKey &key = e.front().key(); - PlainObjectEntry &entry = e.front().value(); + const PlainObjectKey& key = e.front().key(); + PlainObjectEntry& entry = e.front().value(); js_free(key.properties); js_free(entry.types); } diff --git a/js/src/vm/Runtime-inl.h b/js/src/vm/Runtime-inl.h index 4b28f5f515..af11943dba 100644 --- a/js/src/vm/Runtime-inl.h +++ b/js/src/vm/Runtime-inl.h @@ -20,37 +20,37 @@ namespace js { inline bool -NewObjectCache::lookupProto(const Class *clasp, JSObject *proto, gc::AllocKind kind, EntryIndex *pentry) +NewObjectCache::lookupProto(const Class* clasp, JSObject* proto, gc::AllocKind kind, EntryIndex* pentry) { MOZ_ASSERT(!proto->is()); return lookup(clasp, proto, kind, pentry); } inline bool -NewObjectCache::lookupGlobal(const Class *clasp, GlobalObject *global, gc::AllocKind kind, EntryIndex *pentry) +NewObjectCache::lookupGlobal(const Class* clasp, GlobalObject* global, gc::AllocKind kind, EntryIndex* pentry) { return lookup(clasp, global, kind, pentry); } inline void -NewObjectCache::fillGlobal(EntryIndex entry, const Class *clasp, GlobalObject *global, - gc::AllocKind kind, NativeObject *obj) +NewObjectCache::fillGlobal(EntryIndex entry, const Class* clasp, GlobalObject* global, + gc::AllocKind kind, NativeObject* obj) { //MOZ_ASSERT(global == obj->getGlobal()); return fill(entry, clasp, global, kind, obj); } -inline NativeObject * -NewObjectCache::newObjectFromHit(JSContext *cx, EntryIndex entryIndex, gc::InitialHeap heap) +inline NativeObject* +NewObjectCache::newObjectFromHit(JSContext* cx, EntryIndex entryIndex, gc::InitialHeap heap) { MOZ_ASSERT(unsigned(entryIndex) < mozilla::ArrayLength(entries)); - Entry *entry = &entries[entryIndex]; + Entry* entry = &entries[entryIndex]; - NativeObject *templateObj = reinterpret_cast(&entry->templateObject); + NativeObject* templateObj = reinterpret_cast(&entry->templateObject); // Do an end run around JSObject::group() to avoid doing AutoUnprotectCell // on the templateObj, which is not a GC thing and can't use runtimeFromAnyThread. - ObjectGroup *group = templateObj->group_; + ObjectGroup* group = templateObj->group_; if (group->shouldPreTenure()) heap = gc::TenuredHeap; @@ -58,7 +58,7 @@ NewObjectCache::newObjectFromHit(JSContext *cx, EntryIndex entryIndex, gc::Initi if (cx->runtime()->gc.upcomingZealousGC()) return nullptr; - NativeObject *obj = static_cast(Allocate(cx, entry->kind, 0, + NativeObject* obj = static_cast(Allocate(cx, entry->kind, 0, heap, group->clasp())); if (!obj) return nullptr; diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index e647c6eebf..a59e001896 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -67,13 +67,13 @@ struct DtoaState; namespace js { extern MOZ_COLD void -ReportOutOfMemory(ExclusiveContext *cx); +ReportOutOfMemory(ExclusiveContext* cx); extern MOZ_COLD void -ReportAllocationOverflow(ExclusiveContext *maybecx); +ReportAllocationOverflow(ExclusiveContext* maybecx); extern MOZ_COLD void -ReportOverRecursed(ExclusiveContext *cx); +ReportOverRecursed(ExclusiveContext* cx); class Activation; @@ -345,7 +345,7 @@ class NewObjectCache js_memcpy(&entry->templateObject, obj, entry->nbytes); } - static void copyCachedToObject(NativeObject *dst, NativeObject *src, gc::AllocKind kind) { + static void copyCachedToObject(NativeObject* dst, NativeObject* src, gc::AllocKind kind) { js_memcpy(dst, src, gc::Arena::thingSize(kind)); Shape::writeBarrierPost(dst->shape_, &dst->shape_); ObjectGroup::writeBarrierPost(dst->group_, &dst->group_); diff --git a/js/src/vm/SavedStacks.cpp b/js/src/vm/SavedStacks.cpp index d2f1dc1a09..0f3176d0f9 100644 --- a/js/src/vm/SavedStacks.cpp +++ b/js/src/vm/SavedStacks.cpp @@ -42,9 +42,9 @@ namespace js { const unsigned ASYNC_STACK_MAX_FRAME_COUNT = 60; struct SavedFrame::Lookup { - Lookup(JSAtom *source, uint32_t line, uint32_t column, - JSAtom *functionDisplayName, JSAtom *asyncCause, SavedFrame *parent, - JSPrincipals *principals) + Lookup(JSAtom* source, uint32_t line, uint32_t column, + JSAtom* functionDisplayName, JSAtom* asyncCause, SavedFrame* parent, + JSPrincipals* principals) : source(source), line(line), column(column), @@ -56,7 +56,7 @@ struct SavedFrame::Lookup { MOZ_ASSERT(source); } - explicit Lookup(SavedFrame &savedFrame) + explicit Lookup(SavedFrame& savedFrame) : source(savedFrame.getSource()), line(savedFrame.getLine()), column(savedFrame.getColumn()), @@ -359,8 +359,8 @@ SavedFrame::construct(JSContext* cx, unsigned argc, Value* vp) // no such frame, return nullptr. |skippedAsync| is set to true if any of the // skipped frames had the |asyncCause| property set, otherwise it is explicitly // set to false. -static SavedFrame * -GetFirstSubsumedFrame(JSContext *cx, HandleSavedFrame frame, bool &skippedAsync) +static SavedFrame* +GetFirstSubsumedFrame(JSContext* cx, HandleSavedFrame frame, bool& skippedAsync) { skippedAsync = false; @@ -463,7 +463,7 @@ namespace { class MOZ_STACK_CLASS AutoMaybeEnterFrameCompartment { public: - AutoMaybeEnterFrameCompartment(JSContext *cx, + AutoMaybeEnterFrameCompartment(JSContext* cx, HandleObject obj MOZ_GUARD_OBJECT_NOTIFIER_PARAM) { @@ -488,8 +488,8 @@ public: } // namespace -static inline js::SavedFrame * -UnwrapSavedFrame(JSContext *cx, HandleObject obj, bool &skippedAsync) +static inline js::SavedFrame* +UnwrapSavedFrame(JSContext* cx, HandleObject obj, bool& skippedAsync) { if (!obj) return nullptr; @@ -501,7 +501,7 @@ UnwrapSavedFrame(JSContext *cx, HandleObject obj, bool &skippedAsync) } JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameSource(JSContext *cx, HandleObject savedFrame, MutableHandleString sourcep) +GetSavedFrameSource(JSContext* cx, HandleObject savedFrame, MutableHandleString sourcep) { AutoMaybeEnterFrameCompartment ac(cx, savedFrame); bool skippedAsync; @@ -515,7 +515,7 @@ GetSavedFrameSource(JSContext *cx, HandleObject savedFrame, MutableHandleString } JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameLine(JSContext *cx, HandleObject savedFrame, uint32_t *linep) +GetSavedFrameLine(JSContext* cx, HandleObject savedFrame, uint32_t* linep) { MOZ_ASSERT(linep); AutoMaybeEnterFrameCompartment ac(cx, savedFrame); @@ -530,7 +530,7 @@ GetSavedFrameLine(JSContext *cx, HandleObject savedFrame, uint32_t *linep) } JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameColumn(JSContext *cx, HandleObject savedFrame, uint32_t *columnp) +GetSavedFrameColumn(JSContext* cx, HandleObject savedFrame, uint32_t* columnp) { MOZ_ASSERT(columnp); AutoMaybeEnterFrameCompartment ac(cx, savedFrame); @@ -545,7 +545,7 @@ GetSavedFrameColumn(JSContext *cx, HandleObject savedFrame, uint32_t *columnp) } JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameFunctionDisplayName(JSContext *cx, HandleObject savedFrame, MutableHandleString namep) +GetSavedFrameFunctionDisplayName(JSContext* cx, HandleObject savedFrame, MutableHandleString namep) { AutoMaybeEnterFrameCompartment ac(cx, savedFrame); bool skippedAsync; @@ -559,7 +559,7 @@ GetSavedFrameFunctionDisplayName(JSContext *cx, HandleObject savedFrame, Mutable } JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameAsyncCause(JSContext *cx, HandleObject savedFrame, MutableHandleString asyncCausep) +GetSavedFrameAsyncCause(JSContext* cx, HandleObject savedFrame, MutableHandleString asyncCausep) { AutoMaybeEnterFrameCompartment ac(cx, savedFrame); bool skippedAsync; @@ -575,7 +575,7 @@ GetSavedFrameAsyncCause(JSContext *cx, HandleObject savedFrame, MutableHandleStr } JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameAsyncParent(JSContext *cx, HandleObject savedFrame, MutableHandleObject asyncParentp) +GetSavedFrameAsyncParent(JSContext* cx, HandleObject savedFrame, MutableHandleObject asyncParentp) { AutoMaybeEnterFrameCompartment ac(cx, savedFrame); bool skippedAsync; @@ -602,7 +602,7 @@ GetSavedFrameAsyncParent(JSContext *cx, HandleObject savedFrame, MutableHandleOb } JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameParent(JSContext *cx, HandleObject savedFrame, MutableHandleObject parentp) +GetSavedFrameParent(JSContext* cx, HandleObject savedFrame, MutableHandleObject parentp) { AutoMaybeEnterFrameCompartment ac(cx, savedFrame); bool skippedAsync; @@ -690,7 +690,7 @@ StringifySavedFrameStack(JSContext *cx, HandleObject stack, MutableHandleString namespace js { /* static */ bool -SavedFrame::sourceProperty(JSContext *cx, unsigned argc, Value *vp) +SavedFrame::sourceProperty(JSContext* cx, unsigned argc, Value* vp) { THIS_SAVEDFRAME(cx, argc, vp, "(get source)", args, frame); RootedString source(cx); @@ -702,7 +702,7 @@ SavedFrame::sourceProperty(JSContext *cx, unsigned argc, Value *vp) } /* static */ bool -SavedFrame::lineProperty(JSContext *cx, unsigned argc, Value *vp) +SavedFrame::lineProperty(JSContext* cx, unsigned argc, Value* vp) { THIS_SAVEDFRAME(cx, argc, vp, "(get line)", args, frame); uint32_t line; @@ -714,7 +714,7 @@ SavedFrame::lineProperty(JSContext *cx, unsigned argc, Value *vp) } /* static */ bool -SavedFrame::columnProperty(JSContext *cx, unsigned argc, Value *vp) +SavedFrame::columnProperty(JSContext* cx, unsigned argc, Value* vp) { THIS_SAVEDFRAME(cx, argc, vp, "(get column)", args, frame); uint32_t column; @@ -726,7 +726,7 @@ SavedFrame::columnProperty(JSContext *cx, unsigned argc, Value *vp) } /* static */ bool -SavedFrame::functionDisplayNameProperty(JSContext *cx, unsigned argc, Value *vp) +SavedFrame::functionDisplayNameProperty(JSContext* cx, unsigned argc, Value* vp) { THIS_SAVEDFRAME(cx, argc, vp, "(get functionDisplayName)", args, frame); RootedString name(cx); @@ -739,7 +739,7 @@ SavedFrame::functionDisplayNameProperty(JSContext *cx, unsigned argc, Value *vp) } /* static */ bool -SavedFrame::asyncCauseProperty(JSContext *cx, unsigned argc, Value *vp) +SavedFrame::asyncCauseProperty(JSContext* cx, unsigned argc, Value* vp) { THIS_SAVEDFRAME(cx, argc, vp, "(get asyncCause)", args, frame); RootedString asyncCause(cx); @@ -752,7 +752,7 @@ SavedFrame::asyncCauseProperty(JSContext *cx, unsigned argc, Value *vp) } /* static */ bool -SavedFrame::asyncParentProperty(JSContext *cx, unsigned argc, Value *vp) +SavedFrame::asyncParentProperty(JSContext* cx, unsigned argc, Value* vp) { THIS_SAVEDFRAME(cx, argc, vp, "(get asyncParent)", args, frame); RootedObject asyncParent(cx); @@ -762,7 +762,7 @@ SavedFrame::asyncParentProperty(JSContext *cx, unsigned argc, Value *vp) } /* static */ bool -SavedFrame::parentProperty(JSContext *cx, unsigned argc, Value *vp) +SavedFrame::parentProperty(JSContext* cx, unsigned argc, Value* vp) { THIS_SAVEDFRAME(cx, argc, vp, "(get parent)", args, frame); RootedObject parent(cx); @@ -772,7 +772,7 @@ SavedFrame::parentProperty(JSContext *cx, unsigned argc, Value *vp) } /* static */ bool -SavedFrame::toStringMethod(JSContext *cx, unsigned argc, Value *vp) +SavedFrame::toStringMethod(JSContext* cx, unsigned argc, Value* vp) { THIS_SAVEDFRAME(cx, argc, vp, "toString", args, frame); RootedString string(cx); @@ -821,7 +821,7 @@ SavedStacks::sweep(JSRuntime* rt) if (obj != temp || parentMoved) { e.rekeyFront(SavedFrame::Lookup(*frame), - ReadBarriered(frame)); + ReadBarriered(frame)); } } } @@ -881,14 +881,14 @@ SavedStacks::insertFrames(JSContext* cx, FrameIter& iter, MutableHandleSavedFram // pointers on the first pass, and then we fill in the parent pointers as we // return in the second pass. - Activation *asyncActivation = nullptr; + Activation* asyncActivation = nullptr; RootedSavedFrame asyncStack(cx, nullptr); RootedString asyncCause(cx, nullptr); // Accumulate the vector of Lookup objects in |stackChain|. SavedFrame::AutoLookupVector stackChain(cx); while (!iter.done()) { - Activation &activation = *iter.activation(); + Activation& activation = *iter.activation(); if (!asyncActivation) { asyncStack = activation.asyncStack(); @@ -967,7 +967,7 @@ SavedStacks::insertFrames(JSContext* cx, FrameIter& iter, MutableHandleSavedFram } bool -SavedStacks::adoptAsyncStack(JSContext *cx, HandleSavedFrame asyncStack, +SavedStacks::adoptAsyncStack(JSContext* cx, HandleSavedFrame asyncStack, HandleString asyncCause, MutableHandleSavedFrame adoptedStack, unsigned maxFrameCount) @@ -985,7 +985,7 @@ SavedStacks::adoptAsyncStack(JSContext *cx, HandleSavedFrame asyncStack, // Accumulate the vector of Lookup objects in |stackChain|. SavedFrame::AutoLookupVector stackChain(cx); - SavedFrame *currentSavedFrame = asyncStack; + SavedFrame* currentSavedFrame = asyncStack; for (unsigned i = 0; i < maxFrameCount && currentSavedFrame; i++) { // Use growByUninitialized and placement-new instead of just append. // We'd ideally like to use an emplace method once Vector supports it. @@ -1015,10 +1015,10 @@ SavedStacks::adoptAsyncStack(JSContext *cx, HandleSavedFrame asyncStack, return true; } -SavedFrame * -SavedStacks::getOrCreateSavedFrame(JSContext *cx, SavedFrame::HandleLookup lookup) +SavedFrame* +SavedStacks::getOrCreateSavedFrame(JSContext* cx, SavedFrame::HandleLookup lookup) { - const SavedFrame::Lookup &lookupInstance = lookup.get(); + const SavedFrame::Lookup& lookupInstance = lookup.get(); DependentAddPtr p(cx, frames, lookupInstance); if (p) return *p; @@ -1157,10 +1157,10 @@ SavedStacks::chooseSamplingProbability(JSContext* cx) allocationSamplingProbability = allocationTrackingDbg->allocationSamplingProbability; } -JSObject * -SavedStacksMetadataCallback(JSContext *cx) +JSObject* +SavedStacksMetadataCallback(JSContext* cx) { - SavedStacks &stacks = cx->compartment()->savedStacks(); + SavedStacks& stacks = cx->compartment()->savedStacks(); if (stacks.allocationSkipCount > 0) { stacks.allocationSkipCount--; return nullptr; @@ -1205,7 +1205,7 @@ SavedStacksMetadataCallback(JSContext *cx) return frame; } -JS_FRIEND_API(JSPrincipals *) +JS_FRIEND_API(JSPrincipals*) GetSavedFramePrincipals(HandleObject savedFrame) { MOZ_ASSERT(savedFrame); diff --git a/js/src/vm/SavedStacks.h b/js/src/vm/SavedStacks.h index 1f161a0ab1..02bc6067e5 100644 --- a/js/src/vm/SavedStacks.h +++ b/js/src/vm/SavedStacks.h @@ -240,10 +240,10 @@ class SavedStacks { PCLocationMap pcLocationMap; void sweepPCLocationMap(); - bool getLocation(JSContext *cx, const FrameIter &iter, MutableHandleLocationValue locationp); + bool getLocation(JSContext* cx, const FrameIter& iter, MutableHandleLocationValue locationp); }; -JSObject *SavedStacksMetadataCallback(JSContext *cx); +JSObject* SavedStacksMetadataCallback(JSContext* cx); } /* namespace js */ diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index 8eebff1202..e6f654552e 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -299,7 +299,7 @@ CallObject::createHollowForDebug(JSContext* cx, HandleFunction callee) RootedScript script(cx, callee->nonLazyScript()); for (BindingIter bi(script); !bi.done(); bi++) { id = NameToId(bi->name()); - if (!SetProperty(cx, callobj, callobj, id, &optimizedOut)) + if (!SetProperty(cx, callobj, id, optimizedOut)) return nullptr; } @@ -532,14 +532,14 @@ with_GetProperty(JSContext* cx, HandleObject obj, HandleObject receiver, HandleI } static bool -with_SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id, - MutableHandleValue vp, ObjectOpResult &result) +with_SetProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) { RootedObject actual(cx, &obj->as().object()); - RootedObject actualReceiver(cx, receiver); - if (receiver == obj) - actualReceiver = actual; - return SetProperty(cx, actual, actualReceiver, id, vp, result); + RootedValue actualReceiver(cx, receiver); + if (receiver.isObject() && &receiver.toObject() == obj) + actualReceiver.setObject(*actual); + return SetProperty(cx, actual, id, v, actualReceiver, result); } static bool @@ -998,8 +998,8 @@ uninitialized_GetProperty(JSContext* cx, HandleObject obj, HandleObject receiver } static bool -uninitialized_SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id, - MutableHandleValue vp, ObjectOpResult &result) +uninitialized_SetProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) { ReportUninitializedLexicalId(cx, id); return false; @@ -1661,8 +1661,8 @@ class DebugScopeProxy : public BaseProxyHandler } } - bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, - MutableHandleValue vp, ObjectOpResult &result) const override + bool set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, HandleValue receiver, + ObjectOpResult &result) const override { Rooted debugScope(cx, &proxy->as()); Rooted scope(cx, &proxy->as().scope()); @@ -1671,14 +1671,18 @@ class DebugScopeProxy : public BaseProxyHandler return Throw(cx, id, JSMSG_DEBUG_CANT_SET_OPT_ENV); AccessResult access; - if (!handleUnaliasedAccess(cx, debugScope, scope, id, SET, vp, &access)) + RootedValue valCopy(cx, v); + if (!handleUnaliasedAccess(cx, debugScope, scope, id, SET, &valCopy, &access)) return false; switch (access) { case ACCESS_UNALIASED: return result.succeed(); case ACCESS_GENERIC: - return SetProperty(cx, scope, scope, id, vp, result); + { + RootedValue scopeVal(cx, ObjectValue(*scope)); + return SetProperty(cx, scope, id, v, scopeVal, result); + } default: MOZ_CRASH("bad AccessResult"); } diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 919fa4638d..7516f20d35 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -371,10 +371,10 @@ js::intrinsic_UnsafePutElements(JSContext* cx, unsigned argc, Value* vp) if (IsAnyTypedArray(arrobj.get()) || arrobj->is()) { MOZ_ASSERT_IF(IsAnyTypedArray(arrobj.get()), idx < AnyTypedArrayLength(arrobj.get())); MOZ_ASSERT_IF(arrobj->is(), idx < uint32_t(arrobj->as().length())); - RootedValue tmp(cx, args[elemi]); // XXX: Always non-strict. ObjectOpResult ignored; - if (!SetElement(cx, arrobj, arrobj, idx, &tmp, ignored)) + RootedValue receiver(cx, ObjectValue(*arrobj)); + if (!SetElement(cx, arrobj, idx, args[elemi], receiver, ignored)) return false; } else { MOZ_ASSERT(idx < arrobj->as().getDenseInitializedLength()); diff --git a/js/src/vm/Shape-inl.h b/js/src/vm/Shape-inl.h index dad6d41501..c24048f76a 100644 --- a/js/src/vm/Shape-inl.h +++ b/js/src/vm/Shape-inl.h @@ -37,30 +37,6 @@ Shape::search(ExclusiveContext* cx, jsid id) return search(cx, this, id, &_); } -inline bool -Shape::set(JSContext* cx, HandleNativeObject obj, HandleObject receiver, MutableHandleValue vp, - ObjectOpResult &result) -{ - MOZ_ASSERT_IF(hasDefaultSetter(), hasGetterValue()); - MOZ_ASSERT(!obj->is()); // See bug 1128681. - - if (attrs & JSPROP_SETTER) { - Value fval = setterValue(); - if (!InvokeGetterOrSetter(cx, receiver, fval, 1, vp.address(), vp)) - return false; - return result.succeed(); - } - - if (attrs & JSPROP_GETTER) - return result.fail(JSMSG_GETTER_ONLY); - - if (!setterOp()) - return result.succeed(); - - RootedId id(cx, propid()); - return CallJSSetterOp(cx, setterOp(), obj, id, vp, result); -} - /* static */ inline Shape * Shape::search(ExclusiveContext *cx, Shape *start, jsid id, ShapeTable::Entry **pentry, bool adding) { @@ -156,15 +132,15 @@ EmptyShape::ensureInitialCustomShape(ExclusiveContext* cx, Handlecompartment() == cx->atomsCompartment()); MOZ_ASSERT(cx->atomsCompartment()->runtimeFromAnyThread()->currentThreadHasExclusiveAccess()); // Following js::AtomizeString, we grudgingly forgo last-ditch GC here. - Symbol *p = Allocate(cx); + Symbol* p = Allocate(cx); if (!p) { ReportOutOfMemory(cx); return nullptr; @@ -34,8 +34,8 @@ Symbol::newInternal(ExclusiveContext *cx, JS::SymbolCode code, JSAtom *descripti return new (p) Symbol(code, description); } -Symbol * -Symbol::new_(ExclusiveContext *cx, JS::SymbolCode code, JSString *description) +Symbol* +Symbol::new_(ExclusiveContext* cx, JS::SymbolCode code, JSString* description) { RootedAtom atom(cx); if (description) { @@ -51,22 +51,22 @@ Symbol::new_(ExclusiveContext *cx, JS::SymbolCode code, JSString *description) return newInternal(cx, code, atom); } -Symbol * -Symbol::for_(js::ExclusiveContext *cx, HandleString description) +Symbol* +Symbol::for_(js::ExclusiveContext* cx, HandleString description) { - JSAtom *atom = AtomizeString(cx, description); + JSAtom* atom = AtomizeString(cx, description); if (!atom) return nullptr; AutoLockForExclusiveAccess lock(cx); - SymbolRegistry ®istry = cx->symbolRegistry(); + SymbolRegistry& registry = cx->symbolRegistry(); SymbolRegistry::AddPtr p = registry.lookupForAdd(atom); if (p) return *p; AutoCompartment ac(cx, cx->atomsCompartment()); - Symbol *sym = newInternal(cx, SymbolCode::InSymbolRegistry, atom); + Symbol* sym = newInternal(cx, SymbolCode::InSymbolRegistry, atom); if (!sym) return nullptr; @@ -82,7 +82,7 @@ Symbol::for_(js::ExclusiveContext *cx, HandleString description) #ifdef DEBUG void -Symbol::dump(FILE *fp) +Symbol::dump(FILE* fp) { if (isWellKnownSymbol()) { // All the well-known symbol names are ASCII. diff --git a/js/src/vm/UnboxedObject.cpp b/js/src/vm/UnboxedObject.cpp index 65e8d467e5..83afc35f13 100644 --- a/js/src/vm/UnboxedObject.cpp +++ b/js/src/vm/UnboxedObject.cpp @@ -100,12 +100,12 @@ UnboxedLayout::makeConstructorCode(JSContext *cx, HandleObjectGroup group) MOZ_ASSERT(propertiesReg.volatile_()); MOZ_ASSERT(newKindReg.volatile_()); - GeneralRegisterSet regs(GeneralRegisterSet::All()); + AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); regs.take(propertiesReg); regs.take(newKindReg); Register object = regs.takeAny(), scratch1 = regs.takeAny(), scratch2 = regs.takeAny(); - GeneralRegisterSet savedNonVolatileRegisters = SavedNonVolatileRegisters(regs); + LiveGeneralRegisterSet savedNonVolatileRegisters = SavedNonVolatileRegisters(regs); for (GeneralRegisterForwardIterator iter(savedNonVolatileRegisters); iter.more(); ++iter) masm.Push(*iter); @@ -698,7 +698,7 @@ UnboxedPlainObject::obj_defineProperty(JSContext *cx, HandleObject obj, HandleId return false; return DefineProperty(cx, obj, id, desc, result) && - result.checkStrict(cx, obj, id); +result.checkStrict(cx, obj, id); } // Define the property on the expando object. @@ -758,36 +758,38 @@ UnboxedPlainObject::obj_getProperty(JSContext *cx, HandleObject obj, HandleObjec } /* static */ bool -UnboxedPlainObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleObject receiver, - HandleId id, MutableHandleValue vp, ObjectOpResult &result) +UnboxedPlainObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) { const UnboxedLayout &layout = obj->as().layout(); if (const UnboxedLayout::Property *property = layout.lookup(id)) { - if (obj == receiver) { - if (obj->as().setValue(cx, *property, vp)) + if (receiver.isObject() && obj == &receiver.toObject()) { + if (obj->as().setValue(cx, *property, v)) return result.succeed(); if (!convertToNative(cx, obj)) return false; - return SetProperty(cx, obj, receiver, id, vp, result); + return SetProperty(cx, obj, id, v, receiver, result); } - return SetPropertyByDefining(cx, obj, receiver, id, vp, false, result); + return SetPropertyByDefining(cx, obj, id, v, receiver, false, result); } if (UnboxedExpandoObject *expando = obj->as().maybeExpando()) { if (expando->containsShapeOrElement(cx, id)) { // Update property types on the unboxed object as well. - AddTypePropertyId(cx, obj, id, vp); + AddTypePropertyId(cx, obj, id, v); RootedObject nexpando(cx, expando); - RootedObject nreceiver(cx, (obj == receiver) ? expando : receiver.get()); - return SetProperty(cx, nexpando, nreceiver, id, vp, result); + RootedValue nreceiver(cx, (receiver.isObject() && obj == &receiver.toObject()) + ? ObjectValue(*expando) + : receiver); +return SetProperty(cx, nexpando, id, v, nreceiver, result); } } - return SetPropertyOnProto(cx, obj, receiver, id, vp, result); + return SetPropertyOnProto(cx, obj, id, v, receiver, result); } /* static */ bool diff --git a/js/src/vm/UnboxedObject.h b/js/src/vm/UnboxedObject.h index cdc9adcb4d..6d3507109a 100644 --- a/js/src/vm/UnboxedObject.h +++ b/js/src/vm/UnboxedObject.h @@ -201,8 +201,8 @@ class UnboxedPlainObject : public JSObject static bool obj_getProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id, MutableHandleValue vp); - static bool obj_setProperty(JSContext *cx, HandleObject obj, HandleObject receiver, - HandleId id, MutableHandleValue vp, ObjectOpResult &result); + static bool obj_setProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result); static bool obj_getOwnPropertyDescriptor(JSContext* cx, HandleObject obj, HandleId id, MutableHandle desc); diff --git a/js/src/vm/Xdr.h b/js/src/vm/Xdr.h index 8e72e88ed7..3ea4e07a47 100644 --- a/js/src/vm/Xdr.h +++ b/js/src/vm/Xdr.h @@ -29,11 +29,11 @@ namespace js { * * https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode */ -static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 260; +static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 267; static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND); -static_assert(JSErr_Limit == 386, +static_assert(JSErr_Limit == 387, "GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or " "removed MSG_DEFs from js.msg, you should increment " "XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's " diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index 338ebbe60a..002f3f35cc 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -737,12 +737,12 @@ xpc::SandboxProxyHandler::get(JSContext* cx, JS::Handle proxy, bool xpc::SandboxProxyHandler::set(JSContext *cx, JS::Handle proxy, - JS::Handle receiver, JS::Handle id, - JS::MutableHandle vp, + JS::Handle v, + JS::Handle receiver, JS::ObjectOpResult &result) const { - return BaseProxyHandler::set(cx, proxy, receiver, id, vp, result); + return BaseProxyHandler::set(cx, proxy, id, v, receiver, result); } bool diff --git a/js/xpconnect/wrappers/AddonWrapper.cpp b/js/xpconnect/wrappers/AddonWrapper.cpp index b591a06ae2..96a37fdc41 100644 --- a/js/xpconnect/wrappers/AddonWrapper.cpp +++ b/js/xpconnect/wrappers/AddonWrapper.cpp @@ -119,24 +119,24 @@ AddonWrapper::get(JSContext* cx, JS::Handle wrapper, JS::Handle template bool -AddonWrapper::set(JSContext *cx, JS::HandleObject wrapper, JS::HandleObject receiver, - JS::HandleId id, JS::MutableHandleValue vp, - JS::ObjectOpResult &result) const +AddonWrapper::set(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id, JS::HandleValue v, + JS::HandleValue receiver, JS::ObjectOpResult &result) const { Rooted desc(cx); if (!Interpose(cx, wrapper, nullptr, id, &desc)) return false; if (!desc.object()) - return Base::set(cx, wrapper, receiver, id, vp, result); + return Base::set(cx, wrapper, id, v, receiver, result); if (desc.setter()) { MOZ_ASSERT(desc.hasSetterObject()); JS::AutoValueVector args(cx); - if (!args.append(vp)) + if (!args.append(v)) return false; RootedValue fval(cx, ObjectValue(*desc.setterObject())); - if (!JS_CallFunctionValue(cx, receiver, fval, args, vp)) + RootedValue ignored(cx); + if (!JS::Call(cx, receiver, fval, args, &ignored)) return false; return result.succeed(); } diff --git a/js/xpconnect/wrappers/AddonWrapper.h b/js/xpconnect/wrappers/AddonWrapper.h index 3fa88c8e4e..d02725a33a 100644 --- a/js/xpconnect/wrappers/AddonWrapper.h +++ b/js/xpconnect/wrappers/AddonWrapper.h @@ -34,9 +34,8 @@ class AddonWrapper : public Base { JS::ObjectOpResult &result) const override; virtual bool get(JSContext *cx, JS::Handle wrapper, JS::Handle receiver, JS::Handle id, JS::MutableHandle vp) const override; - virtual bool set(JSContext *cx, JS::HandleObject wrapper, JS::HandleObject receiver, - JS::HandleId id, JS::MutableHandleValue vp, - JS::ObjectOpResult &result) const override; + virtual bool set(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id, JS::HandleValue v, + JS::HandleValue receiver, JS::ObjectOpResult &result) const override; virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle wrapper, JS::Handle id, diff --git a/js/xpconnect/wrappers/ChromeObjectWrapper.cpp b/js/xpconnect/wrappers/ChromeObjectWrapper.cpp index 2bae4261ea..2729a568c0 100644 --- a/js/xpconnect/wrappers/ChromeObjectWrapper.cpp +++ b/js/xpconnect/wrappers/ChromeObjectWrapper.cpp @@ -30,13 +30,12 @@ ChromeObjectWrapper::defineProperty(JSContext* cx, HandleObject wrapper, } bool -ChromeObjectWrapper::set(JSContext *cx, HandleObject wrapper, - HandleObject receiver, HandleId id, - MutableHandleValue vp, ObjectOpResult &result) const +ChromeObjectWrapper::set(JSContext* cx, HandleObject wrapper, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult& result) const { - if (!AccessCheck::checkPassToPrivilegedCode(cx, wrapper, vp)) + if (!AccessCheck::checkPassToPrivilegedCode(cx, wrapper, v)) return false; - return ChromeObjectWrapperBase::set(cx, wrapper, receiver, id, vp, result); + return ChromeObjectWrapperBase::set(cx, wrapper, id, v, receiver, result); } } // namespace xpc diff --git a/js/xpconnect/wrappers/ChromeObjectWrapper.h b/js/xpconnect/wrappers/ChromeObjectWrapper.h index 16f0d29f2c..80d6e7d62f 100644 --- a/js/xpconnect/wrappers/ChromeObjectWrapper.h +++ b/js/xpconnect/wrappers/ChromeObjectWrapper.h @@ -31,9 +31,8 @@ class ChromeObjectWrapper : public ChromeObjectWrapperBase JS::Handle id, JS::Handle desc, JS::ObjectOpResult &result) const override; - virtual bool set(JSContext *cx, JS::Handle wrapper, - JS::Handle receiver, JS::Handle id, - JS::MutableHandle vp, + virtual bool set(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id, + JS::HandleValue v, JS::HandleValue receiver, JS::ObjectOpResult &result) const override; static const ChromeObjectWrapper singleton; diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp index 0c875971fe..1c3fa49f5f 100644 --- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -2090,15 +2090,15 @@ XrayWrapper::get(JSContext *cx, HandleObject wrapper, template bool -XrayWrapper::set(JSContext *cx, HandleObject wrapper, - HandleObject receiver, HandleId id, - MutableHandleValue vp, ObjectOpResult &result) const +XrayWrapper::set(JSContext *cx, HandleObject wrapper, HandleId id, HandleValue v, + HandleValue receiver, ObjectOpResult &result) const { MOZ_ASSERT(!Traits::HasPrototype); // Skip our Base if it isn't already BaseProxyHandler. // NB: None of the functions we call are prepared for the receiver not // being the wrapper, so ignore the receiver here. - return js::BaseProxyHandler::set(cx, wrapper, wrapper, id, vp, result); + RootedValue wrapperValue(cx, ObjectValue(*wrapper)); + return js::BaseProxyHandler::set(cx, wrapper, id, v, wrapperValue, result); } template diff --git a/js/xpconnect/wrappers/XrayWrapper.h b/js/xpconnect/wrappers/XrayWrapper.h index 6c93039195..094949ea8d 100644 --- a/js/xpconnect/wrappers/XrayWrapper.h +++ b/js/xpconnect/wrappers/XrayWrapper.h @@ -261,7 +261,7 @@ public: return false; } - bool getPrototype(JSContext *cx, JS::HandleObject wrapper, + bool getPrototype(JSContext* cx, JS::HandleObject wrapper, JS::HandleObject target, JS::MutableHandleObject protop) { @@ -441,8 +441,8 @@ class XrayWrapper : public Base { bool *bp) const override; virtual bool get(JSContext *cx, JS::Handle wrapper, JS::Handle receiver, JS::Handle id, JS::MutableHandle vp) const override; - virtual bool set(JSContext *cx, JS::Handle wrapper, JS::Handle receiver, - JS::Handle id, JS::MutableHandle vp, + virtual bool set(JSContext *cx, JS::Handle wrapper, JS::Handle id, + JS::Handle v, JS::Handle receiver, JS::ObjectOpResult &result) const override; virtual bool call(JSContext *cx, JS::Handle wrapper, const JS::CallArgs& args) const override; @@ -467,19 +467,19 @@ class XrayWrapper : public Base { private: template typename mozilla::EnableIf::Type - getPrototypeHelper(JSContext *cx, JS::HandleObject wrapper, + getPrototypeHelper(JSContext* cx, JS::HandleObject wrapper, JS::HandleObject target, JS::MutableHandleObject protop) const { return Traits::singleton.getPrototype(cx, wrapper, target, protop); } template typename mozilla::EnableIf::Type - getPrototypeHelper(JSContext *cx, JS::HandleObject wrapper, + getPrototypeHelper(JSContext* cx, JS::HandleObject wrapper, JS::HandleObject target, JS::MutableHandleObject protop) const { return Base::getPrototype(cx, wrapper, protop); } - bool getPrototypeHelper(JSContext *cx, JS::HandleObject wrapper, + bool getPrototypeHelper(JSContext* cx, JS::HandleObject wrapper, JS::HandleObject target, JS::MutableHandleObject protop) const { return getPrototypeHelper(cx, wrapper, target, @@ -515,8 +515,8 @@ public: bool* bp) const override; virtual bool get(JSContext* cx, JS::Handle proxy, JS::Handle receiver, JS::Handle id, JS::MutableHandle vp) const override; - virtual bool set(JSContext *cx, JS::Handle proxy, JS::Handle receiver, - JS::Handle id, JS::MutableHandle vp, + virtual bool set(JSContext *cx, JS::Handle proxy, JS::Handle id, + JS::Handle v, JS::Handle receiver, JS::ObjectOpResult &result) const override; virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle proxy, diff --git a/mfbt/Attributes.h b/mfbt/Attributes.h index 68f4301cab..735deca57c 100644 --- a/mfbt/Attributes.h +++ b/mfbt/Attributes.h @@ -89,10 +89,11 @@ # endif #elif defined(__GNUC__) # if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L -# if MOZ_GCC_VERSION_AT_LEAST(4, 6, 0) -# define MOZ_HAVE_CXX11_CONSTEXPR +# define MOZ_HAVE_CXX11_CONSTEXPR +# if MOZ_GCC_VERSION_AT_LEAST(4, 8, 0) +# define MOZ_HAVE_CXX11_CONSTEXPR_IN_TEMPLATES # endif -# define MOZ_HAVE_EXPLICIT_CONVERSION +# define MOZ_HAVE_EXPLICIT_CONVERSION # endif # define MOZ_HAVE_NEVER_INLINE __attribute__((noinline)) # define MOZ_HAVE_NORETURN __attribute__((noreturn)) @@ -121,9 +122,15 @@ #ifdef MOZ_HAVE_CXX11_CONSTEXPR # define MOZ_CONSTEXPR constexpr # define MOZ_CONSTEXPR_VAR constexpr +# ifdef MOZ_HAVE_CXX11_CONSTEXPR_IN_TEMPLATES +# define MOZ_CONSTEXPR_TMPL constexpr +# else +# define MOZ_CONSTEXPR_TMPL +# endif #else # define MOZ_CONSTEXPR /* no support */ # define MOZ_CONSTEXPR_VAR const +# define MOZ_CONSTEXPR_TMPL #endif /*