mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 16:25:38 +00:00
Bug 1508962 part 1 - Add a BaselineCodeGen<Handler> base class to BaselineCompiler and use it for JSOp compilation. r=djvj
This is just the first step: the Handler classes are still empty and BaselineCodeGen contains fields/methods that should eventually move out of there. That will happen in follow-up patches. Rooting analysis now reported a hazard in ObjectGroup::getOrFixupCopyOnWriteObject, this patch has the trivial fix for that too. Differential Revision: https://phabricator.services.mozilla.com/D12522 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
725be0ed7c
commit
07002c8c3d
File diff suppressed because it is too large
Load Diff
@ -249,8 +249,16 @@ namespace jit {
|
||||
_(JSOP_IMPORTMETA) \
|
||||
_(JSOP_DYNAMIC_IMPORT)
|
||||
|
||||
class BaselineCompiler final
|
||||
// Base class for BaselineCompiler and BaselineInterpreterGenerator. The Handler
|
||||
// template is a class storing fields/methods that are interpreter or compiler
|
||||
// specific. This can be combined with template specialization of methods in
|
||||
// this class to specialize behavior.
|
||||
template <typename Handler>
|
||||
class BaselineCodeGen
|
||||
{
|
||||
protected:
|
||||
Handler handler;
|
||||
|
||||
JSContext* cx;
|
||||
JSScript* script;
|
||||
jsbytecode* pc;
|
||||
@ -263,20 +271,11 @@ class BaselineCompiler final
|
||||
FrameInfo frame;
|
||||
|
||||
js::Vector<RetAddrEntry, 16, SystemAllocPolicy> retAddrEntries_;
|
||||
js::Vector<CodeOffset> traceLoggerToggleOffsets_;
|
||||
|
||||
// Stores the native code offset for a bytecode pc.
|
||||
struct PCMappingEntry
|
||||
{
|
||||
uint32_t pcOffset;
|
||||
uint32_t nativeOffset;
|
||||
PCMappingSlotInfo slotInfo;
|
||||
|
||||
// If set, insert a PCMappingIndexEntry before encoding the
|
||||
// current entry.
|
||||
bool addIndexEntry;
|
||||
};
|
||||
|
||||
js::Vector<PCMappingEntry, 16, SystemAllocPolicy> pcMappingEntries_;
|
||||
FixedList<Label> labels_;
|
||||
NonAssertingLabel return_;
|
||||
NonAssertingLabel postBarrierSlot_;
|
||||
|
||||
// Index of the current ICEntry in the script's ICScript.
|
||||
uint32_t icEntryIndex_;
|
||||
@ -286,54 +285,15 @@ class BaselineCompiler final
|
||||
bool inCall_;
|
||||
#endif
|
||||
|
||||
CodeOffset profilerPushToggleOffset_;
|
||||
CodeOffset profilerEnterFrameToggleOffset_;
|
||||
CodeOffset profilerExitFrameToggleOffset_;
|
||||
|
||||
Vector<CodeOffset> traceLoggerToggleOffsets_;
|
||||
CodeOffset traceLoggerScriptTextIdOffset_;
|
||||
|
||||
FixedList<Label> labels_;
|
||||
NonAssertingLabel return_;
|
||||
NonAssertingLabel postBarrierSlot_;
|
||||
|
||||
// Early Ion bailouts will enter at this address. This is after frame
|
||||
// construction and before environment chain is initialized.
|
||||
CodeOffset bailoutPrologueOffset_;
|
||||
|
||||
// Baseline Debug OSR during prologue will enter at this address. This is
|
||||
// right after where a debug prologue VM call would have returned.
|
||||
CodeOffset debugOsrPrologueOffset_;
|
||||
|
||||
// Baseline Debug OSR during epilogue will enter at this address. This is
|
||||
// right after where a debug epilogue VM call would have returned.
|
||||
CodeOffset debugOsrEpilogueOffset_;
|
||||
|
||||
// Whether any on stack arguments are modified.
|
||||
bool modifiesArguments_;
|
||||
|
||||
BaselineCodeGen(JSContext* cx, TempAllocator& alloc, JSScript* script);
|
||||
|
||||
Label* labelOf(jsbytecode* pc) {
|
||||
return &labels_[script->pcToOffset(pc)];
|
||||
}
|
||||
|
||||
// If a script has more |nslots| than this, then emit code to do an
|
||||
// early stack check.
|
||||
static const unsigned EARLY_STACK_CHECK_SLOT_COUNT = 128;
|
||||
bool needsEarlyStackCheck() const {
|
||||
return script->nslots() > EARLY_STACK_CHECK_SLOT_COUNT;
|
||||
}
|
||||
|
||||
public:
|
||||
BaselineCompiler(JSContext* cx, TempAllocator& alloc, JSScript* script);
|
||||
MOZ_MUST_USE bool init();
|
||||
|
||||
MethodStatus compile();
|
||||
|
||||
void setCompileDebugInstrumentation() {
|
||||
compileDebugInstrumentation_ = true;
|
||||
}
|
||||
|
||||
private:
|
||||
MOZ_MUST_USE bool appendRetAddrEntry(RetAddrEntry::Kind kind, uint32_t retOffset) {
|
||||
if (!retAddrEntries_.emplaceBack(script->pcToOffset(pc), kind, CodeOffset(retOffset))) {
|
||||
ReportOutOfMemory(cx);
|
||||
@ -352,20 +312,6 @@ class BaselineCompiler final
|
||||
return script->module();
|
||||
}
|
||||
|
||||
PCMappingSlotInfo getStackTopSlotInfo() {
|
||||
MOZ_ASSERT(frame.numUnsyncedSlots() <= 2);
|
||||
switch (frame.numUnsyncedSlots()) {
|
||||
case 0:
|
||||
return PCMappingSlotInfo::MakeSlotInfo();
|
||||
case 1:
|
||||
return PCMappingSlotInfo::MakeSlotInfo(PCMappingSlotInfo::ToSlotLocation(frame.peek(-1)));
|
||||
case 2:
|
||||
default:
|
||||
return PCMappingSlotInfo::MakeSlotInfo(PCMappingSlotInfo::ToSlotLocation(frame.peek(-1)),
|
||||
PCMappingSlotInfo::ToSlotLocation(frame.peek(-2)));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void pushArg(const T& t) {
|
||||
masm.Push(t);
|
||||
@ -386,36 +332,14 @@ class BaselineCompiler final
|
||||
return true;
|
||||
}
|
||||
|
||||
BytecodeAnalysis& analysis() {
|
||||
return analysis_;
|
||||
}
|
||||
|
||||
MethodStatus emitBody();
|
||||
|
||||
MOZ_MUST_USE bool emitCheckThis(ValueOperand val, bool reinit=false);
|
||||
void emitLoadReturnValue(ValueOperand val);
|
||||
|
||||
void emitInitializeLocals();
|
||||
MOZ_MUST_USE bool emitPrologue();
|
||||
MOZ_MUST_USE bool emitEpilogue();
|
||||
MOZ_MUST_USE bool emitOutOfLinePostBarrierSlot();
|
||||
MOZ_MUST_USE bool emitNextIC();
|
||||
MOZ_MUST_USE bool emitStackCheck();
|
||||
MOZ_MUST_USE bool emitInterruptCheck();
|
||||
MOZ_MUST_USE bool emitWarmUpCounterIncrement(bool allowOsr=true);
|
||||
MOZ_MUST_USE bool emitArgumentTypeChecks();
|
||||
void emitIsDebuggeeCheck();
|
||||
MOZ_MUST_USE bool emitDebugPrologue();
|
||||
MOZ_MUST_USE bool emitDebugTrap();
|
||||
MOZ_MUST_USE bool emitTraceLoggerEnter();
|
||||
MOZ_MUST_USE bool emitTraceLoggerExit();
|
||||
MOZ_MUST_USE bool emitTraceLoggerResume(Register script, AllocatableGeneralRegisterSet& regs);
|
||||
|
||||
void emitProfilerEnterFrame();
|
||||
void emitProfilerExitFrame();
|
||||
|
||||
MOZ_MUST_USE bool initEnvironmentChain();
|
||||
|
||||
void storeValue(const StackValue* source, const Address& dest,
|
||||
const ValueOperand& scratch);
|
||||
|
||||
@ -450,8 +374,6 @@ class BaselineCompiler final
|
||||
|
||||
MOZ_MUST_USE bool emitIsMagicValue();
|
||||
|
||||
MOZ_MUST_USE bool addPCMappingEntry(bool addIndexEntry);
|
||||
|
||||
void getEnvironmentCoordinateObject(Register reg);
|
||||
Address getEnvironmentCoordinateAddressFromObject(Register objReg, Register reg);
|
||||
Address getEnvironmentCoordinateAddress(Register reg);
|
||||
@ -459,6 +381,115 @@ class BaselineCompiler final
|
||||
void getThisEnvironmentCallee(Register reg);
|
||||
};
|
||||
|
||||
// Interface used by BaselineCodeGen for BaselineCompiler.
|
||||
class BaselineCompilerHandler
|
||||
{
|
||||
public:
|
||||
};
|
||||
|
||||
class BaselineCompiler final : private BaselineCodeGen<BaselineCompilerHandler>
|
||||
{
|
||||
// Stores the native code offset for a bytecode pc.
|
||||
struct PCMappingEntry
|
||||
{
|
||||
uint32_t pcOffset;
|
||||
uint32_t nativeOffset;
|
||||
PCMappingSlotInfo slotInfo;
|
||||
|
||||
// If set, insert a PCMappingIndexEntry before encoding the
|
||||
// current entry.
|
||||
bool addIndexEntry;
|
||||
};
|
||||
|
||||
js::Vector<PCMappingEntry, 16, SystemAllocPolicy> pcMappingEntries_;
|
||||
|
||||
CodeOffset profilerPushToggleOffset_;
|
||||
CodeOffset profilerEnterFrameToggleOffset_;
|
||||
CodeOffset profilerExitFrameToggleOffset_;
|
||||
|
||||
CodeOffset traceLoggerScriptTextIdOffset_;
|
||||
|
||||
// Early Ion bailouts will enter at this address. This is after frame
|
||||
// construction and before environment chain is initialized.
|
||||
CodeOffset bailoutPrologueOffset_;
|
||||
|
||||
// Baseline Debug OSR during prologue will enter at this address. This is
|
||||
// right after where a debug prologue VM call would have returned.
|
||||
CodeOffset debugOsrPrologueOffset_;
|
||||
|
||||
// Baseline Debug OSR during epilogue will enter at this address. This is
|
||||
// right after where a debug epilogue VM call would have returned.
|
||||
CodeOffset debugOsrEpilogueOffset_;
|
||||
|
||||
// If a script has more |nslots| than this, then emit code to do an
|
||||
// early stack check.
|
||||
static const unsigned EARLY_STACK_CHECK_SLOT_COUNT = 128;
|
||||
bool needsEarlyStackCheck() const {
|
||||
return script->nslots() > EARLY_STACK_CHECK_SLOT_COUNT;
|
||||
}
|
||||
|
||||
public:
|
||||
BaselineCompiler(JSContext* cx, TempAllocator& alloc, JSScript* script);
|
||||
MOZ_MUST_USE bool init();
|
||||
|
||||
MethodStatus compile();
|
||||
|
||||
void setCompileDebugInstrumentation() {
|
||||
compileDebugInstrumentation_ = true;
|
||||
}
|
||||
|
||||
private:
|
||||
PCMappingSlotInfo getStackTopSlotInfo() {
|
||||
MOZ_ASSERT(frame.numUnsyncedSlots() <= 2);
|
||||
switch (frame.numUnsyncedSlots()) {
|
||||
case 0:
|
||||
return PCMappingSlotInfo::MakeSlotInfo();
|
||||
case 1:
|
||||
return PCMappingSlotInfo::MakeSlotInfo(PCMappingSlotInfo::ToSlotLocation(frame.peek(-1)));
|
||||
case 2:
|
||||
default:
|
||||
return PCMappingSlotInfo::MakeSlotInfo(PCMappingSlotInfo::ToSlotLocation(frame.peek(-1)),
|
||||
PCMappingSlotInfo::ToSlotLocation(frame.peek(-2)));
|
||||
}
|
||||
}
|
||||
|
||||
BytecodeAnalysis& analysis() {
|
||||
return analysis_;
|
||||
}
|
||||
|
||||
MethodStatus emitBody();
|
||||
|
||||
void emitInitializeLocals();
|
||||
MOZ_MUST_USE bool emitPrologue();
|
||||
MOZ_MUST_USE bool emitEpilogue();
|
||||
MOZ_MUST_USE bool emitOutOfLinePostBarrierSlot();
|
||||
MOZ_MUST_USE bool emitStackCheck();
|
||||
MOZ_MUST_USE bool emitArgumentTypeChecks();
|
||||
void emitIsDebuggeeCheck();
|
||||
MOZ_MUST_USE bool emitDebugPrologue();
|
||||
MOZ_MUST_USE bool emitDebugTrap();
|
||||
MOZ_MUST_USE bool emitTraceLoggerEnter();
|
||||
MOZ_MUST_USE bool emitTraceLoggerExit();
|
||||
|
||||
void emitProfilerEnterFrame();
|
||||
void emitProfilerExitFrame();
|
||||
|
||||
MOZ_MUST_USE bool initEnvironmentChain();
|
||||
|
||||
MOZ_MUST_USE bool addPCMappingEntry(bool addIndexEntry);
|
||||
};
|
||||
|
||||
// Interface used by BaselineCodeGen for BaselineInterpreterGenerator.
|
||||
class BaselineInterpreterHandler
|
||||
{
|
||||
public:
|
||||
};
|
||||
|
||||
class BaselineInterpreterGenerator final : private BaselineCodeGen<BaselineInterpreterHandler>
|
||||
{
|
||||
public:
|
||||
};
|
||||
|
||||
extern const VMFunction NewArrayCopyOnWriteInfo;
|
||||
extern const VMFunction ImplicitThisInfo;
|
||||
|
||||
|
@ -1644,10 +1644,12 @@ ObjectGroup::getOrFixupCopyOnWriteObject(JSContext* cx, HandleScript script, jsb
|
||||
RootedArrayObject obj(cx, &script->getObject(GET_UINT32_INDEX(pc))->as<ArrayObject>());
|
||||
MOZ_ASSERT(obj->denseElementsAreCopyOnWrite());
|
||||
|
||||
AutoSweepObjectGroup sweepObjGroup(obj->group());
|
||||
if (obj->group()->fromAllocationSite(sweepObjGroup)) {
|
||||
MOZ_ASSERT(obj->group()->hasAnyFlags(sweepObjGroup, OBJECT_FLAG_COPY_ON_WRITE));
|
||||
return obj;
|
||||
{
|
||||
AutoSweepObjectGroup sweepObjGroup(obj->group());
|
||||
if (obj->group()->fromAllocationSite(sweepObjGroup)) {
|
||||
MOZ_ASSERT(obj->group()->hasAnyFlags(sweepObjGroup, OBJECT_FLAG_COPY_ON_WRITE));
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
RootedObjectGroup group(cx, allocationSiteGroup(cx, script, pc, JSProto_Array));
|
||||
|
Loading…
Reference in New Issue
Block a user