Bug 1511891 part 6 - Merge two DefLexicalOperation functions into one and have the JITs call it directly. r=tcampbell

Differential Revision: https://phabricator.services.mozilla.com/D13704

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jan de Mooij 2019-01-11 09:14:17 +00:00
Родитель b9ee882ac8
Коммит 6032002978
12 изменённых файлов: 57 добавлений и 87 удалений

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

@ -3092,10 +3092,10 @@ bool BaselineCodeGen<Handler>::emit_JSOP_DEFVAR() {
return callVM(DefVarInfo); return callVM(DefVarInfo);
} }
typedef bool (*DefLexicalFn)(JSContext*, HandlePropertyName, unsigned, typedef bool (*DefLexicalFn)(JSContext*, HandleObject, HandleScript,
HandleObject); jsbytecode*);
static const VMFunction DefLexicalInfo = static const VMFunction DefLexicalInfo =
FunctionInfo<DefLexicalFn>(DefLexical, "DefLexical"); FunctionInfo<DefLexicalFn>(DefLexicalOperation, "DefLexicalOperation");
template <typename Handler> template <typename Handler>
bool BaselineCodeGen<Handler>::emitDefLexical(JSOp op) { bool BaselineCodeGen<Handler>::emitDefLexical(JSOp op) {
@ -3103,19 +3103,13 @@ bool BaselineCodeGen<Handler>::emitDefLexical(JSOp op) {
frame.syncStack(0); frame.syncStack(0);
unsigned attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT;
if (op == JSOP_DEFCONST) {
attrs |= JSPROP_READONLY;
}
MOZ_ASSERT(attrs <= UINT32_MAX);
masm.loadPtr(frame.addressOfEnvironmentChain(), R0.scratchReg()); masm.loadPtr(frame.addressOfEnvironmentChain(), R0.scratchReg());
prepareVMCall(); prepareVMCall();
pushArg(ImmPtr(pc));
pushArg(ImmGCPtr(script));
pushArg(R0.scratchReg()); pushArg(R0.scratchReg());
pushArg(Imm32(attrs));
pushArg(ImmGCPtr(script->getName(pc)));
return callVM(DefLexicalInfo); return callVM(DefLexicalInfo);
} }

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

@ -176,6 +176,8 @@ bool BytecodeAnalysis::init(TempAllocator& alloc, GSNCache& gsn) {
case JSOP_LAMBDA_ARROW: case JSOP_LAMBDA_ARROW:
case JSOP_DEFFUN: case JSOP_DEFFUN:
case JSOP_DEFVAR: case JSOP_DEFVAR:
case JSOP_DEFLET:
case JSOP_DEFCONST:
case JSOP_PUSHLEXICALENV: case JSOP_PUSHLEXICALENV:
case JSOP_POPLEXICALENV: case JSOP_POPLEXICALENV:
case JSOP_IMPLICITTHIS: case JSOP_IMPLICITTHIS:

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

@ -5420,13 +5420,20 @@ void CodeGenerator::visitDefVar(LDefVar* lir) {
callVM(DefVarInfo, lir); callVM(DefVarInfo, lir);
} }
typedef bool (*DefLexicalFn)(JSContext*, HandlePropertyName, unsigned); typedef bool (*DefLexicalFn)(JSContext*, HandleObject, HandleScript,
jsbytecode*);
static const VMFunction DefLexicalInfo = static const VMFunction DefLexicalInfo =
FunctionInfo<DefLexicalFn>(DefGlobalLexical, "DefGlobalLexical"); FunctionInfo<DefLexicalFn>(DefLexicalOperation, "DefLexicalOperation");
void CodeGenerator::visitDefLexical(LDefLexical* lir) { void CodeGenerator::visitDefLexical(LDefLexical* lir) {
pushArg(Imm32(lir->mir()->attrs())); // unsigned Register envChain = ToRegister(lir->environmentChain());
pushArg(ImmGCPtr(lir->mir()->name())); // PropertyName*
JSScript* script = current->mir()->info().script();
jsbytecode* pc = lir->mir()->resumePoint()->pc();
pushArg(ImmPtr(pc)); // jsbytecode*
pushArg(ImmGCPtr(script)); // JSScript*
pushArg(envChain); // JSObject*
callVM(DefLexicalInfo, lir); callVM(DefLexicalInfo, lir);
} }

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

@ -1915,11 +1915,11 @@ AbortReasonOr<Ok> IonBuilder::inspectOpcode(JSOp op) {
return jsop_tostring(); return jsop_tostring();
case JSOP_DEFVAR: case JSOP_DEFVAR:
return jsop_defvar(GET_UINT32_INDEX(pc)); return jsop_defvar();
case JSOP_DEFLET: case JSOP_DEFLET:
case JSOP_DEFCONST: case JSOP_DEFCONST:
return jsop_deflexical(GET_UINT32_INDEX(pc)); return jsop_deflexical();
case JSOP_DEFFUN: case JSOP_DEFFUN:
return jsop_deffun(); return jsop_deffun();
@ -12775,7 +12775,7 @@ AbortReasonOr<Ok> IonBuilder::jsop_setarg(uint32_t arg) {
return Ok(); return Ok();
} }
AbortReasonOr<Ok> IonBuilder::jsop_defvar(uint32_t index) { AbortReasonOr<Ok> IonBuilder::jsop_defvar() {
MOZ_ASSERT(JSOp(*pc) == JSOP_DEFVAR); MOZ_ASSERT(JSOp(*pc) == JSOP_DEFVAR);
// Pass the EnvironmentChain. // Pass the EnvironmentChain.
@ -12787,20 +12787,15 @@ AbortReasonOr<Ok> IonBuilder::jsop_defvar(uint32_t index) {
return resumeAfter(defvar); return resumeAfter(defvar);
} }
AbortReasonOr<Ok> IonBuilder::jsop_deflexical(uint32_t index) { AbortReasonOr<Ok> IonBuilder::jsop_deflexical() {
MOZ_ASSERT(!script()->hasNonSyntacticScope());
MOZ_ASSERT(JSOp(*pc) == JSOP_DEFLET || JSOp(*pc) == JSOP_DEFCONST); MOZ_ASSERT(JSOp(*pc) == JSOP_DEFLET || JSOp(*pc) == JSOP_DEFCONST);
MOZ_ASSERT(usesEnvironmentChain());
PropertyName* name = script()->getName(index); MDefinition* env = current->environmentChain();
unsigned attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT; MDefLexical* defLexical = MDefLexical::New(alloc(), env);
if (JSOp(*pc) == JSOP_DEFCONST) { current->add(defLexical);
attrs |= JSPROP_READONLY;
}
MDefLexical* deflex = MDefLexical::New(alloc(), name, attrs); return resumeAfter(defLexical);
current->add(deflex);
return resumeAfter(deflex);
} }
AbortReasonOr<Ok> IonBuilder::jsop_deffun() { AbortReasonOr<Ok> IonBuilder::jsop_deffun() {

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

@ -537,8 +537,8 @@ class IonBuilder : public MIRGenerator,
AbortReasonOr<Ok> jsop_neg(); AbortReasonOr<Ok> jsop_neg();
AbortReasonOr<Ok> jsop_tostring(); AbortReasonOr<Ok> jsop_tostring();
AbortReasonOr<Ok> jsop_setarg(uint32_t arg); AbortReasonOr<Ok> jsop_setarg(uint32_t arg);
AbortReasonOr<Ok> jsop_defvar(uint32_t index); AbortReasonOr<Ok> jsop_defvar();
AbortReasonOr<Ok> jsop_deflexical(uint32_t index); AbortReasonOr<Ok> jsop_deflexical();
AbortReasonOr<Ok> jsop_deffun(); AbortReasonOr<Ok> jsop_deffun();
AbortReasonOr<Ok> jsop_notearg(); AbortReasonOr<Ok> jsop_notearg();
AbortReasonOr<Ok> jsop_throwsetconst(); AbortReasonOr<Ok> jsop_throwsetconst();

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

@ -141,7 +141,8 @@ void LIRGenerator::visitDefVar(MDefVar* ins) {
} }
void LIRGenerator::visitDefLexical(MDefLexical* ins) { void LIRGenerator::visitDefLexical(MDefLexical* ins) {
LDefLexical* lir = new (alloc()) LDefLexical(); LDefLexical* lir =
new (alloc()) LDefLexical(useRegisterAtStart(ins->environmentChain()));
add(lir, ins); add(lir, ins);
assignSafepoint(lir, ins); assignSafepoint(lir, ins);
} }

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

@ -6318,23 +6318,17 @@ class MDefVar : public MUnaryInstruction, public NoTypePolicy::Data {
bool possiblyCalls() const override { return true; } bool possiblyCalls() const override { return true; }
}; };
class MDefLexical : public MNullaryInstruction { class MDefLexical : public MUnaryInstruction, public NoTypePolicy::Data {
CompilerPropertyName name_; // Target name to be defined.
unsigned attrs_; // Attributes to be set.
private: private:
MDefLexical(PropertyName* name, unsigned attrs) explicit MDefLexical(MDefinition* envChain)
: MNullaryInstruction(classOpcode), name_(name), attrs_(attrs) {} : MUnaryInstruction(classOpcode, envChain) {}
public: public:
INSTRUCTION_HEADER(DefLexical) INSTRUCTION_HEADER(DefLexical)
TRIVIAL_NEW_WRAPPERS TRIVIAL_NEW_WRAPPERS
NAMED_OPERANDS((0, environmentChain))
PropertyName* name() const { return name_; } bool possiblyCalls() const override { return true; }
unsigned attrs() const { return attrs_; }
bool appendRoots(MRootList& roots) const override {
return roots.append(name_);
}
}; };
class MDefFun : public MBinaryInstruction, public ObjectPolicy<0>::Data { class MDefFun : public MBinaryInstruction, public ObjectPolicy<0>::Data {

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

@ -189,23 +189,6 @@ bool CheckOverRecursedBaseline(JSContext* cx, BaselineFrame* frame) {
return CheckOverRecursed(cx); return CheckOverRecursed(cx);
} }
bool DefLexical(JSContext* cx, HandlePropertyName dn, unsigned attrs,
HandleObject envChain) {
// Find the extensible lexical scope.
Rooted<LexicalEnvironmentObject*> lexicalEnv(
cx, &NearestEnclosingExtensibleLexicalEnvironment(envChain));
// Find the variables object.
RootedObject varObj(cx, &GetVariablesObject(envChain));
return DefLexicalOperation(cx, lexicalEnv, varObj, dn, attrs);
}
bool DefGlobalLexical(JSContext* cx, HandlePropertyName dn, unsigned attrs) {
Rooted<LexicalEnvironmentObject*> globalLexical(
cx, &cx->global()->lexicalEnvironment());
return DefLexicalOperation(cx, globalLexical, cx->global(), dn, attrs);
}
bool MutatePrototype(JSContext* cx, HandlePlainObject obj, HandleValue value) { bool MutatePrototype(JSContext* cx, HandlePlainObject obj, HandleValue value) {
if (!value.isObjectOrNull()) { if (!value.isObjectOrNull()) {
return true; return true;

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

@ -921,10 +921,6 @@ bool InvokeFromInterpreterStub(JSContext* cx,
bool CheckOverRecursed(JSContext* cx); bool CheckOverRecursed(JSContext* cx);
bool CheckOverRecursedBaseline(JSContext* cx, BaselineFrame* frame); bool CheckOverRecursedBaseline(JSContext* cx, BaselineFrame* frame);
MOZ_MUST_USE bool DefLexical(JSContext* cx, HandlePropertyName dn,
unsigned attrs, HandleObject scopeChain);
MOZ_MUST_USE bool DefGlobalLexical(JSContext* cx, HandlePropertyName dn,
unsigned attrs);
MOZ_MUST_USE bool MutatePrototype(JSContext* cx, HandlePlainObject obj, MOZ_MUST_USE bool MutatePrototype(JSContext* cx, HandlePlainObject obj,
HandleValue value); HandleValue value);
MOZ_MUST_USE bool InitProp(JSContext* cx, HandleObject obj, MOZ_MUST_USE bool InitProp(JSContext* cx, HandleObject obj,

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

@ -712,12 +712,16 @@ class LDefVar : public LCallInstructionHelper<0, 1, 0> {
MDefVar* mir() const { return mir_->toDefVar(); } MDefVar* mir() const { return mir_->toDefVar(); }
}; };
class LDefLexical : public LCallInstructionHelper<0, 0, 0> { class LDefLexical : public LCallInstructionHelper<0, 1, 0> {
public: public:
LIR_HEADER(DefLexical) LIR_HEADER(DefLexical)
LDefLexical() : LCallInstructionHelper(classOpcode) {} explicit LDefLexical(const LAllocation& envChain)
: LCallInstructionHelper(classOpcode) {
setOperand(0, envChain);
}
const LAllocation* environmentChain() { return getOperand(0); }
MDefLexical* mir() const { return mir_->toDefLexical(); } MDefLexical* mir() const { return mir_->toDefLexical(); }
}; };

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

@ -4622,35 +4622,27 @@ bool js::DefVarOperation(JSContext* cx, HandleObject envChain,
return true; return true;
} }
bool js::DefLexicalOperation(JSContext* cx,
Handle<LexicalEnvironmentObject*> lexicalEnv,
HandleObject varObj, HandlePropertyName name,
unsigned attrs) {
// Redeclaration checks should have already been done.
MOZ_ASSERT(CheckLexicalNameConflict(cx, lexicalEnv, varObj, name));
RootedId id(cx, NameToId(name));
RootedValue uninitialized(cx, MagicValue(JS_UNINITIALIZED_LEXICAL));
return NativeDefineDataProperty(cx, lexicalEnv, id, uninitialized, attrs);
}
bool js::DefLexicalOperation(JSContext* cx, HandleObject envChain, bool js::DefLexicalOperation(JSContext* cx, HandleObject envChain,
HandleScript script, jsbytecode* pc) { HandleScript script, jsbytecode* pc) {
MOZ_ASSERT(*pc == JSOP_DEFLET || *pc == JSOP_DEFCONST); MOZ_ASSERT(*pc == JSOP_DEFLET || *pc == JSOP_DEFCONST);
RootedPropertyName name(cx, script->getName(pc));
unsigned attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT; unsigned attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT;
if (*pc == JSOP_DEFCONST) { if (*pc == JSOP_DEFCONST) {
attrs |= JSPROP_READONLY; attrs |= JSPROP_READONLY;
} }
Rooted<LexicalEnvironmentObject*> lexicalEnv(cx); Rooted<LexicalEnvironmentObject*> lexicalEnv(cx);
RootedObject varObj(cx);
if (script->hasNonSyntacticScope()) { if (script->hasNonSyntacticScope()) {
lexicalEnv = &NearestEnclosingExtensibleLexicalEnvironment(envChain); lexicalEnv = &NearestEnclosingExtensibleLexicalEnvironment(envChain);
varObj = &GetVariablesObject(envChain);
} else { } else {
lexicalEnv = &cx->global()->lexicalEnvironment(); lexicalEnv = &cx->global()->lexicalEnvironment();
}
#ifdef DEBUG
RootedObject varObj(cx);
if (script->hasNonSyntacticScope()) {
varObj = &GetVariablesObject(envChain);
} else {
varObj = cx->global(); varObj = cx->global();
} }
@ -4658,7 +4650,14 @@ bool js::DefLexicalOperation(JSContext* cx, HandleObject envChain,
lexicalEnv == &cx->global()->lexicalEnvironment() && lexicalEnv == &cx->global()->lexicalEnvironment() &&
varObj == cx->global()); varObj == cx->global());
return DefLexicalOperation(cx, lexicalEnv, varObj, name, attrs); // Redeclaration checks should have already been done.
RootedPropertyName name(cx, script->getName(pc));
MOZ_ASSERT(CheckLexicalNameConflict(cx, lexicalEnv, varObj, name));
#endif
RootedId id(cx, NameToId(script->getName(pc)));
RootedValue uninitialized(cx, MagicValue(JS_UNINITIALIZED_LEXICAL));
return NativeDefineDataProperty(cx, lexicalEnv, id, uninitialized, attrs);
} }
bool js::DefFunOperation(JSContext* cx, HandleScript script, bool js::DefFunOperation(JSContext* cx, HandleScript script,

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

@ -449,11 +449,6 @@ JSObject* BindVarOperation(JSContext* cx, JSObject* envChain);
bool DefVarOperation(JSContext* cx, HandleObject envChain, HandleScript script, bool DefVarOperation(JSContext* cx, HandleObject envChain, HandleScript script,
jsbytecode* pc); jsbytecode* pc);
bool DefLexicalOperation(JSContext* cx,
Handle<LexicalEnvironmentObject*> lexicalEnv,
HandleObject varObj, HandlePropertyName name,
unsigned attrs);
bool DefLexicalOperation(JSContext* cx, HandleObject envChain, bool DefLexicalOperation(JSContext* cx, HandleObject envChain,
HandleScript script, jsbytecode* pc); HandleScript script, jsbytecode* pc);