зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
c99b9e79e5
Коммит
709d51cfa3
|
@ -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 {
|
||||
|
|
Загрузка…
Ссылка в новой задаче