Bug 1636059 part 2 - Use template objects for NewArray and NewObject. r=iain

Differential Revision: https://phabricator.services.mozilla.com/D74219
This commit is contained in:
Jan de Mooij 2020-05-08 07:41:35 +00:00
Родитель c99b9e79e5
Коммит 709d51cfa3
7 изменённых файлов: 135 добавлений и 14 удалений

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

@ -7032,6 +7032,12 @@ void CodeGenerator::visitNewArray(LNewArray* lir) {
if (lir->mir()->convertDoubleElements()) {
templateObject.setConvertDoubleElements();
}
#ifdef DEBUG
size_t numInlineElements = gc::GetGCKindSlots(templateObject.getAllocKind()) -
ObjectElements::VALUES_PER_HEADER;
MOZ_ASSERT(length <= numInlineElements,
"Inline allocation only supports inline elements");
#endif
masm.createGCObject(objReg, tempReg, templateObject,
lir->mir()->initialHeap(), ool->entry());

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

@ -4766,7 +4766,7 @@ MNewArray::MNewArray(TempAllocator& alloc, CompilerConstraintList* constraints,
pc_(pc),
vmCall_(vmCall) {
setResultType(MIRType::Object);
if (templateObject()) {
if (templateObject() && !JitOptions.warpBuilder) {
if (TemporaryTypeSet* types =
MakeSingletonTypeSet(alloc, constraints, templateObject())) {
setResultTypeSet(types);

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

@ -2303,7 +2303,8 @@ class MNewObject : public MUnaryInstruction, public NoTypePolicy::Data {
MOZ_ASSERT_IF(mode != ObjectLiteral, templateObject());
setResultType(MIRType::Object);
if (JSObject* obj = templateObject()) {
JSObject* obj = templateObject();
if (obj && !JitOptions.warpBuilder) {
setResultTypeSet(MakeSingletonTypeSet(alloc, constraints, obj));
}

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

@ -2100,12 +2100,27 @@ bool WarpBuilder::build_CallSiteObj(BytecodeLocation loc) {
bool WarpBuilder::build_NewArray(BytecodeLocation loc) {
uint32_t length = loc.getNewArrayLength();
// TODO: support fast inline allocation, pre-tenuring.
// TODO: support pre-tenuring.
gc::InitialHeap heap = gc::DefaultHeap;
MConstant* templateConst = constant(NullValue());
auto* ins = MNewArray::NewVM(alloc(), /* constraints = */ nullptr, length,
MConstant* templateConst;
bool useVMCall;
if (const auto* snapshot = getOpSnapshot<WarpNewArray>(loc)) {
templateConst = constant(ObjectValue(*snapshot->templateObject()));
useVMCall = snapshot->useVMCall();
} else {
templateConst = constant(NullValue());
useVMCall = true;
}
MNewArray* ins;
if (useVMCall) {
ins = MNewArray::NewVM(alloc(), /* constraints = */ nullptr, length,
templateConst, heap, loc.toRawBytecode());
} else {
ins = MNewArray::New(alloc(), /* constraints = */ nullptr, length,
templateConst, heap, loc.toRawBytecode());
}
current->add(ins);
current->push(ins);
return true;
@ -2130,12 +2145,19 @@ bool WarpBuilder::build_NewArrayCopyOnWrite(BytecodeLocation loc) {
}
bool WarpBuilder::build_NewObject(BytecodeLocation loc) {
// TODO: support fast inline allocation, pre-tenuring.
// TODO: support pre-tenuring.
gc::InitialHeap heap = gc::DefaultHeap;
MConstant* templateConst = constant(NullValue());
auto* ins = MNewObject::NewVM(alloc(), /* constraints = */ nullptr,
templateConst, heap, MNewObject::ObjectLiteral);
MNewObject* ins;
if (const auto* snapshot = getOpSnapshot<WarpNewObject>(loc)) {
auto* templateConst = constant(ObjectValue(*snapshot->templateObject()));
ins = MNewObject::New(alloc(), /* constraints = */ nullptr, templateConst,
heap, MNewObject::ObjectLiteral);
} else {
auto* templateConst = constant(NullValue());
ins = MNewObject::NewVM(alloc(), /* constraints = */ nullptr, templateConst,
heap, MNewObject::ObjectLiteral);
}
current->add(ins);
current->push(ins);
return resumeAfter(ins, loc);

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

@ -387,6 +387,39 @@ AbortReasonOr<WarpScriptSnapshot*> WarpOracle::createScriptSnapshot(
break;
}
case JSOp::NewArray: {
// TODO: optimize ICEntry lookup.
const ICEntry& entry = script->jitScript()->icEntryFromPCOffset(offset);
auto* stub = entry.fallbackStub()->toNewArray_Fallback();
if (ArrayObject* templateObj = stub->templateObject()) {
// Only inline elements are supported without a VM call.
size_t numInlineElements =
gc::GetGCKindSlots(templateObj->asTenured().getAllocKind()) -
ObjectElements::VALUES_PER_HEADER;
bool useVMCall = loc.getNewArrayLength() > numInlineElements;
if (!AddOpSnapshot<WarpNewArray>(alloc_, opSnapshots, offset,
templateObj, useVMCall)) {
return abort(AbortReason::Alloc);
}
}
break;
}
case JSOp::NewObject:
case JSOp::NewObjectWithGroup:
case JSOp::NewInit: {
// TODO: optimize ICEntry lookup.
const ICEntry& entry = script->jitScript()->icEntryFromPCOffset(offset);
auto* stub = entry.fallbackStub()->toNewObject_Fallback();
if (JSObject* templateObj = stub->templateObject()) {
if (!AddOpSnapshot<WarpNewObject>(alloc_, opSnapshots, offset,
templateObj)) {
return abort(AbortReason::Alloc);
}
}
break;
}
case JSOp::GetName:
case JSOp::GetGName:
case JSOp::GetProp:
@ -547,10 +580,6 @@ AbortReasonOr<WarpScriptSnapshot*> WarpOracle::createScriptSnapshot(
case JSOp::InitHomeObject:
case JSOp::SuperBase:
case JSOp::SuperFun:
case JSOp::NewArray:
case JSOp::NewObject:
case JSOp::NewObjectWithGroup:
case JSOp::NewInit:
case JSOp::InitPropGetter:
case JSOp::InitPropSetter:
case JSOp::InitHiddenPropGetter:

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

@ -143,6 +143,15 @@ void WarpRest::dumpData(GenericPrinter& out) const {
out.printf(" template: 0x%p\n", templateObject());
}
void WarpNewArray::dumpData(GenericPrinter& out) const {
out.printf(" template: 0x%p\n", templateObject());
out.printf(" useVMCall: %u\n", useVMCall());
}
void WarpNewObject::dumpData(GenericPrinter& out) const {
out.printf(" template: 0x%p\n", templateObject());
}
void WarpCacheIR::dumpData(GenericPrinter& out) const {
out.printf(" stubCode: 0x%p\n", static_cast<JitCode*>(stubCode_));
out.printf(" stubInfo: 0x%p\n", stubInfo_);
@ -241,6 +250,14 @@ void WarpRest::traceData(JSTracer* trc) {
TraceWarpGCPtr(trc, templateObject_, "warp-rest-template");
}
void WarpNewArray::traceData(JSTracer* trc) {
TraceWarpGCPtr(trc, templateObject_, "warp-newarray-template");
}
void WarpNewObject::traceData(JSTracer* trc) {
TraceWarpGCPtr(trc, templateObject_, "warp-newobject-template");
}
void WarpCacheIR::traceData(JSTracer* trc) {
TraceWarpGCPtr(trc, stubCode_, "warp-stub-code");
// TODO: trace pointers in stub data.

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

@ -32,6 +32,8 @@ class CacheIRStubInfo;
_(WarpGetImport) \
_(WarpLambda) \
_(WarpRest) \
_(WarpNewArray) \
_(WarpNewObject) \
_(WarpCacheIR)
// Wrapper for GC things stored in WarpSnapshot. Asserts the GC pointer is not
@ -262,6 +264,7 @@ class WarpCacheIR : public WarpOpSnapshot {
#endif
};
// Template object for JSOp::Rest.
class WarpRest : public WarpOpSnapshot {
WarpGCPtr<ArrayObject*> templateObject_;
@ -270,6 +273,7 @@ class WarpRest : public WarpOpSnapshot {
WarpRest(uint32_t offset, ArrayObject* templateObject)
: WarpOpSnapshot(ThisKind, offset), templateObject_(templateObject) {}
ArrayObject* templateObject() const { return templateObject_; }
void traceData(JSTracer* trc);
@ -279,6 +283,48 @@ class WarpRest : public WarpOpSnapshot {
#endif
};
// Template object for JSOp::NewArray.
class WarpNewArray : public WarpOpSnapshot {
WarpGCPtr<ArrayObject*> templateObject_;
bool useVMCall_;
public:
static constexpr Kind ThisKind = Kind::WarpNewArray;
WarpNewArray(uint32_t offset, ArrayObject* templateObject, bool useVMCall)
: WarpOpSnapshot(ThisKind, offset),
templateObject_(templateObject),
useVMCall_(useVMCall) {}
ArrayObject* templateObject() const { return templateObject_; }
bool useVMCall() const { return useVMCall_; }
void traceData(JSTracer* trc);
#ifdef JS_JITSPEW
void dumpData(GenericPrinter& out) const;
#endif
};
// Template object for JSOp::NewObject, JSOp::NewInit, JSOp::NewObjectWithGroup.
class WarpNewObject : public WarpOpSnapshot {
WarpGCPtr<JSObject*> templateObject_;
public:
static constexpr Kind ThisKind = Kind::WarpNewObject;
WarpNewObject(uint32_t offset, JSObject* templateObject)
: WarpOpSnapshot(ThisKind, offset), templateObject_(templateObject) {}
JSObject* templateObject() const { return templateObject_; }
void traceData(JSTracer* trc);
#ifdef JS_JITSPEW
void dumpData(GenericPrinter& out) const;
#endif
};
struct NoEnvironment {};
using ConstantObjectEnvironment = WarpGCPtr<JSObject*>;
struct FunctionEnvironment {