mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-29 11:57:32 +09:00
Optimize argument handling in array and math functions by caching argument counts
This commit is contained in:
parent
bd8939adb7
commit
def0f21065
4 changed files with 48 additions and 27 deletions
|
|
@ -2083,6 +2083,7 @@ js::array_push(JSContext* cx, unsigned argc, Value* vp)
|
|||
{
|
||||
AutoSPSEntry pseudoFrame(cx->runtime(), "Array.prototype.push");
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
const unsigned argCount = args.length();
|
||||
|
||||
/* Step 1. */
|
||||
RootedObject obj(cx, ToObject(cx, args.thisv()));
|
||||
|
|
@ -2097,12 +2098,12 @@ js::array_push(JSContext* cx, unsigned argc, Value* vp)
|
|||
if (!ObjectMayHaveExtraIndexedProperties(obj)) {
|
||||
DenseElementResult result =
|
||||
SetOrExtendAnyBoxedOrUnboxedDenseElements(cx, obj, length,
|
||||
args.array(), args.length());
|
||||
args.array(), argCount);
|
||||
if (result != DenseElementResult::Incomplete) {
|
||||
if (result == DenseElementResult::Failure)
|
||||
return false;
|
||||
|
||||
uint32_t newlength = length + args.length();
|
||||
uint32_t newlength = length + argCount;
|
||||
args.rval().setNumber(newlength);
|
||||
|
||||
// SetOrExtendAnyBoxedOrUnboxedDenseElements takes care of updating the
|
||||
|
|
@ -2120,11 +2121,11 @@ js::array_push(JSContext* cx, unsigned argc, Value* vp)
|
|||
}
|
||||
|
||||
/* Steps 4-5. */
|
||||
if (!InitArrayElements(cx, obj, length, args.length(), args.array()))
|
||||
if (!InitArrayElements(cx, obj, length, argCount, args.array()))
|
||||
return false;
|
||||
|
||||
/* Steps 6-7. */
|
||||
double newlength = length + double(args.length());
|
||||
double newlength = length + double(argCount);
|
||||
args.rval().setNumber(newlength);
|
||||
return SetLengthProperty(cx, obj, newlength);
|
||||
}
|
||||
|
|
@ -2482,6 +2483,8 @@ array_splice_impl(JSContext* cx, unsigned argc, Value* vp, bool returnValueIsUse
|
|||
if (!GetLengthProperty(cx, obj, &len))
|
||||
return false;
|
||||
|
||||
const unsigned argCount = args.length();
|
||||
|
||||
/* Step 3. */
|
||||
double relativeStart;
|
||||
if (!ToInteger(cx, args.get(0), &relativeStart))
|
||||
|
|
@ -2496,10 +2499,10 @@ array_splice_impl(JSContext* cx, unsigned argc, Value* vp, bool returnValueIsUse
|
|||
|
||||
/* Step 5. */
|
||||
uint32_t actualDeleteCount;
|
||||
if (args.length() == 0) {
|
||||
if (argCount == 0) {
|
||||
/* Step 5.b. */
|
||||
actualDeleteCount = 0;
|
||||
} else if (args.length() == 1) {
|
||||
} else if (argCount == 1) {
|
||||
/* Step 6.b. */
|
||||
actualDeleteCount = len - actualStart;
|
||||
} else {
|
||||
|
|
@ -2554,7 +2557,7 @@ array_splice_impl(JSContext* cx, unsigned argc, Value* vp, bool returnValueIsUse
|
|||
}
|
||||
|
||||
/* Step 14. */
|
||||
uint32_t itemCount = (args.length() >= 2) ? (args.length() - 2) : 0;
|
||||
uint32_t itemCount = (argCount >= 2) ? (argCount - 2) : 0;
|
||||
|
||||
if (itemCount < actualDeleteCount) {
|
||||
/* Step 15: the array is being shrunk. */
|
||||
|
|
@ -2945,6 +2948,7 @@ js::array_slice(JSContext* cx, unsigned argc, Value* vp)
|
|||
{
|
||||
AutoSPSEntry pseudoFrame(cx->runtime(), "Array.prototype.slice");
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
const unsigned argCount = args.length();
|
||||
|
||||
/* Step 1. */
|
||||
RootedObject obj(cx, ToObject(cx, args.thisv()));
|
||||
|
|
@ -2958,7 +2962,7 @@ js::array_slice(JSContext* cx, unsigned argc, Value* vp)
|
|||
|
||||
uint32_t k = 0;
|
||||
uint32_t final = length;
|
||||
if (args.length() > 0) {
|
||||
if (argCount > 0) {
|
||||
double d;
|
||||
/* Step 3. */
|
||||
if (!ToInteger(cx, args[0], &d))
|
||||
|
|
@ -3100,7 +3104,8 @@ array_isArray(JSContext* cx, unsigned argc, Value* vp)
|
|||
static bool
|
||||
ArrayFromCallArgs(JSContext* cx, CallArgs& args, HandleObject proto = nullptr)
|
||||
{
|
||||
JSObject* obj = NewCopiedArrayForCallingAllocationSite(cx, args.array(), args.length(), proto);
|
||||
const unsigned argCount = args.length();
|
||||
JSObject* obj = NewCopiedArrayForCallingAllocationSite(cx, args.array(), argCount, proto);
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
|
|
@ -3112,6 +3117,7 @@ static bool
|
|||
array_of(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
const unsigned argCount = args.length();
|
||||
|
||||
if (IsArrayConstructor(args.thisv()) || !IsConstructor(args.thisv())) {
|
||||
// IsArrayConstructor(this) will usually be true in practice. This is
|
||||
|
|
@ -3124,20 +3130,20 @@ array_of(JSContext* cx, unsigned argc, Value* vp)
|
|||
{
|
||||
FixedConstructArgs<1> cargs(cx);
|
||||
|
||||
cargs[0].setNumber(args.length());
|
||||
cargs[0].setNumber(argCount);
|
||||
|
||||
if (!Construct(cx, args.thisv(), cargs, args.thisv(), &obj))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 8.
|
||||
for (unsigned k = 0; k < args.length(); k++) {
|
||||
for (unsigned k = 0; k < argCount; k++) {
|
||||
if (!DefineElement(cx, obj, k, args[k]))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Steps 9-10.
|
||||
if (!SetLengthProperty(cx, obj, args.length()))
|
||||
if (!SetLengthProperty(cx, obj, argCount))
|
||||
return false;
|
||||
|
||||
// Step 11.
|
||||
|
|
@ -3249,6 +3255,8 @@ const JSPropertySpec array_static_props[] = {
|
|||
static inline bool
|
||||
ArrayConstructorImpl(JSContext* cx, CallArgs& args, bool isConstructor)
|
||||
{
|
||||
const unsigned argCount = args.length();
|
||||
|
||||
RootedObject proto(cx);
|
||||
if (isConstructor) {
|
||||
if (!GetPrototypeFromCallableConstructor(cx, args, &proto))
|
||||
|
|
@ -3261,7 +3269,7 @@ ArrayConstructorImpl(JSContext* cx, CallArgs& args, bool isConstructor)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (args.length() != 1 || !args[0].isNumber())
|
||||
if (argCount != 1 || !args[0].isNumber())
|
||||
return ArrayFromCallArgs(cx, args, proto);
|
||||
|
||||
uint32_t length;
|
||||
|
|
@ -3301,8 +3309,9 @@ bool
|
|||
js::array_construct(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
const unsigned argCount = args.length();
|
||||
MOZ_ASSERT(!args.isConstructing());
|
||||
MOZ_ASSERT(args.length() == 1);
|
||||
MOZ_ASSERT(argCount == 1);
|
||||
MOZ_ASSERT(args[0].isNumber());
|
||||
return ArrayConstructorImpl(cx, args, /* isConstructor = */ false);
|
||||
}
|
||||
|
|
@ -3818,9 +3827,10 @@ bool
|
|||
js::ArrayInfo(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
const unsigned argCount = args.length();
|
||||
RootedObject obj(cx);
|
||||
|
||||
for (unsigned i = 0; i < args.length(); i++) {
|
||||
for (unsigned i = 0; i < argCount; i++) {
|
||||
HandleValue arg = args[i];
|
||||
|
||||
UniqueChars bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, arg, nullptr);
|
||||
|
|
|
|||
|
|
@ -566,9 +566,10 @@ bool
|
|||
js::math_max(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
const unsigned argCount = args.length();
|
||||
|
||||
double maxval = NegativeInfinity<double>();
|
||||
for (unsigned i = 0; i < args.length(); i++) {
|
||||
for (unsigned i = 0; i < argCount; i++) {
|
||||
double x;
|
||||
if (!ToNumber(cx, args[i], &x))
|
||||
return false;
|
||||
|
|
@ -591,9 +592,10 @@ bool
|
|||
js::math_min(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
const unsigned argCount = args.length();
|
||||
|
||||
double minval = PositiveInfinity<double>();
|
||||
for (unsigned i = 0; i < args.length(); i++) {
|
||||
for (unsigned i = 0; i < argCount; i++) {
|
||||
double x;
|
||||
if (!ToNumber(cx, args[i], &x))
|
||||
return false;
|
||||
|
|
@ -1263,9 +1265,11 @@ js::math_hypot(JSContext* cx, unsigned argc, Value* vp)
|
|||
bool
|
||||
js::math_hypot_handle(JSContext* cx, HandleValueArray args, MutableHandleValue res)
|
||||
{
|
||||
const unsigned argCount = args.length();
|
||||
|
||||
// IonMonkey calls the system hypot function directly if two arguments are
|
||||
// given. Do that here as well to get the same results.
|
||||
if (args.length() == 2) {
|
||||
if (argCount == 2) {
|
||||
double x, y;
|
||||
if (!ToNumber(cx, args[0], &x))
|
||||
return false;
|
||||
|
|
@ -1283,7 +1287,7 @@ js::math_hypot_handle(JSContext* cx, HandleValueArray args, MutableHandleValue r
|
|||
double scale = 0;
|
||||
double sumsq = 1;
|
||||
|
||||
for (unsigned i = 0; i < args.length(); i++) {
|
||||
for (unsigned i = 0; i < argCount; i++) {
|
||||
double x;
|
||||
if (!ToNumber(cx, args[i], &x))
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -527,7 +527,8 @@ js::SetIntegrityLevel(JSContext* cx, HandleObject obj, IntegrityLevel level)
|
|||
const unsigned AllowConfigureAndWritable = AllowConfigure & ~JSPROP_IGNORE_READONLY;
|
||||
|
||||
// 8.a/9.a. The two different loops are merged here.
|
||||
for (size_t i = 0; i < keys.length(); i++) {
|
||||
const size_t keyCount = keys.length();
|
||||
for (size_t i = 0; i < keyCount; i++) {
|
||||
id = keys[i];
|
||||
|
||||
if (level == IntegrityLevel::Sealed) {
|
||||
|
|
@ -1062,7 +1063,8 @@ JS_CopyPropertiesFrom(JSContext* cx, HandleObject target, HandleObject obj)
|
|||
if (!GetPropertyKeys(cx, obj, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &props))
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < props.length(); ++i) {
|
||||
const size_t propCount = props.length();
|
||||
for (size_t i = 0; i < propCount; ++i) {
|
||||
if (!JS_CopyPropertyFrom(cx, props[i], target, obj))
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1158,6 +1160,7 @@ GetScriptPlainObjectProperties(ExclusiveContext* cx, HandleObject obj,
|
|||
{
|
||||
if (obj->is<PlainObject>()) {
|
||||
PlainObject* nobj = &obj->as<PlainObject>();
|
||||
const size_t initLength = nobj->getDenseInitializedLength();
|
||||
|
||||
if (!properties.appendN(IdValuePair(), nobj->slotSpan()))
|
||||
return false;
|
||||
|
|
@ -1170,7 +1173,7 @@ GetScriptPlainObjectProperties(ExclusiveContext* cx, HandleObject obj,
|
|||
properties[slot].get().value = nobj->getSlot(slot);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < nobj->getDenseInitializedLength(); i++) {
|
||||
for (size_t i = 0; i < initLength; i++) {
|
||||
Value v = nobj->getDenseElement(i);
|
||||
if (!v.isMagic(JS_ELEMENTS_HOLE) && !properties.append(IdValuePair(INT_TO_JSID(i), v)))
|
||||
return false;
|
||||
|
|
@ -1183,11 +1186,13 @@ GetScriptPlainObjectProperties(ExclusiveContext* cx, HandleObject obj,
|
|||
UnboxedPlainObject* nobj = &obj->as<UnboxedPlainObject>();
|
||||
|
||||
const UnboxedLayout& layout = nobj->layout();
|
||||
if (!properties.appendN(IdValuePair(), layout.properties().length()))
|
||||
const auto& layoutProperties = layout.properties();
|
||||
const size_t layoutPropertyCount = layoutProperties.length();
|
||||
if (!properties.appendN(IdValuePair(), layoutPropertyCount))
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < layout.properties().length(); i++) {
|
||||
const UnboxedLayout::Property& property = layout.properties()[i];
|
||||
for (size_t i = 0; i < layoutPropertyCount; i++) {
|
||||
const UnboxedLayout::Property& property = layoutProperties[i];
|
||||
properties[i].get().id = NameToId(property.name);
|
||||
properties[i].get().value = nobj->getValue(property);
|
||||
}
|
||||
|
|
@ -1244,7 +1249,8 @@ js::DeepCloneObjectLiteral(JSContext* cx, HandleObject obj, NewObjectKind newKin
|
|||
if (!GetScriptPlainObjectProperties(cx, obj, &properties))
|
||||
return nullptr;
|
||||
|
||||
for (size_t i = 0; i < properties.length(); i++) {
|
||||
const size_t propertyCount = properties.length();
|
||||
for (size_t i = 0; i < propertyCount; i++) {
|
||||
if (!DeepCloneValue(cx, &properties[i].get().value, newKind))
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3352,9 +3352,10 @@ bool
|
|||
js::StringConstructor(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
const unsigned argCount = args.length();
|
||||
|
||||
RootedString str(cx);
|
||||
if (args.length() > 0) {
|
||||
if (argCount > 0) {
|
||||
if (!args.isConstructing() && args[0].isSymbol())
|
||||
return js::SymbolDescriptiveString(cx, args[0].toSymbol(), args.rval());
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue