Bug 1608809 - Part 3: Remove lazy-proto code paths from JSOp::SuperBase implementations. r=jandem

The [[HomeObject]] slot is guaranteed to either contain a JSFunction or a
PlainObject, so we can use safely use `JSObject::staticPrototype()` to retrieve
the prototype and can also remove the lazy-proto handling in the compilers.

Differential Revision: https://phabricator.services.mozilla.com/D60680
This commit is contained in:
André Bargull committed 2020-01-31 06:12:41 +00:00
1 parent 070d6c7884
commit 184219917b
5 files changed
+53 -30

No files matched your search

+16 -7
View File
@@ -5679,19 +5679,28 @@ bool BaselineCodeGen<Handler>::emit_SuperBase() {
// Load prototype from [[HomeObject]]
masm.loadObjProto(scratch, proto);
Label hasProto;
#ifdef DEBUG
// We won't encounter a lazy proto, because the prototype is guaranteed to
// either be a JSFunction or a PlainObject, and only proxy objects can have a
// lazy proto.
MOZ_ASSERT(uintptr_t(TaggedProto::LazyProto) == 1);
masm.branchPtr(Assembler::Above, proto, ImmWord(1), &hasProto);
// Use VMCall for missing or lazy proto
Label proxyCheckDone;
masm.branchPtr(Assembler::NotEqual, proto, ImmWord(1), &proxyCheckDone);
masm.assumeUnreachable("Unexpected lazy proto in JSOp::SuperBase");
masm.bind(&proxyCheckDone);
#endif
Label hasProto;
masm.branchPtr(Assembler::NotEqual, proto, ImmWord(0), &hasProto);
// Throw an error if |proto| is null.
prepareVMCall();
pushArg(scratch); // [[HomeObject]]
using Fn = JSObject* (*)(JSContext*, HandleObject);
if (!callVM<Fn, HomeObjectSuperBase>()) {
using Fn = bool (*)(JSContext*);
if (!callVM<Fn, ThrowHomeObjectNotObject>()) {
return false;
}
masm.movePtr(ReturnReg, proto);
// Box prototype and return
masm.bind(&hasProto);
+17 -4
View File
@@ -4211,12 +4211,25 @@ void CodeGenerator::visitHomeObjectSuperBase(LHomeObjectSuperBase* lir) {
Register homeObject = ToRegister(lir->homeObject());
Register output = ToRegister(lir->output());
using Fn = JSObject* (*)(JSContext*, HandleObject);
OutOfLineCode* ool = oolCallVM<Fn, HomeObjectSuperBase>(
lir, ArgList(homeObject), StoreRegisterTo(output));
using Fn = bool (*)(JSContext*);
OutOfLineCode* ool =
oolCallVM<Fn, ThrowHomeObjectNotObject>(lir, ArgList(), StoreNothing());
masm.loadObjProto(homeObject, output);
masm.branchPtr(Assembler::BelowOrEqual, output, ImmWord(1), ool->entry());
#ifdef DEBUG
// We won't encounter a lazy proto, because the prototype is guaranteed to
// either be a JSFunction or a PlainObject, and only proxy objects can have a
// lazy proto.
MOZ_ASSERT(uintptr_t(TaggedProto::LazyProto) == 1);
Label proxyCheckDone;
masm.branchPtr(Assembler::NotEqual, output, ImmWord(1), &proxyCheckDone);
masm.assumeUnreachable("Unexpected lazy proto in JSOp::SuperBase");
masm.bind(&proxyCheckDone);
#endif
masm.branchPtr(Assembler::Equal, output, ImmWord(0), ool->entry());
masm.bind(ool->rejoin());
}
+1 -1
View File
@@ -148,7 +148,6 @@ namespace jit {
_(GreaterThan, js::jit::GreaterThan) \
_(GreaterThanOrEqual, js::jit::GreaterThanOrEqual) \
_(HandleDebugTrap, js::jit::HandleDebugTrap) \
_(HomeObjectSuperBase, js::HomeObjectSuperBase) \
_(ImplicitThisOperation, js::ImplicitThisOperation) \
_(ImportMetaOperation, js::ImportMetaOperation) \
_(InitElemGetterSetterOperation, js::InitElemGetterSetterOperation) \
@@ -275,6 +274,7 @@ namespace jit {
_(SubstringKernel, js::SubstringKernel) \
_(ThrowBadDerivedReturn, js::jit::ThrowBadDerivedReturn) \
_(ThrowCheckIsObject, js::ThrowCheckIsObject) \
_(ThrowHomeObjectNotObject, js::ThrowHomeObjectNotObject) \
_(ThrowInitializedThis, js::ThrowInitializedThis) \
_(ThrowMsgOperation, js::ThrowMsgOperation) \
_(ThrowObjectCoercible, js::jit::ThrowObjectCoercible) \
+17 -16
View File
@@ -334,6 +334,17 @@ static JSObject* SuperFunOperation(JSObject* callee) {
return callee->as<JSFunction>().staticPrototype();
}
static JSObject* HomeObjectSuperBase(JSContext* cx, JSObject* homeObj) {
MOZ_ASSERT(homeObj->is<PlainObject>() || homeObj->is<JSFunction>());
if (JSObject* superBase = homeObj->staticPrototype()) {
return superBase;
}
ThrowHomeObjectNotObject(cx);
return nullptr;
}
bool js::ReportIsNotFunction(JSContext* cx, HandleValue v, int numToSkip,
MaybeConstruct construct) {
unsigned error = construct ? JSMSG_NOT_CONSTRUCTOR : JSMSG_NOT_FUNCTION;
@@ -5343,27 +5354,17 @@ bool js::ThrowUninitializedThis(JSContext* cx) {
return false;
}
JSObject* js::HomeObjectSuperBase(JSContext* cx, HandleObject homeObj) {
RootedObject superBase(cx);
if (!GetPrototype(cx, homeObj, &superBase)) {
return nullptr;
}
if (!superBase) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_CANT_CONVERT_TO, "null", "object");
return nullptr;
}
return superBase;
}
bool js::ThrowInitializedThis(JSContext* cx) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_REINIT_THIS);
return false;
}
bool js::ThrowHomeObjectNotObject(JSContext* cx) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CANT_CONVERT_TO,
"null", "object");
return false;
}
bool js::SetPropertySuper(JSContext* cx, HandleObject obj, HandleValue receiver,
HandlePropertyName name, HandleValue rval,
bool strict) {
+2 -2
View File
@@ -643,6 +643,8 @@ bool ThrowUninitializedThis(JSContext* cx);
bool ThrowInitializedThis(JSContext* cx);
bool ThrowHomeObjectNotObject(JSContext* cx);
bool DefaultClassConstructor(JSContext* cx, unsigned argc, Value* vp);
bool Debug_CheckSelfHosted(JSContext* cx, HandleValue v);
@@ -657,8 +659,6 @@ JSObject* FunWithProtoOperation(JSContext* cx, HandleFunction fun,
JSFunction* MakeDefaultConstructor(JSContext* cx, HandleScript script,
jsbytecode* pc, HandleObject proto);
JSObject* HomeObjectSuperBase(JSContext* cx, HandleObject homeObj);
bool SetPropertySuper(JSContext* cx, HandleObject obj, HandleValue receiver,
HandlePropertyName id, HandleValue rval, bool strict);