mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-21 09:49:14 +00:00
Bug 1724031 - Part 3: Store JSFunction flags and arg count as a JS::Value r=jandem
In preparation for storing them in a slot, store them in a Value. The value is encoded as a private uint32 value. Differential Revision: https://phabricator.services.mozilla.com/D123083
This commit is contained in:
parent
98f8f1c73d
commit
9fca780648
@ -15,6 +15,7 @@
|
||||
|
||||
#include "js/CallArgs.h" // JSNative
|
||||
#include "js/shadow/Object.h" // JS::shadow::Object
|
||||
#include "js/Value.h" // JS::Value
|
||||
|
||||
class JS_PUBLIC_API JSFunction;
|
||||
class JSJitInfo;
|
||||
@ -25,7 +26,7 @@ namespace shadow {
|
||||
|
||||
struct Function {
|
||||
shadow::Object base;
|
||||
uint32_t flagsAndArgCount;
|
||||
JS::Value flagsAndArgCount;
|
||||
/* Used only for natives */
|
||||
JSNative native;
|
||||
const JSJitInfo* jitinfo;
|
||||
|
@ -76,7 +76,7 @@ assertEq(tByteSize([1, 2, 3, 4, 5, 6, 7]), s(112, 120));
|
||||
assertEq(tByteSize([1, 2, 3, 4, 5, 6, 7, 8]), s(112, 120));
|
||||
|
||||
// Various forms of functions.
|
||||
assertEq(tByteSize(function () {}), s(32, 56));
|
||||
assertEq(tByteSize(function () {}.bind()), s(48, 72));
|
||||
assertEq(tByteSize(() => 1), s(48, 72));
|
||||
assertEq(tByteSize(Math.sin), s(32, 56));
|
||||
assertEq(tByteSize(function () {}), s(40, 56));
|
||||
assertEq(tByteSize(function () {}.bind()), s(56, 72));
|
||||
assertEq(tByteSize(() => 1), s(56, 72));
|
||||
assertEq(tByteSize(Math.sin), s(40, 56));
|
||||
|
@ -3525,8 +3525,8 @@ void CodeGenerator::emitLambdaInit(Register output, Register envChain,
|
||||
const LambdaFunctionInfo& info) {
|
||||
uint32_t flagsAndArgs =
|
||||
info.flags.toRaw() | (info.nargs << JSFunction::ArgCountShift);
|
||||
masm.store32(Imm32(flagsAndArgs),
|
||||
Address(output, JSFunction::offsetOfFlagsAndArgCount()));
|
||||
masm.storeValue(JS::PrivateUint32Value(flagsAndArgs),
|
||||
Address(output, JSFunction::offsetOfFlagsAndArgCount()));
|
||||
masm.storePtr(ImmGCPtr(info.baseScript),
|
||||
Address(output, JSFunction::offsetOfBaseScript()));
|
||||
masm.storePtr(envChain, Address(output, JSFunction::offsetOfEnvironment()));
|
||||
|
@ -550,7 +550,8 @@ static MOZ_ALWAYS_INLINE const JSJitInfo* FUNCTION_VALUE_TO_JITINFO(
|
||||
MOZ_ASSERT(JS::GetClass(obj) == js::FunctionClassPtr);
|
||||
|
||||
auto* fun = reinterpret_cast<JS::shadow::Function*>(obj);
|
||||
MOZ_ASSERT(!(fun->flagsAndArgCount & js::JS_FUNCTION_INTERPRETED_BITS),
|
||||
MOZ_ASSERT(!(fun->flagsAndArgCount.toPrivateUint32() &
|
||||
js::JS_FUNCTION_INTERPRETED_BITS),
|
||||
"Unexpected non-native function");
|
||||
|
||||
return fun->jitinfo;
|
||||
@ -559,7 +560,8 @@ static MOZ_ALWAYS_INLINE const JSJitInfo* FUNCTION_VALUE_TO_JITINFO(
|
||||
static MOZ_ALWAYS_INLINE void SET_JITINFO(JSFunction* func,
|
||||
const JSJitInfo* info) {
|
||||
auto* fun = reinterpret_cast<JS::shadow::Function*>(func);
|
||||
MOZ_ASSERT(!(fun->flagsAndArgCount & js::JS_FUNCTION_INTERPRETED_BITS));
|
||||
MOZ_ASSERT(!(fun->flagsAndArgCount.toPrivateUint32() &
|
||||
js::JS_FUNCTION_INTERPRETED_BITS));
|
||||
fun->jitinfo = info;
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ inline JSFunction* JSFunction::create(JSContext* cx, js::gc::AllocKind kind,
|
||||
MOZ_ASSERT(shape->slotSpan() == 0);
|
||||
|
||||
JSFunction* fun = static_cast<JSFunction*>(nobj);
|
||||
fun->setArgCount(0);
|
||||
fun->initFlagsAndArgCount();
|
||||
|
||||
// This must be overwritten by some ultimate caller: there's no default
|
||||
// value to which we could sensibly initialize this.
|
||||
|
@ -53,12 +53,13 @@ class JSFunction : public js::NativeObject {
|
||||
using FunctionFlags = js::FunctionFlags;
|
||||
|
||||
/*
|
||||
* Bitfield composed of FunctionFlags and argument count.
|
||||
* Bitfield composed of FunctionFlags and argument count, stored as a
|
||||
* PrivateUint32Value.
|
||||
*
|
||||
* If any of these flags needs to be accessed in off-thread JIT compilation,
|
||||
* copy it to js::jit::WrappedFunction.
|
||||
*/
|
||||
uint32_t flagsAndArgCount_;
|
||||
js::GCPtrValue flagsAndArgCount_;
|
||||
|
||||
union U {
|
||||
class {
|
||||
@ -151,12 +152,18 @@ class JSFunction : public js::NativeObject {
|
||||
return needsFunctionEnvironmentObjects() || needsExtraBodyVarEnvironment();
|
||||
}
|
||||
|
||||
uint32_t flagsAndArgCountRaw() const { return flagsAndArgCount_; }
|
||||
uint32_t flagsAndArgCountRaw() const {
|
||||
return flagsAndArgCount_.toPrivateUint32();
|
||||
}
|
||||
|
||||
size_t nargs() const { return flagsAndArgCount_ >> ArgCountShift; }
|
||||
void initFlagsAndArgCount() {
|
||||
flagsAndArgCount_.init(JS::PrivateUint32Value(0));
|
||||
}
|
||||
|
||||
size_t nargs() const { return flagsAndArgCountRaw() >> ArgCountShift; }
|
||||
|
||||
FunctionFlags flags() const {
|
||||
return FunctionFlags(uint16_t(flagsAndArgCount_ & FlagsMask));
|
||||
return FunctionFlags(uint16_t(flagsAndArgCountRaw() & FlagsMask));
|
||||
}
|
||||
|
||||
FunctionFlags::FunctionKind kind() const { return flags().kind(); }
|
||||
@ -269,8 +276,10 @@ class JSFunction : public js::NativeObject {
|
||||
|
||||
void setFlags(FunctionFlags flags) { setFlags(flags.toRaw()); }
|
||||
void setFlags(uint16_t flags) {
|
||||
flagsAndArgCount_ &= ~FlagsMask;
|
||||
flagsAndArgCount_ |= flags;
|
||||
uint32_t flagsAndArgCount = flagsAndArgCountRaw();
|
||||
flagsAndArgCount &= ~FlagsMask;
|
||||
flagsAndArgCount |= flags;
|
||||
flagsAndArgCount_.unbarrieredSet(JS::PrivateUint32Value(flagsAndArgCount));
|
||||
}
|
||||
|
||||
// Make the function constructible.
|
||||
@ -278,8 +287,10 @@ class JSFunction : public js::NativeObject {
|
||||
|
||||
// Can be called multiple times by the parser.
|
||||
void setArgCount(uint16_t nargs) {
|
||||
flagsAndArgCount_ &= ~ArgCountMask;
|
||||
flagsAndArgCount_ |= nargs << ArgCountShift;
|
||||
uint32_t flagsAndArgCount = flagsAndArgCountRaw();
|
||||
flagsAndArgCount &= ~ArgCountMask;
|
||||
flagsAndArgCount |= nargs << ArgCountShift;
|
||||
flagsAndArgCount_.set(JS::PrivateUint32Value(flagsAndArgCount));
|
||||
}
|
||||
|
||||
void setIsBoundFunction() { setFlags(flags().setIsBoundFunction()); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user