Bug 1649398 - Known class support for MRegExp and folding for MHasClass and MIsCallable. r=jandem

Differential Revision: https://phabricator.services.mozilla.com/D81179
This commit is contained in:
Tom Schuster 2020-06-30 10:11:12 +00:00
Родитель 79b42c90a6
Коммит 52f794edec
5 изменённых файлов: 74 добавлений и 2 удалений

Просмотреть файл

@ -1,24 +1,33 @@
var IsRegExpObject = getSelfHostedValue("IsRegExpObject");
var IsCallable = getSelfHostedValue("IsCallable");
function array() {
var a = [0];
assertEq(Array.isArray(a), true);
assertEq(typeof a, "object");
assertEq(IsRegExpObject(a), false);
assertEq(IsCallable(a), false);
}
function array2(x) {
var a;
if (x) {
a = [0]
a = [0];
} else {
a = [1];
}
assertEq(Array.isArray(a), true);
assertEq(typeof a, "object");
assertEq(IsRegExpObject(a), false);
assertEq(IsCallable(a), false);
}
function object() {
var o = {a: 1};
assertEq(Array.isArray(o), false);
assertEq(typeof o, "object");
assertEq(IsRegExpObject(o), false);
assertEq(IsCallable(o), false);
}
function object2(x) {
@ -30,6 +39,8 @@ function object2(x) {
}
assertEq(Array.isArray(o), false);
assertEq(typeof o, "object");
assertEq(IsRegExpObject(o), false);
assertEq(IsCallable(o), false);
}
function mixed(x) {
@ -41,20 +52,46 @@ function mixed(x) {
}
assertEq(Array.isArray(o), x);
assertEq(typeof o, "object");
assertEq(IsRegExpObject(o), false);
assertEq(IsCallable(o), false);
}
function lambda() {
function f() {}
assertEq(Array.isArray(f), false);
assertEq(typeof f, "function");
assertEq(IsRegExpObject(f), false);
assertEq(IsCallable(f), true);
}
function arrow() {
var f = () => {};
assertEq(Array.isArray(f), false);
assertEq(typeof f, "function");
assertEq(IsRegExpObject(f), false);
assertEq(IsCallable(f), true);
}
function regexp() {
var r = /a/;
assertEq(Array.isArray(r), false);
assertEq(typeof r, "object");
assertEq(IsRegExpObject(r), true);
assertEq(IsCallable(r), false);
}
function regexp2(x) {
var a;
if (x) {
a = /a/;
} else {
a = /b/;
}
assertEq(Array.isArray(a), false);
assertEq(typeof a, "object");
assertEq(IsRegExpObject(a), true);
assertEq(IsCallable(a), false);
}
var b = true;
for (var i = 0; i < 1e4; i++) {
@ -65,6 +102,8 @@ for (var i = 0; i < 1e4; i++) {
mixed(b);
lambda();
arrow();
regexp()
regexp2(b);
b = !b;
}

Просмотреть файл

@ -5097,6 +5097,9 @@ KnownClass jit::GetObjectKnownClass(const MDefinition* def) {
case MDefinition::Opcode::FunctionWithProto:
return KnownClass::Function;
case MDefinition::Opcode::RegExp:
return KnownClass::RegExp;
case MDefinition::Opcode::Phi: {
if (def->numOperands() == 0) {
return KnownClass::None;
@ -5138,6 +5141,8 @@ const JSClass* jit::GetObjectKnownJSClass(const MDefinition* def) {
return &ArrayObject::class_;
case KnownClass::Function:
return &JSFunction::class_;
case KnownClass::RegExp:
return &RegExpObject::class_;
case KnownClass::None:
break;
}

Просмотреть файл

@ -174,7 +174,7 @@ bool DeadIfUnused(const MDefinition* def);
bool IsDiscardable(const MDefinition* def);
enum class KnownClass { PlainObject, Array, Function, None };
enum class KnownClass { PlainObject, Array, Function, RegExp, None };
KnownClass GetObjectKnownClass(const MDefinition* def);
const JSClass* GetObjectKnownJSClass(const MDefinition* def);

Просмотреть файл

@ -3587,6 +3587,7 @@ MDefinition* MTypeOf::foldsTo(TempAllocator& alloc) {
switch (known) {
case KnownClass::Array:
case KnownClass::PlainObject:
case KnownClass::RegExp:
type = JSTYPE_OBJECT;
break;
case KnownClass::Function:
@ -5908,6 +5909,30 @@ MDefinition* MGuardToClass::foldsTo(TempAllocator& alloc) {
return object();
}
MDefinition* MHasClass::foldsTo(TempAllocator& alloc) {
const JSClass* clasp = GetObjectKnownJSClass(object());
if (!clasp) {
return this;
}
AssertKnownClass(alloc, this, object());
return MConstant::New(alloc, BooleanValue(getClass() == clasp));
}
MDefinition* MIsCallable::foldsTo(TempAllocator& alloc) {
if (input()->type() != MIRType::Object) {
return this;
}
KnownClass known = GetObjectKnownClass(input());
if (known == KnownClass::None) {
return this;
}
AssertKnownClass(alloc, this, input());
return MConstant::New(alloc, BooleanValue(known == KnownClass::Function));
}
MDefinition* MIsArray::foldsTo(TempAllocator& alloc) {
if (input()->type() != MIRType::Object) {
return this;

Просмотреть файл

@ -10776,6 +10776,7 @@ class MIsCallable : public MUnaryInstruction,
TRIVIAL_NEW_WRAPPERS
NAMED_OPERANDS((0, object))
MDefinition* foldsTo(TempAllocator& alloc) override;
AliasSet getAliasSet() const override { return AliasSet::None(); }
};
@ -10853,6 +10854,8 @@ class MHasClass : public MUnaryInstruction, public SingleObjectPolicy::Data {
NAMED_OPERANDS((0, object))
const JSClass* getClass() const { return class_; }
MDefinition* foldsTo(TempAllocator& alloc) override;
AliasSet getAliasSet() const override { return AliasSet::None(); }
bool congruentTo(const MDefinition* ins) const override {
if (!ins->isHasClass()) {