зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1850305 part 2 - Add some infallible type conversions in the transpiler. r=iain
This fixes issues caught by the assertion added in the next patch. These operations are actually infallible so didn't have the same performance cliff. Differential Revision: https://phabricator.services.mozilla.com/D187265
This commit is contained in:
Родитель
9f755e8bd8
Коммит
7831d3edd1
|
@ -0,0 +1,12 @@
|
||||||
|
function f() {
|
||||||
|
var arr = [[]];
|
||||||
|
for (var i = 1; i < 101; i++) {
|
||||||
|
arr[0].push(i);
|
||||||
|
}
|
||||||
|
var res = 0;
|
||||||
|
for (var i = 0; i < 100; i++) {
|
||||||
|
res += Math.max(...arr[0]) + Math.min(...arr[0]);
|
||||||
|
}
|
||||||
|
assertEq(res, 10100);
|
||||||
|
}
|
||||||
|
f();
|
|
@ -1695,6 +1695,7 @@ bool WarpBuilder::build_EndIter(BytecodeLocation loc) {
|
||||||
|
|
||||||
bool WarpBuilder::build_CloseIter(BytecodeLocation loc) {
|
bool WarpBuilder::build_CloseIter(BytecodeLocation loc) {
|
||||||
MDefinition* iter = current->pop();
|
MDefinition* iter = current->pop();
|
||||||
|
iter = unboxObjectInfallible(iter);
|
||||||
return buildIC(loc, CacheKind::CloseIter, {iter});
|
return buildIC(loc, CacheKind::CloseIter, {iter});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2901,6 +2902,10 @@ bool WarpBuilder::build_SpreadCall(BytecodeLocation loc) {
|
||||||
CallInfo callInfo(alloc(), constructing, loc.resultIsPopped());
|
CallInfo callInfo(alloc(), constructing, loc.resultIsPopped());
|
||||||
callInfo.initForSpreadCall(current);
|
callInfo.initForSpreadCall(current);
|
||||||
|
|
||||||
|
// The argument must be an array object.
|
||||||
|
MOZ_ASSERT(callInfo.argc() == 1);
|
||||||
|
callInfo.setArg(0, unboxObjectInfallible(callInfo.getArg(0)));
|
||||||
|
|
||||||
if (auto* cacheIRSnapshot = getOpSnapshot<WarpCacheIR>(loc)) {
|
if (auto* cacheIRSnapshot = getOpSnapshot<WarpCacheIR>(loc)) {
|
||||||
return transpileCall(loc, cacheIRSnapshot, &callInfo);
|
return transpileCall(loc, cacheIRSnapshot, &callInfo);
|
||||||
}
|
}
|
||||||
|
@ -2921,6 +2926,10 @@ bool WarpBuilder::build_SpreadNew(BytecodeLocation loc) {
|
||||||
CallInfo callInfo(alloc(), constructing, loc.resultIsPopped());
|
CallInfo callInfo(alloc(), constructing, loc.resultIsPopped());
|
||||||
callInfo.initForSpreadCall(current);
|
callInfo.initForSpreadCall(current);
|
||||||
|
|
||||||
|
// The argument must be an array object.
|
||||||
|
MOZ_ASSERT(callInfo.argc() == 1);
|
||||||
|
callInfo.setArg(0, unboxObjectInfallible(callInfo.getArg(0)));
|
||||||
|
|
||||||
if (auto* cacheIRSnapshot = getOpSnapshot<WarpCacheIR>(loc)) {
|
if (auto* cacheIRSnapshot = getOpSnapshot<WarpCacheIR>(loc)) {
|
||||||
return transpileCall(loc, cacheIRSnapshot, &callInfo);
|
return transpileCall(loc, cacheIRSnapshot, &callInfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,18 @@ void WarpBuilderShared::pushConstant(const Value& v) {
|
||||||
current->push(cst);
|
current->push(cst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MDefinition* WarpBuilderShared::unboxObjectInfallible(MDefinition* def) {
|
||||||
|
if (def->type() == MIRType::Object) {
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(def->type() == MIRType::Value);
|
||||||
|
|
||||||
|
auto* unbox = MUnbox::New(alloc(), def, MIRType::Object, MUnbox::Infallible);
|
||||||
|
current->add(unbox);
|
||||||
|
return unbox;
|
||||||
|
}
|
||||||
|
|
||||||
MCall* WarpBuilderShared::makeCall(CallInfo& callInfo, bool needsThisCheck,
|
MCall* WarpBuilderShared::makeCall(CallInfo& callInfo, bool needsThisCheck,
|
||||||
WrappedFunction* target, bool isDOMCall) {
|
WrappedFunction* target, bool isDOMCall) {
|
||||||
auto addUndefined = [this]() -> MConstant* {
|
auto addUndefined = [this]() -> MConstant* {
|
||||||
|
@ -73,9 +85,10 @@ MInstruction* WarpBuilderShared::makeSpreadCall(CallInfo& callInfo,
|
||||||
current->add(elements);
|
current->add(elements);
|
||||||
|
|
||||||
if (callInfo.constructing()) {
|
if (callInfo.constructing()) {
|
||||||
|
auto* newTarget = unboxObjectInfallible(callInfo.getNewTarget());
|
||||||
auto* construct =
|
auto* construct =
|
||||||
MConstructArray::New(alloc(), target, callInfo.callee(), elements,
|
MConstructArray::New(alloc(), target, callInfo.callee(), elements,
|
||||||
callInfo.thisArg(), callInfo.getNewTarget());
|
callInfo.thisArg(), newTarget);
|
||||||
if (isSameRealm) {
|
if (isSameRealm) {
|
||||||
construct->setNotCrossRealm();
|
construct->setNotCrossRealm();
|
||||||
}
|
}
|
||||||
|
|
|
@ -420,6 +420,8 @@ class WarpBuilderShared {
|
||||||
MConstant* constant(const JS::Value& v);
|
MConstant* constant(const JS::Value& v);
|
||||||
void pushConstant(const JS::Value& v);
|
void pushConstant(const JS::Value& v);
|
||||||
|
|
||||||
|
MDefinition* unboxObjectInfallible(MDefinition* def);
|
||||||
|
|
||||||
MCall* makeCall(CallInfo& callInfo, bool needsThisCheck,
|
MCall* makeCall(CallInfo& callInfo, bool needsThisCheck,
|
||||||
WrappedFunction* target = nullptr, bool isDOMCall = false);
|
WrappedFunction* target = nullptr, bool isDOMCall = false);
|
||||||
MInstruction* makeSpreadCall(CallInfo& callInfo, bool needsThisCheck,
|
MInstruction* makeSpreadCall(CallInfo& callInfo, bool needsThisCheck,
|
||||||
|
|
|
@ -3853,7 +3853,10 @@ bool WarpCacheIRTranspiler::emitTypedArrayByteLengthDoubleResult(
|
||||||
auto* size = MTypedArrayElementSize::New(alloc(), obj);
|
auto* size = MTypedArrayElementSize::New(alloc(), obj);
|
||||||
add(size);
|
add(size);
|
||||||
|
|
||||||
auto* mul = MMul::New(alloc(), lengthDouble, size, MIRType::Double);
|
auto* sizeDouble = MToDouble::New(alloc(), size);
|
||||||
|
add(sizeDouble);
|
||||||
|
|
||||||
|
auto* mul = MMul::New(alloc(), lengthDouble, sizeDouble, MIRType::Double);
|
||||||
mul->setCanBeNegativeZero(false);
|
mul->setCanBeNegativeZero(false);
|
||||||
add(mul);
|
add(mul);
|
||||||
|
|
||||||
|
@ -4949,7 +4952,7 @@ bool WarpCacheIRTranspiler::maybeCreateThis(MDefinition* callee,
|
||||||
MOZ_ASSERT(thisArg->type() == MIRType::MagicIsConstructing ||
|
MOZ_ASSERT(thisArg->type() == MIRType::MagicIsConstructing ||
|
||||||
thisArg->isPhi());
|
thisArg->isPhi());
|
||||||
|
|
||||||
MDefinition* newTarget = callInfo_->getNewTarget();
|
auto* newTarget = unboxObjectInfallible(callInfo_->getNewTarget());
|
||||||
auto* createThis = MCreateThis::New(alloc(), callee, newTarget);
|
auto* createThis = MCreateThis::New(alloc(), callee, newTarget);
|
||||||
add(createThis);
|
add(createThis);
|
||||||
|
|
||||||
|
@ -5310,7 +5313,8 @@ bool WarpCacheIRTranspiler::emitCallBoundScriptedFunction(
|
||||||
auto* boundArgs = MLoadFixedSlot::New(
|
auto* boundArgs = MLoadFixedSlot::New(
|
||||||
alloc(), callee, BoundFunctionObject::firstInlineBoundArgSlot());
|
alloc(), callee, BoundFunctionObject::firstInlineBoundArgSlot());
|
||||||
add(boundArgs);
|
add(boundArgs);
|
||||||
elements = MElements::New(alloc(), boundArgs);
|
auto* boundArgsObj = unboxObjectInfallible(boundArgs);
|
||||||
|
elements = MElements::New(alloc(), boundArgsObj);
|
||||||
add(elements);
|
add(elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче