зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1688033: Add forwarded argument flag to ArgumentsObject r=jandem
Being able to test whether an ArgumentsObject has closed-over arguments by checking a flag instead of testing each argument makes future patches significantly simpler. I considered just making closed-over arguments set ELEMENT_OVERRIDDEN_BIT, but this would make ArgumentsObjectArg fail if *any* argument was closed over, even if the specific argument we are loading is not. Depends on D104483 Differential Revision: https://phabricator.services.mozilla.com/D104484
This commit is contained in:
Родитель
7159fa8127
Коммит
d5fecbb0dc
|
@ -0,0 +1,14 @@
|
||||||
|
function bar(x,y) {
|
||||||
|
return x + y;
|
||||||
|
}
|
||||||
|
|
||||||
|
function foo(x, y) {
|
||||||
|
function closeOver() { return x; }
|
||||||
|
return bar.apply({}, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
var sum = 0;
|
||||||
|
for (var i = 0; i < 100; i++) {
|
||||||
|
sum += foo(1,2);
|
||||||
|
}
|
||||||
|
assertEq(sum, 300)
|
|
@ -99,6 +99,7 @@ void ArgumentsObject::MaybeForwardToCallObject(AbstractFramePtr frame,
|
||||||
for (PositionalFormalParameterIter fi(script); fi; fi++) {
|
for (PositionalFormalParameterIter fi(script); fi; fi++) {
|
||||||
if (fi.closedOver()) {
|
if (fi.closedOver()) {
|
||||||
data->args[fi.argumentSlot()] = MagicEnvSlotValue(fi.location().slot());
|
data->args[fi.argumentSlot()] = MagicEnvSlotValue(fi.location().slot());
|
||||||
|
obj->markArgumentForwarded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,6 +118,7 @@ void ArgumentsObject::MaybeForwardToCallObject(jit::JitFrameLayout* frame,
|
||||||
for (PositionalFormalParameterIter fi(script); fi; fi++) {
|
for (PositionalFormalParameterIter fi(script); fi; fi++) {
|
||||||
if (fi.closedOver()) {
|
if (fi.closedOver()) {
|
||||||
data->args[fi.argumentSlot()] = MagicEnvSlotValue(fi.location().slot());
|
data->args[fi.argumentSlot()] = MagicEnvSlotValue(fi.location().slot());
|
||||||
|
obj->markArgumentForwarded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,7 +168,9 @@ class ArgumentsObject : public NativeObject {
|
||||||
static const uint32_t ITERATOR_OVERRIDDEN_BIT = 0x2;
|
static const uint32_t ITERATOR_OVERRIDDEN_BIT = 0x2;
|
||||||
static const uint32_t ELEMENT_OVERRIDDEN_BIT = 0x4;
|
static const uint32_t ELEMENT_OVERRIDDEN_BIT = 0x4;
|
||||||
static const uint32_t CALLEE_OVERRIDDEN_BIT = 0x8;
|
static const uint32_t CALLEE_OVERRIDDEN_BIT = 0x8;
|
||||||
static const uint32_t PACKED_BITS_COUNT = 4;
|
static const uint32_t FORWARDED_ARGUMENTS_BIT = 0x10;
|
||||||
|
static const uint32_t PACKED_BITS_COUNT = 5;
|
||||||
|
static const uint32_t PACKED_BITS_MASK = (1 << PACKED_BITS_COUNT) - 1;
|
||||||
|
|
||||||
static_assert(ARGS_LENGTH_MAX <= (UINT32_MAX >> PACKED_BITS_COUNT),
|
static_assert(ARGS_LENGTH_MAX <= (UINT32_MAX >> PACKED_BITS_COUNT),
|
||||||
"Max arguments length must fit in available bits");
|
"Max arguments length must fit in available bits");
|
||||||
|
@ -370,9 +372,21 @@ class ArgumentsObject : public NativeObject {
|
||||||
bool argIsForwarded(unsigned i) const {
|
bool argIsForwarded(unsigned i) const {
|
||||||
MOZ_ASSERT(i < data()->numArgs);
|
MOZ_ASSERT(i < data()->numArgs);
|
||||||
const Value& v = data()->args[i];
|
const Value& v = data()->args[i];
|
||||||
|
MOZ_ASSERT_IF(IsMagicScopeSlotValue(v), anyArgIsForwarded());
|
||||||
return IsMagicScopeSlotValue(v);
|
return IsMagicScopeSlotValue(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool anyArgIsForwarded() const {
|
||||||
|
const Value& v = getFixedSlot(INITIAL_LENGTH_SLOT);
|
||||||
|
return v.toInt32() & FORWARDED_ARGUMENTS_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void markArgumentForwarded() {
|
||||||
|
uint32_t v =
|
||||||
|
getFixedSlot(INITIAL_LENGTH_SLOT).toInt32() | FORWARDED_ARGUMENTS_BIT;
|
||||||
|
setFixedSlot(INITIAL_LENGTH_SLOT, Int32Value(v));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attempt to speedily and efficiently access the i-th element of this
|
* Attempt to speedily and efficiently access the i-th element of this
|
||||||
* arguments object. Return true if the element was speedily returned.
|
* arguments object. Return true if the element was speedily returned.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче