mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-04 07:40:42 +00:00
Bug 1266180 - Port unboxed object getprop stub to CacheIR. r=efaust
This commit is contained in:
parent
b21b1c955b
commit
6e76c672f2
@ -843,6 +843,26 @@ BaselineCacheIRCompiler::emitLoadDynamicSlotResult()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BaselineCacheIRCompiler::emitLoadUnboxedPropertyResult()
|
||||
{
|
||||
Register obj = allocator.useRegister(masm, reader.objOperandId());
|
||||
AutoScratchRegister scratch(allocator, masm);
|
||||
|
||||
JSValueType fieldType = reader.valueType();
|
||||
|
||||
Address fieldOffset(stubAddress(reader.stubOffset()));
|
||||
masm.load32(fieldOffset, scratch);
|
||||
masm.loadUnboxedProperty(BaseIndex(obj, scratch, TimesOne), fieldType, R0);
|
||||
|
||||
if (fieldType == JSVAL_TYPE_OBJECT)
|
||||
emitEnterTypeMonitorIC();
|
||||
else
|
||||
emitReturnFromIC();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BaselineCacheIRCompiler::emitLoadUndefinedResult()
|
||||
{
|
||||
|
@ -108,8 +108,6 @@ AddReceiver(const ReceiverGuard& receiver,
|
||||
static bool
|
||||
GetCacheIRReceiverForNativeReadSlot(ICCacheIR_Monitored* stub, ReceiverGuard* receiver)
|
||||
{
|
||||
// If this is a getprop stub to get an own object's read-slot stub.
|
||||
//
|
||||
// We match either:
|
||||
//
|
||||
// GuardIsObject 0
|
||||
@ -125,6 +123,7 @@ GetCacheIRReceiverForNativeReadSlot(ICCacheIR_Monitored* stub, ReceiverGuard* re
|
||||
// LoadUnboxedExpando 0
|
||||
// LoadFixedSlotResult or LoadDynamicSlotResult
|
||||
|
||||
*receiver = ReceiverGuard();
|
||||
CacheIRReader reader(stub->stubInfo());
|
||||
|
||||
ObjOperandId objId = ObjOperandId(0);
|
||||
@ -154,6 +153,29 @@ GetCacheIRReceiverForNativeReadSlot(ICCacheIR_Monitored* stub, ReceiverGuard* re
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
GetCacheIRReceiverForUnboxedProperty(ICCacheIR_Monitored* stub, ReceiverGuard* receiver)
|
||||
{
|
||||
// We match:
|
||||
//
|
||||
// GuardIsObject 0
|
||||
// GuardGroup 0
|
||||
// LoadUnboxedPropertyResult 0 ..
|
||||
|
||||
*receiver = ReceiverGuard();
|
||||
CacheIRReader reader(stub->stubInfo());
|
||||
|
||||
ObjOperandId objId = ObjOperandId(0);
|
||||
if (!reader.matchOp(CacheOp::GuardIsObject, objId))
|
||||
return false;
|
||||
|
||||
if (!reader.matchOp(CacheOp::GuardGroup, objId))
|
||||
return false;
|
||||
receiver->group = stub->stubInfo()->getStubField<ObjectGroup*>(stub, reader.stubOffset());
|
||||
|
||||
return reader.matchOp(CacheOp::LoadUnboxedPropertyResult, objId);
|
||||
}
|
||||
|
||||
bool
|
||||
BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receivers,
|
||||
ObjectGroupVector& convertUnboxedGroups)
|
||||
@ -176,15 +198,15 @@ BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receiv
|
||||
while (stub->next()) {
|
||||
ReceiverGuard receiver;
|
||||
if (stub->isCacheIR_Monitored()) {
|
||||
if (!GetCacheIRReceiverForNativeReadSlot(stub->toCacheIR_Monitored(), &receiver)) {
|
||||
if (!GetCacheIRReceiverForNativeReadSlot(stub->toCacheIR_Monitored(), &receiver) &&
|
||||
!GetCacheIRReceiverForUnboxedProperty(stub->toCacheIR_Monitored(), &receiver))
|
||||
{
|
||||
receivers.clear();
|
||||
return true;
|
||||
}
|
||||
} else if (stub->isSetProp_Native()) {
|
||||
receiver = ReceiverGuard(stub->toSetProp_Native()->group(),
|
||||
stub->toSetProp_Native()->shape());
|
||||
} else if (stub->isGetProp_Unboxed()) {
|
||||
receiver = ReceiverGuard(stub->toGetProp_Unboxed()->group(), nullptr);
|
||||
} else if (stub->isSetProp_Unboxed()) {
|
||||
receiver = ReceiverGuard(stub->toSetProp_Unboxed()->group(), nullptr);
|
||||
} else {
|
||||
@ -805,7 +827,6 @@ BaselineInspector::expectedPropertyAccessInputType(jsbytecode* pc)
|
||||
// Either an object or magic arguments.
|
||||
return MIRType::Value;
|
||||
|
||||
case ICStub::GetProp_Unboxed:
|
||||
case ICStub::GetProp_TypedObject:
|
||||
case ICStub::GetProp_CallScripted:
|
||||
case ICStub::GetProp_CallNative:
|
||||
|
@ -60,6 +60,8 @@ GetPropIRGenerator::tryAttachStub(Maybe<CacheIRWriter>& writer)
|
||||
return false;
|
||||
if (!emitted_ && !tryAttachNative(*writer, obj, objId))
|
||||
return false;
|
||||
if (!emitted_ && !tryAttachUnboxed(*writer, obj, objId))
|
||||
return false;
|
||||
if (!emitted_ && !tryAttachUnboxedExpando(*writer, obj, objId))
|
||||
return false;
|
||||
if (!emitted_ && !tryAttachModuleNamespace(*writer, obj, objId))
|
||||
@ -257,6 +259,29 @@ GetPropIRGenerator::tryAttachNative(CacheIRWriter& writer, HandleObject obj, Obj
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GetPropIRGenerator::tryAttachUnboxed(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId)
|
||||
{
|
||||
MOZ_ASSERT(!emitted_);
|
||||
|
||||
if (!obj->is<UnboxedPlainObject>())
|
||||
return true;
|
||||
|
||||
const UnboxedLayout::Property* property = obj->as<UnboxedPlainObject>().layout().lookup(name_);
|
||||
if (!property)
|
||||
return true;
|
||||
|
||||
if (!cx_->runtime()->jitSupportsFloatingPoint)
|
||||
return true;
|
||||
|
||||
writer.guardGroup(objId, obj->group());
|
||||
writer.loadUnboxedPropertyResult(objId, property->type,
|
||||
UnboxedPlainObject::offsetOfData() + property->offset);
|
||||
emitted_ = true;
|
||||
preliminaryObjectAction_ = PreliminaryObjectAction::Unlink;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GetPropIRGenerator::tryAttachUnboxedExpando(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId)
|
||||
{
|
||||
|
@ -91,6 +91,7 @@ class ObjOperandId : public OperandId
|
||||
_(LoadUnboxedExpando) \
|
||||
_(LoadFixedSlotResult) \
|
||||
_(LoadDynamicSlotResult) \
|
||||
_(LoadUnboxedPropertyResult) \
|
||||
_(LoadInt32ArrayLengthResult) \
|
||||
_(LoadUnboxedArrayLengthResult) \
|
||||
_(LoadArgumentsObjectLengthResult) \
|
||||
@ -304,6 +305,11 @@ class MOZ_RAII CacheIRWriter
|
||||
writeOpWithOperandId(CacheOp::LoadDynamicSlotResult, obj);
|
||||
addStubWord(offset, StubField::GCType::NoGCThing);
|
||||
}
|
||||
void loadUnboxedPropertyResult(ObjOperandId obj, JSValueType type, size_t offset) {
|
||||
writeOpWithOperandId(CacheOp::LoadUnboxedPropertyResult, obj);
|
||||
buffer_.writeByte(uint32_t(type));
|
||||
addStubWord(offset, StubField::GCType::NoGCThing);
|
||||
}
|
||||
void loadInt32ArrayLengthResult(ObjOperandId obj) {
|
||||
writeOpWithOperandId(CacheOp::LoadInt32ArrayLengthResult, obj);
|
||||
}
|
||||
@ -349,6 +355,7 @@ class MOZ_RAII CacheIRReader
|
||||
|
||||
uint32_t stubOffset() { return buffer_.readByte(); }
|
||||
GuardClassKind guardClassKind() { return GuardClassKind(buffer_.readByte()); }
|
||||
JSValueType valueType() { return JSValueType(buffer_.readByte()); }
|
||||
|
||||
bool matchOp(CacheOp op) {
|
||||
const uint8_t* pos = buffer_.currentPosition();
|
||||
@ -388,6 +395,7 @@ class MOZ_RAII GetPropIRGenerator
|
||||
PreliminaryObjectAction preliminaryObjectAction_;
|
||||
|
||||
bool tryAttachNative(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId);
|
||||
bool tryAttachUnboxed(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId);
|
||||
bool tryAttachUnboxedExpando(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId);
|
||||
bool tryAttachObjectLength(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId);
|
||||
bool tryAttachModuleNamespace(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId);
|
||||
|
@ -404,11 +404,6 @@ ICStub::trace(JSTracer* trc)
|
||||
TraceEdge(trc, &propStub->protoShape(), "baseline-getprop-primitive-stub-shape");
|
||||
break;
|
||||
}
|
||||
case ICStub::GetProp_Unboxed: {
|
||||
ICGetProp_Unboxed* propStub = toGetProp_Unboxed();
|
||||
TraceEdge(trc, &propStub->group(), "baseline-getprop-unboxed-stub-group");
|
||||
break;
|
||||
}
|
||||
case ICStub::GetProp_TypedObject: {
|
||||
ICGetProp_TypedObject* propStub = toGetProp_TypedObject();
|
||||
TraceEdge(trc, &propStub->shape(), "baseline-getprop-typedobject-stub-shape");
|
||||
@ -2554,40 +2549,6 @@ TryAttachNativeGetAccessorPropStub(JSContext* cx, SharedStubInfo* info,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
TryAttachUnboxedGetPropStub(JSContext* cx, SharedStubInfo* info,
|
||||
ICGetProp_Fallback* stub, HandlePropertyName name,
|
||||
HandleValue val, bool* attached)
|
||||
{
|
||||
MOZ_ASSERT(!*attached);
|
||||
|
||||
if (!cx->runtime()->jitSupportsFloatingPoint)
|
||||
return true;
|
||||
|
||||
if (!val.isObject() || !val.toObject().is<UnboxedPlainObject>())
|
||||
return true;
|
||||
Rooted<UnboxedPlainObject*> obj(cx, &val.toObject().as<UnboxedPlainObject>());
|
||||
|
||||
const UnboxedLayout::Property* property = obj->layout().lookup(name);
|
||||
if (!property)
|
||||
return true;
|
||||
|
||||
ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
|
||||
|
||||
ICGetProp_Unboxed::Compiler compiler(cx, info->engine(), monitorStub, obj->group(),
|
||||
property->offset + UnboxedPlainObject::offsetOfData(),
|
||||
property->type);
|
||||
ICStub* newStub = compiler.getStub(compiler.getStubSpace(info->outerScript(cx)));
|
||||
if (!newStub)
|
||||
return false;
|
||||
stub->addNewStub(newStub);
|
||||
|
||||
StripPreliminaryObjectStubs(cx, stub);
|
||||
|
||||
*attached = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
TryAttachTypedObjectGetPropStub(JSContext* cx, SharedStubInfo* info,
|
||||
ICGetProp_Fallback* stub, HandlePropertyName name,
|
||||
@ -2861,11 +2822,6 @@ DoGetPropFallback(JSContext* cx, void* payload, ICGetProp_Fallback* stub_,
|
||||
return true;
|
||||
|
||||
|
||||
if (!TryAttachUnboxedGetPropStub(cx, &info, stub, name, val, &attached))
|
||||
return false;
|
||||
if (attached)
|
||||
return true;
|
||||
|
||||
if (!TryAttachTypedObjectGetPropStub(cx, &info, stub, name, val, &attached))
|
||||
return false;
|
||||
if (attached)
|
||||
@ -3754,39 +3710,6 @@ ICGetProp_Generic::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ICGetProp_Unboxed::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
{
|
||||
Label failure;
|
||||
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
|
||||
Register scratch = regs.takeAnyExcluding(ICTailCallReg);
|
||||
|
||||
// Object and group guard.
|
||||
masm.branchTestObject(Assembler::NotEqual, R0, &failure);
|
||||
Register object = masm.extractObject(R0, ExtractTemp0);
|
||||
masm.loadPtr(Address(ICStubReg, ICGetProp_Unboxed::offsetOfGroup()), scratch);
|
||||
masm.branchPtr(Assembler::NotEqual, Address(object, JSObject::offsetOfGroup()), scratch,
|
||||
&failure);
|
||||
|
||||
// Get the address being read from.
|
||||
masm.load32(Address(ICStubReg, ICGetProp_Unboxed::offsetOfFieldOffset()), scratch);
|
||||
|
||||
masm.loadUnboxedProperty(BaseIndex(object, scratch, TimesOne), fieldType_, TypedOrValueRegister(R0));
|
||||
|
||||
// Only monitor the result if its type might change.
|
||||
if (fieldType_ == JSVAL_TYPE_OBJECT)
|
||||
EmitEnterTypeMonitorIC(masm);
|
||||
else
|
||||
EmitReturnFromIC(masm);
|
||||
|
||||
masm.bind(&failure);
|
||||
EmitStubGuardFailure(masm);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CheckForTypedObjectWithDetachedStorage(JSContext* cx, MacroAssembler& masm, Label* failure)
|
||||
{
|
||||
|
@ -2595,65 +2595,6 @@ class ICGetPropNativeCompiler : public ICStubCompiler
|
||||
ICGetPropNativeStub* getStub(ICStubSpace* space);
|
||||
};
|
||||
|
||||
class ICGetProp_Unboxed : public ICMonitoredStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
HeapPtrObjectGroup group_;
|
||||
uint32_t fieldOffset_;
|
||||
|
||||
ICGetProp_Unboxed(JitCode* stubCode, ICStub* firstMonitorStub, ObjectGroup* group,
|
||||
uint32_t fieldOffset)
|
||||
: ICMonitoredStub(ICStub::GetProp_Unboxed, stubCode, firstMonitorStub),
|
||||
group_(group), fieldOffset_(fieldOffset)
|
||||
{
|
||||
(void) fieldOffset_; // Silence clang warning
|
||||
}
|
||||
|
||||
public:
|
||||
HeapPtrObjectGroup& group() {
|
||||
return group_;
|
||||
}
|
||||
|
||||
static size_t offsetOfGroup() {
|
||||
return offsetof(ICGetProp_Unboxed, group_);
|
||||
}
|
||||
static size_t offsetOfFieldOffset() {
|
||||
return offsetof(ICGetProp_Unboxed, fieldOffset_);
|
||||
}
|
||||
|
||||
class Compiler : public ICStubCompiler {
|
||||
protected:
|
||||
ICStub* firstMonitorStub_;
|
||||
RootedObjectGroup group_;
|
||||
uint32_t fieldOffset_;
|
||||
JSValueType fieldType_;
|
||||
|
||||
bool generateStubCode(MacroAssembler& masm);
|
||||
|
||||
virtual int32_t getKey() const {
|
||||
return static_cast<int32_t>(engine_) |
|
||||
(static_cast<int32_t>(kind) << 1) |
|
||||
(static_cast<int32_t>(fieldType_) << 17);
|
||||
}
|
||||
|
||||
public:
|
||||
Compiler(JSContext* cx, Engine engine, ICStub* firstMonitorStub,
|
||||
ObjectGroup* group, uint32_t fieldOffset, JSValueType fieldType)
|
||||
: ICStubCompiler(cx, ICStub::GetProp_Unboxed, engine),
|
||||
firstMonitorStub_(firstMonitorStub),
|
||||
group_(cx, group),
|
||||
fieldOffset_(fieldOffset),
|
||||
fieldType_(fieldType)
|
||||
{}
|
||||
|
||||
ICStub* getStub(ICStubSpace* space) {
|
||||
return newStub<ICGetProp_Unboxed>(space, getStubCode(), firstMonitorStub_, group_,
|
||||
fieldOffset_);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
static uint32_t
|
||||
SimpleTypeDescrKey(SimpleTypeDescr* descr)
|
||||
{
|
||||
|
@ -37,7 +37,6 @@ namespace jit {
|
||||
_(GetProp_Fallback) \
|
||||
_(GetProp_Primitive) \
|
||||
_(GetProp_StringLength) \
|
||||
_(GetProp_Unboxed) \
|
||||
_(GetProp_TypedObject) \
|
||||
_(GetProp_CallScripted) \
|
||||
_(GetProp_CallNative) \
|
||||
|
Loading…
x
Reference in New Issue
Block a user