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

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

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

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

@ -174,7 +174,7 @@ bool DeadIfUnused(const MDefinition* def);
bool IsDiscardable(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); KnownClass GetObjectKnownClass(const MDefinition* def);
const JSClass* GetObjectKnownJSClass(const MDefinition* def); const JSClass* GetObjectKnownJSClass(const MDefinition* def);

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

@ -3587,6 +3587,7 @@ MDefinition* MTypeOf::foldsTo(TempAllocator& alloc) {
switch (known) { switch (known) {
case KnownClass::Array: case KnownClass::Array:
case KnownClass::PlainObject: case KnownClass::PlainObject:
case KnownClass::RegExp:
type = JSTYPE_OBJECT; type = JSTYPE_OBJECT;
break; break;
case KnownClass::Function: case KnownClass::Function:
@ -5908,6 +5909,30 @@ MDefinition* MGuardToClass::foldsTo(TempAllocator& alloc) {
return object(); 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) { MDefinition* MIsArray::foldsTo(TempAllocator& alloc) {
if (input()->type() != MIRType::Object) { if (input()->type() != MIRType::Object) {
return this; return this;

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

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