Part 3: Support JSOP_SETFUNNAME in Baseline and Ion

Issue #87
This commit is contained in:
janekptacijarabaci 2018-03-19 15:59:22 +01:00 committed by Roy Tam
commit 7bfe087f0c
12 changed files with 122 additions and 0 deletions

View file

@ -9,6 +9,8 @@
#include "mozilla/Casting.h"
#include "mozilla/SizePrintfMacros.h"
#include "jsfun.h"
#include "jit/BaselineIC.h"
#include "jit/BaselineJIT.h"
#include "jit/FixedList.h"
@ -1681,6 +1683,29 @@ BaselineCompiler::emit_JSOP_LAMBDA_ARROW()
return true;
}
typedef bool (*SetFunNameFn)(JSContext*, HandleFunction, HandleValue, FunctionPrefixKind);
static const VMFunction SetFunNameInfo =
FunctionInfo<SetFunNameFn>(js::SetFunctionNameIfNoOwnName, "SetFunName");
bool
BaselineCompiler::emit_JSOP_SETFUNNAME()
{
frame.popRegsAndSync(2);
frame.push(R0);
frame.syncStack(0);
FunctionPrefixKind prefixKind = FunctionPrefixKind(GET_UINT8(pc));
masm.unboxObject(R0, R0.scratchReg());
prepareVMCall();
pushArg(Imm32(int32_t(prefixKind)));
pushArg(R1);
pushArg(R0.scratchReg());
return callVM(SetFunNameInfo);
}
void
BaselineCompiler::storeValue(const StackValue* source, const Address& dest,
const ValueOperand& scratch)

View file

@ -71,6 +71,7 @@ namespace jit {
_(JSOP_REGEXP) \
_(JSOP_LAMBDA) \
_(JSOP_LAMBDA_ARROW) \
_(JSOP_SETFUNNAME) \
_(JSOP_BITOR) \
_(JSOP_BITXOR) \
_(JSOP_BITAND) \

View file

@ -2548,6 +2548,20 @@ CodeGenerator::emitLambdaInit(Register output, Register envChain,
masm.storePtr(ImmGCPtr(info.fun->displayAtom()), Address(output, JSFunction::offsetOfAtom()));
}
typedef bool (*SetFunNameFn)(JSContext*, HandleFunction, HandleValue, FunctionPrefixKind);
static const VMFunction SetFunNameInfo =
FunctionInfo<SetFunNameFn>(js::SetFunctionNameIfNoOwnName, "SetFunName");
void
CodeGenerator::visitSetFunName(LSetFunName* lir)
{
pushArg(Imm32(lir->mir()->prefixKind()));
pushArg(ToValue(lir, LSetFunName::NameValue));
pushArg(ToRegister(lir->fun()));
callVM(SetFunNameInfo, lir);
}
void
CodeGenerator::visitOsiPoint(LOsiPoint* lir)
{

View file

@ -134,6 +134,7 @@ class CodeGenerator final : public CodeGeneratorSpecific
void visitOutOfLineLambdaArrow(OutOfLineLambdaArrow* ool);
void visitLambdaArrow(LLambdaArrow* lir);
void visitLambdaForSingleton(LLambdaForSingleton* lir);
void visitSetFunName(LSetFunName* lir);
void visitPointer(LPointer* lir);
void visitKeepAliveObject(LKeepAliveObject* lir);
void visitSlots(LSlots* lir);

View file

@ -2122,6 +2122,9 @@ IonBuilder::inspectOpcode(JSOp op)
case JSOP_LAMBDA_ARROW:
return jsop_lambda_arrow(info().getFunction(pc));
case JSOP_SETFUNNAME:
return jsop_setfunname(GET_UINT8(pc));
case JSOP_ITER:
return jsop_iter(GET_INT8(pc));
@ -13339,6 +13342,21 @@ IonBuilder::jsop_lambda_arrow(JSFunction* fun)
return resumeAfter(ins);
}
bool
IonBuilder::jsop_setfunname(uint8_t prefixKind)
{
MDefinition* name = current->pop();
MDefinition* fun = current->pop();
MOZ_ASSERT(fun->type() == MIRType::Object);
MSetFunName* ins = MSetFunName::New(alloc(), fun, name, prefixKind);
current->add(ins);
current->push(fun);
return resumeAfter(ins);
}
bool
IonBuilder::jsop_setarg(uint32_t arg)
{

View file

@ -766,6 +766,7 @@ class IonBuilder
MOZ_MUST_USE bool jsop_object(JSObject* obj);
MOZ_MUST_USE bool jsop_lambda(JSFunction* fun);
MOZ_MUST_USE bool jsop_lambda_arrow(JSFunction* fun);
MOZ_MUST_USE bool jsop_setfunname(uint8_t prefixKind);
MOZ_MUST_USE bool jsop_functionthis();
MOZ_MUST_USE bool jsop_globalthis();
MOZ_MUST_USE bool jsop_typeof();

View file

@ -2459,6 +2459,18 @@ LIRGenerator::visitLambdaArrow(MLambdaArrow* ins)
assignSafepoint(lir, ins);
}
void
LIRGenerator::visitSetFunName(MSetFunName* ins)
{
MOZ_ASSERT(ins->fun()->type() == MIRType::Object);
MOZ_ASSERT(ins->name()->type() == MIRType::Value);
LSetFunName* lir = new(alloc()) LSetFunName(useRegisterAtStart(ins->fun()),
useBoxAtStart(ins->name()));
add(lir, ins);
assignSafepoint(lir, ins);
}
void
LIRGenerator::visitKeepAliveObject(MKeepAliveObject* ins)
{

View file

@ -185,6 +185,7 @@ class LIRGenerator : public LIRGeneratorSpecific
void visitNullarySharedStub(MNullarySharedStub* ins);
void visitLambda(MLambda* ins);
void visitLambdaArrow(MLambdaArrow* ins);
void visitSetFunName(MSetFunName* ins);
void visitKeepAliveObject(MKeepAliveObject* ins);
void visitSlots(MSlots* ins);
void visitElements(MElements* ins);

View file

@ -8464,6 +8464,34 @@ class MLambdaArrow
}
};
class MSetFunName
: public MAryInstruction<2>,
public MixPolicy<ObjectPolicy<0>, BoxPolicy<1> >::Data
{
uint8_t prefixKind_;
explicit MSetFunName(MDefinition* fun, MDefinition* name, uint8_t prefixKind)
: prefixKind_(prefixKind)
{
initOperand(0, fun);
initOperand(1, name);
setResultType(MIRType::None);
}
public:
INSTRUCTION_HEADER(SetFunName)
TRIVIAL_NEW_WRAPPERS
NAMED_OPERANDS((0, fun), (1, name))
uint8_t prefixKind() const {
return prefixKind_;
}
bool possiblyCalls() const override {
return true;
}
};
// Returns obj->slots.
class MSlots
: public MUnaryInstruction,

View file

@ -161,6 +161,7 @@ namespace jit {
_(StringReplace) \
_(Lambda) \
_(LambdaArrow) \
_(SetFunName) \
_(KeepAliveObject) \
_(Slots) \
_(Elements) \

View file

@ -4995,6 +4995,25 @@ class LLambdaArrow : public LInstructionHelper<1, 1 + BOX_PIECES, 0>
}
};
class LSetFunName : public LCallInstructionHelper<1, 1 + BOX_PIECES, 0>
{
public:
LIR_HEADER(SetFunName)
static const size_t NameValue = 1;
LSetFunName(const LAllocation& fun, const LBoxAllocation& name) {
setOperand(0, fun);
setBoxOperand(NameValue, name);
}
const LAllocation* fun() {
return getOperand(0);
}
const MSetFunName* mir() const {
return mir_->toSetFunName();
}
};
class LKeepAliveObject : public LInstructionHelper<0, 1, 0>
{
public:

View file

@ -242,6 +242,7 @@
_(Lambda) \
_(LambdaArrow) \
_(LambdaForSingleton) \
_(SetFunName) \
_(KeepAliveObject) \
_(Slots) \
_(Elements) \