зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
b9ee882ac8
Коммит
6032002978
|
@ -3092,10 +3092,10 @@ bool BaselineCodeGen<Handler>::emit_JSOP_DEFVAR() {
|
|||
return callVM(DefVarInfo);
|
||||
}
|
||||
|
||||
typedef bool (*DefLexicalFn)(JSContext*, HandlePropertyName, unsigned,
|
||||
HandleObject);
|
||||
typedef bool (*DefLexicalFn)(JSContext*, HandleObject, HandleScript,
|
||||
jsbytecode*);
|
||||
static const VMFunction DefLexicalInfo =
|
||||
FunctionInfo<DefLexicalFn>(DefLexical, "DefLexical");
|
||||
FunctionInfo<DefLexicalFn>(DefLexicalOperation, "DefLexicalOperation");
|
||||
|
||||
template <typename Handler>
|
||||
bool BaselineCodeGen<Handler>::emitDefLexical(JSOp op) {
|
||||
|
@ -3103,19 +3103,13 @@ bool BaselineCodeGen<Handler>::emitDefLexical(JSOp op) {
|
|||
|
||||
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());
|
||||
|
||||
prepareVMCall();
|
||||
|
||||
pushArg(ImmPtr(pc));
|
||||
pushArg(ImmGCPtr(script));
|
||||
pushArg(R0.scratchReg());
|
||||
pushArg(Imm32(attrs));
|
||||
pushArg(ImmGCPtr(script->getName(pc)));
|
||||
|
||||
return callVM(DefLexicalInfo);
|
||||
}
|
||||
|
|
|
@ -176,6 +176,8 @@ bool BytecodeAnalysis::init(TempAllocator& alloc, GSNCache& gsn) {
|
|||
case JSOP_LAMBDA_ARROW:
|
||||
case JSOP_DEFFUN:
|
||||
case JSOP_DEFVAR:
|
||||
case JSOP_DEFLET:
|
||||
case JSOP_DEFCONST:
|
||||
case JSOP_PUSHLEXICALENV:
|
||||
case JSOP_POPLEXICALENV:
|
||||
case JSOP_IMPLICITTHIS:
|
||||
|
|
|
@ -5420,13 +5420,20 @@ void CodeGenerator::visitDefVar(LDefVar* lir) {
|
|||
callVM(DefVarInfo, lir);
|
||||
}
|
||||
|
||||
typedef bool (*DefLexicalFn)(JSContext*, HandlePropertyName, unsigned);
|
||||
typedef bool (*DefLexicalFn)(JSContext*, HandleObject, HandleScript,
|
||||
jsbytecode*);
|
||||
static const VMFunction DefLexicalInfo =
|
||||
FunctionInfo<DefLexicalFn>(DefGlobalLexical, "DefGlobalLexical");
|
||||
FunctionInfo<DefLexicalFn>(DefLexicalOperation, "DefLexicalOperation");
|
||||
|
||||
void CodeGenerator::visitDefLexical(LDefLexical* lir) {
|
||||
pushArg(Imm32(lir->mir()->attrs())); // unsigned
|
||||
pushArg(ImmGCPtr(lir->mir()->name())); // PropertyName*
|
||||
Register envChain = ToRegister(lir->environmentChain());
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -1915,11 +1915,11 @@ AbortReasonOr<Ok> IonBuilder::inspectOpcode(JSOp op) {
|
|||
return jsop_tostring();
|
||||
|
||||
case JSOP_DEFVAR:
|
||||
return jsop_defvar(GET_UINT32_INDEX(pc));
|
||||
return jsop_defvar();
|
||||
|
||||
case JSOP_DEFLET:
|
||||
case JSOP_DEFCONST:
|
||||
return jsop_deflexical(GET_UINT32_INDEX(pc));
|
||||
return jsop_deflexical();
|
||||
|
||||
case JSOP_DEFFUN:
|
||||
return jsop_deffun();
|
||||
|
@ -12775,7 +12775,7 @@ AbortReasonOr<Ok> IonBuilder::jsop_setarg(uint32_t arg) {
|
|||
return Ok();
|
||||
}
|
||||
|
||||
AbortReasonOr<Ok> IonBuilder::jsop_defvar(uint32_t index) {
|
||||
AbortReasonOr<Ok> IonBuilder::jsop_defvar() {
|
||||
MOZ_ASSERT(JSOp(*pc) == JSOP_DEFVAR);
|
||||
|
||||
// Pass the EnvironmentChain.
|
||||
|
@ -12787,20 +12787,15 @@ AbortReasonOr<Ok> IonBuilder::jsop_defvar(uint32_t index) {
|
|||
return resumeAfter(defvar);
|
||||
}
|
||||
|
||||
AbortReasonOr<Ok> IonBuilder::jsop_deflexical(uint32_t index) {
|
||||
MOZ_ASSERT(!script()->hasNonSyntacticScope());
|
||||
AbortReasonOr<Ok> IonBuilder::jsop_deflexical() {
|
||||
MOZ_ASSERT(JSOp(*pc) == JSOP_DEFLET || JSOp(*pc) == JSOP_DEFCONST);
|
||||
MOZ_ASSERT(usesEnvironmentChain());
|
||||
|
||||
PropertyName* name = script()->getName(index);
|
||||
unsigned attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT;
|
||||
if (JSOp(*pc) == JSOP_DEFCONST) {
|
||||
attrs |= JSPROP_READONLY;
|
||||
}
|
||||
MDefinition* env = current->environmentChain();
|
||||
MDefLexical* defLexical = MDefLexical::New(alloc(), env);
|
||||
current->add(defLexical);
|
||||
|
||||
MDefLexical* deflex = MDefLexical::New(alloc(), name, attrs);
|
||||
current->add(deflex);
|
||||
|
||||
return resumeAfter(deflex);
|
||||
return resumeAfter(defLexical);
|
||||
}
|
||||
|
||||
AbortReasonOr<Ok> IonBuilder::jsop_deffun() {
|
||||
|
|
|
@ -537,8 +537,8 @@ class IonBuilder : public MIRGenerator,
|
|||
AbortReasonOr<Ok> jsop_neg();
|
||||
AbortReasonOr<Ok> jsop_tostring();
|
||||
AbortReasonOr<Ok> jsop_setarg(uint32_t arg);
|
||||
AbortReasonOr<Ok> jsop_defvar(uint32_t index);
|
||||
AbortReasonOr<Ok> jsop_deflexical(uint32_t index);
|
||||
AbortReasonOr<Ok> jsop_defvar();
|
||||
AbortReasonOr<Ok> jsop_deflexical();
|
||||
AbortReasonOr<Ok> jsop_deffun();
|
||||
AbortReasonOr<Ok> jsop_notearg();
|
||||
AbortReasonOr<Ok> jsop_throwsetconst();
|
||||
|
|
|
@ -141,7 +141,8 @@ void LIRGenerator::visitDefVar(MDefVar* ins) {
|
|||
}
|
||||
|
||||
void LIRGenerator::visitDefLexical(MDefLexical* ins) {
|
||||
LDefLexical* lir = new (alloc()) LDefLexical();
|
||||
LDefLexical* lir =
|
||||
new (alloc()) LDefLexical(useRegisterAtStart(ins->environmentChain()));
|
||||
add(lir, ins);
|
||||
assignSafepoint(lir, ins);
|
||||
}
|
||||
|
|
|
@ -6318,23 +6318,17 @@ class MDefVar : public MUnaryInstruction, public NoTypePolicy::Data {
|
|||
bool possiblyCalls() const override { return true; }
|
||||
};
|
||||
|
||||
class MDefLexical : public MNullaryInstruction {
|
||||
CompilerPropertyName name_; // Target name to be defined.
|
||||
unsigned attrs_; // Attributes to be set.
|
||||
|
||||
class MDefLexical : public MUnaryInstruction, public NoTypePolicy::Data {
|
||||
private:
|
||||
MDefLexical(PropertyName* name, unsigned attrs)
|
||||
: MNullaryInstruction(classOpcode), name_(name), attrs_(attrs) {}
|
||||
explicit MDefLexical(MDefinition* envChain)
|
||||
: MUnaryInstruction(classOpcode, envChain) {}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(DefLexical)
|
||||
TRIVIAL_NEW_WRAPPERS
|
||||
NAMED_OPERANDS((0, environmentChain))
|
||||
|
||||
PropertyName* name() const { return name_; }
|
||||
unsigned attrs() const { return attrs_; }
|
||||
bool appendRoots(MRootList& roots) const override {
|
||||
return roots.append(name_);
|
||||
}
|
||||
bool possiblyCalls() const override { return true; }
|
||||
};
|
||||
|
||||
class MDefFun : public MBinaryInstruction, public ObjectPolicy<0>::Data {
|
||||
|
|
|
@ -189,23 +189,6 @@ bool CheckOverRecursedBaseline(JSContext* cx, BaselineFrame* frame) {
|
|||
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) {
|
||||
if (!value.isObjectOrNull()) {
|
||||
return true;
|
||||
|
|
|
@ -921,10 +921,6 @@ bool InvokeFromInterpreterStub(JSContext* cx,
|
|||
bool CheckOverRecursed(JSContext* cx);
|
||||
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,
|
||||
HandleValue value);
|
||||
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(); }
|
||||
};
|
||||
|
||||
class LDefLexical : public LCallInstructionHelper<0, 0, 0> {
|
||||
class LDefLexical : public LCallInstructionHelper<0, 1, 0> {
|
||||
public:
|
||||
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(); }
|
||||
};
|
||||
|
||||
|
|
|
@ -4622,35 +4622,27 @@ bool js::DefVarOperation(JSContext* cx, HandleObject envChain,
|
|||
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,
|
||||
HandleScript script, jsbytecode* pc) {
|
||||
MOZ_ASSERT(*pc == JSOP_DEFLET || *pc == JSOP_DEFCONST);
|
||||
|
||||
RootedPropertyName name(cx, script->getName(pc));
|
||||
|
||||
unsigned attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT;
|
||||
if (*pc == JSOP_DEFCONST) {
|
||||
attrs |= JSPROP_READONLY;
|
||||
}
|
||||
|
||||
Rooted<LexicalEnvironmentObject*> lexicalEnv(cx);
|
||||
RootedObject varObj(cx);
|
||||
if (script->hasNonSyntacticScope()) {
|
||||
lexicalEnv = &NearestEnclosingExtensibleLexicalEnvironment(envChain);
|
||||
varObj = &GetVariablesObject(envChain);
|
||||
} else {
|
||||
lexicalEnv = &cx->global()->lexicalEnvironment();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
RootedObject varObj(cx);
|
||||
if (script->hasNonSyntacticScope()) {
|
||||
varObj = &GetVariablesObject(envChain);
|
||||
} else {
|
||||
varObj = cx->global();
|
||||
}
|
||||
|
||||
|
@ -4658,7 +4650,14 @@ bool js::DefLexicalOperation(JSContext* cx, HandleObject envChain,
|
|||
lexicalEnv == &cx->global()->lexicalEnvironment() &&
|
||||
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,
|
||||
|
|
|
@ -449,11 +449,6 @@ JSObject* BindVarOperation(JSContext* cx, JSObject* envChain);
|
|||
bool DefVarOperation(JSContext* cx, HandleObject envChain, HandleScript script,
|
||||
jsbytecode* pc);
|
||||
|
||||
bool DefLexicalOperation(JSContext* cx,
|
||||
Handle<LexicalEnvironmentObject*> lexicalEnv,
|
||||
HandleObject varObj, HandlePropertyName name,
|
||||
unsigned attrs);
|
||||
|
||||
bool DefLexicalOperation(JSContext* cx, HandleObject envChain,
|
||||
HandleScript script, jsbytecode* pc);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче