зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1266180 - Port unboxed object getprop stub to CacheIR. r=efaust
This commit is contained in:
Родитель
b21b1c955b
Коммит
6e76c672f2
|
@ -843,6 +843,26 @@ BaselineCacheIRCompiler::emitLoadDynamicSlotResult()
|
||||||
return true;
|
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
|
bool
|
||||||
BaselineCacheIRCompiler::emitLoadUndefinedResult()
|
BaselineCacheIRCompiler::emitLoadUndefinedResult()
|
||||||
{
|
{
|
||||||
|
|
|
@ -108,8 +108,6 @@ AddReceiver(const ReceiverGuard& receiver,
|
||||||
static bool
|
static bool
|
||||||
GetCacheIRReceiverForNativeReadSlot(ICCacheIR_Monitored* stub, ReceiverGuard* receiver)
|
GetCacheIRReceiverForNativeReadSlot(ICCacheIR_Monitored* stub, ReceiverGuard* receiver)
|
||||||
{
|
{
|
||||||
// If this is a getprop stub to get an own object's read-slot stub.
|
|
||||||
//
|
|
||||||
// We match either:
|
// We match either:
|
||||||
//
|
//
|
||||||
// GuardIsObject 0
|
// GuardIsObject 0
|
||||||
|
@ -125,6 +123,7 @@ GetCacheIRReceiverForNativeReadSlot(ICCacheIR_Monitored* stub, ReceiverGuard* re
|
||||||
// LoadUnboxedExpando 0
|
// LoadUnboxedExpando 0
|
||||||
// LoadFixedSlotResult or LoadDynamicSlotResult
|
// LoadFixedSlotResult or LoadDynamicSlotResult
|
||||||
|
|
||||||
|
*receiver = ReceiverGuard();
|
||||||
CacheIRReader reader(stub->stubInfo());
|
CacheIRReader reader(stub->stubInfo());
|
||||||
|
|
||||||
ObjOperandId objId = ObjOperandId(0);
|
ObjOperandId objId = ObjOperandId(0);
|
||||||
|
@ -154,6 +153,29 @@ GetCacheIRReceiverForNativeReadSlot(ICCacheIR_Monitored* stub, ReceiverGuard* re
|
||||||
return false;
|
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
|
bool
|
||||||
BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receivers,
|
BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receivers,
|
||||||
ObjectGroupVector& convertUnboxedGroups)
|
ObjectGroupVector& convertUnboxedGroups)
|
||||||
|
@ -176,15 +198,15 @@ BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receiv
|
||||||
while (stub->next()) {
|
while (stub->next()) {
|
||||||
ReceiverGuard receiver;
|
ReceiverGuard receiver;
|
||||||
if (stub->isCacheIR_Monitored()) {
|
if (stub->isCacheIR_Monitored()) {
|
||||||
if (!GetCacheIRReceiverForNativeReadSlot(stub->toCacheIR_Monitored(), &receiver)) {
|
if (!GetCacheIRReceiverForNativeReadSlot(stub->toCacheIR_Monitored(), &receiver) &&
|
||||||
|
!GetCacheIRReceiverForUnboxedProperty(stub->toCacheIR_Monitored(), &receiver))
|
||||||
|
{
|
||||||
receivers.clear();
|
receivers.clear();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (stub->isSetProp_Native()) {
|
} else if (stub->isSetProp_Native()) {
|
||||||
receiver = ReceiverGuard(stub->toSetProp_Native()->group(),
|
receiver = ReceiverGuard(stub->toSetProp_Native()->group(),
|
||||||
stub->toSetProp_Native()->shape());
|
stub->toSetProp_Native()->shape());
|
||||||
} else if (stub->isGetProp_Unboxed()) {
|
|
||||||
receiver = ReceiverGuard(stub->toGetProp_Unboxed()->group(), nullptr);
|
|
||||||
} else if (stub->isSetProp_Unboxed()) {
|
} else if (stub->isSetProp_Unboxed()) {
|
||||||
receiver = ReceiverGuard(stub->toSetProp_Unboxed()->group(), nullptr);
|
receiver = ReceiverGuard(stub->toSetProp_Unboxed()->group(), nullptr);
|
||||||
} else {
|
} else {
|
||||||
|
@ -805,7 +827,6 @@ BaselineInspector::expectedPropertyAccessInputType(jsbytecode* pc)
|
||||||
// Either an object or magic arguments.
|
// Either an object or magic arguments.
|
||||||
return MIRType::Value;
|
return MIRType::Value;
|
||||||
|
|
||||||
case ICStub::GetProp_Unboxed:
|
|
||||||
case ICStub::GetProp_TypedObject:
|
case ICStub::GetProp_TypedObject:
|
||||||
case ICStub::GetProp_CallScripted:
|
case ICStub::GetProp_CallScripted:
|
||||||
case ICStub::GetProp_CallNative:
|
case ICStub::GetProp_CallNative:
|
||||||
|
|
|
@ -60,6 +60,8 @@ GetPropIRGenerator::tryAttachStub(Maybe<CacheIRWriter>& writer)
|
||||||
return false;
|
return false;
|
||||||
if (!emitted_ && !tryAttachNative(*writer, obj, objId))
|
if (!emitted_ && !tryAttachNative(*writer, obj, objId))
|
||||||
return false;
|
return false;
|
||||||
|
if (!emitted_ && !tryAttachUnboxed(*writer, obj, objId))
|
||||||
|
return false;
|
||||||
if (!emitted_ && !tryAttachUnboxedExpando(*writer, obj, objId))
|
if (!emitted_ && !tryAttachUnboxedExpando(*writer, obj, objId))
|
||||||
return false;
|
return false;
|
||||||
if (!emitted_ && !tryAttachModuleNamespace(*writer, obj, objId))
|
if (!emitted_ && !tryAttachModuleNamespace(*writer, obj, objId))
|
||||||
|
@ -257,6 +259,29 @@ GetPropIRGenerator::tryAttachNative(CacheIRWriter& writer, HandleObject obj, Obj
|
||||||
return true;
|
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
|
bool
|
||||||
GetPropIRGenerator::tryAttachUnboxedExpando(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId)
|
GetPropIRGenerator::tryAttachUnboxedExpando(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId)
|
||||||
{
|
{
|
||||||
|
|
|
@ -91,6 +91,7 @@ class ObjOperandId : public OperandId
|
||||||
_(LoadUnboxedExpando) \
|
_(LoadUnboxedExpando) \
|
||||||
_(LoadFixedSlotResult) \
|
_(LoadFixedSlotResult) \
|
||||||
_(LoadDynamicSlotResult) \
|
_(LoadDynamicSlotResult) \
|
||||||
|
_(LoadUnboxedPropertyResult) \
|
||||||
_(LoadInt32ArrayLengthResult) \
|
_(LoadInt32ArrayLengthResult) \
|
||||||
_(LoadUnboxedArrayLengthResult) \
|
_(LoadUnboxedArrayLengthResult) \
|
||||||
_(LoadArgumentsObjectLengthResult) \
|
_(LoadArgumentsObjectLengthResult) \
|
||||||
|
@ -304,6 +305,11 @@ class MOZ_RAII CacheIRWriter
|
||||||
writeOpWithOperandId(CacheOp::LoadDynamicSlotResult, obj);
|
writeOpWithOperandId(CacheOp::LoadDynamicSlotResult, obj);
|
||||||
addStubWord(offset, StubField::GCType::NoGCThing);
|
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) {
|
void loadInt32ArrayLengthResult(ObjOperandId obj) {
|
||||||
writeOpWithOperandId(CacheOp::LoadInt32ArrayLengthResult, obj);
|
writeOpWithOperandId(CacheOp::LoadInt32ArrayLengthResult, obj);
|
||||||
}
|
}
|
||||||
|
@ -349,6 +355,7 @@ class MOZ_RAII CacheIRReader
|
||||||
|
|
||||||
uint32_t stubOffset() { return buffer_.readByte(); }
|
uint32_t stubOffset() { return buffer_.readByte(); }
|
||||||
GuardClassKind guardClassKind() { return GuardClassKind(buffer_.readByte()); }
|
GuardClassKind guardClassKind() { return GuardClassKind(buffer_.readByte()); }
|
||||||
|
JSValueType valueType() { return JSValueType(buffer_.readByte()); }
|
||||||
|
|
||||||
bool matchOp(CacheOp op) {
|
bool matchOp(CacheOp op) {
|
||||||
const uint8_t* pos = buffer_.currentPosition();
|
const uint8_t* pos = buffer_.currentPosition();
|
||||||
|
@ -388,6 +395,7 @@ class MOZ_RAII GetPropIRGenerator
|
||||||
PreliminaryObjectAction preliminaryObjectAction_;
|
PreliminaryObjectAction preliminaryObjectAction_;
|
||||||
|
|
||||||
bool tryAttachNative(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId);
|
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 tryAttachUnboxedExpando(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId);
|
||||||
bool tryAttachObjectLength(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId);
|
bool tryAttachObjectLength(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId);
|
||||||
bool tryAttachModuleNamespace(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");
|
TraceEdge(trc, &propStub->protoShape(), "baseline-getprop-primitive-stub-shape");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ICStub::GetProp_Unboxed: {
|
|
||||||
ICGetProp_Unboxed* propStub = toGetProp_Unboxed();
|
|
||||||
TraceEdge(trc, &propStub->group(), "baseline-getprop-unboxed-stub-group");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ICStub::GetProp_TypedObject: {
|
case ICStub::GetProp_TypedObject: {
|
||||||
ICGetProp_TypedObject* propStub = toGetProp_TypedObject();
|
ICGetProp_TypedObject* propStub = toGetProp_TypedObject();
|
||||||
TraceEdge(trc, &propStub->shape(), "baseline-getprop-typedobject-stub-shape");
|
TraceEdge(trc, &propStub->shape(), "baseline-getprop-typedobject-stub-shape");
|
||||||
|
@ -2554,40 +2549,6 @@ TryAttachNativeGetAccessorPropStub(JSContext* cx, SharedStubInfo* info,
|
||||||
return true;
|
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
|
static bool
|
||||||
TryAttachTypedObjectGetPropStub(JSContext* cx, SharedStubInfo* info,
|
TryAttachTypedObjectGetPropStub(JSContext* cx, SharedStubInfo* info,
|
||||||
ICGetProp_Fallback* stub, HandlePropertyName name,
|
ICGetProp_Fallback* stub, HandlePropertyName name,
|
||||||
|
@ -2861,11 +2822,6 @@ DoGetPropFallback(JSContext* cx, void* payload, ICGetProp_Fallback* stub_,
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
||||||
if (!TryAttachUnboxedGetPropStub(cx, &info, stub, name, val, &attached))
|
|
||||||
return false;
|
|
||||||
if (attached)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (!TryAttachTypedObjectGetPropStub(cx, &info, stub, name, val, &attached))
|
if (!TryAttachTypedObjectGetPropStub(cx, &info, stub, name, val, &attached))
|
||||||
return false;
|
return false;
|
||||||
if (attached)
|
if (attached)
|
||||||
|
@ -3754,39 +3710,6 @@ ICGetProp_Generic::Compiler::generateStubCode(MacroAssembler& masm)
|
||||||
return true;
|
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
|
void
|
||||||
CheckForTypedObjectWithDetachedStorage(JSContext* cx, MacroAssembler& masm, Label* failure)
|
CheckForTypedObjectWithDetachedStorage(JSContext* cx, MacroAssembler& masm, Label* failure)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2595,65 +2595,6 @@ class ICGetPropNativeCompiler : public ICStubCompiler
|
||||||
ICGetPropNativeStub* getStub(ICStubSpace* space);
|
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
|
static uint32_t
|
||||||
SimpleTypeDescrKey(SimpleTypeDescr* descr)
|
SimpleTypeDescrKey(SimpleTypeDescr* descr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,7 +37,6 @@ namespace jit {
|
||||||
_(GetProp_Fallback) \
|
_(GetProp_Fallback) \
|
||||||
_(GetProp_Primitive) \
|
_(GetProp_Primitive) \
|
||||||
_(GetProp_StringLength) \
|
_(GetProp_StringLength) \
|
||||||
_(GetProp_Unboxed) \
|
|
||||||
_(GetProp_TypedObject) \
|
_(GetProp_TypedObject) \
|
||||||
_(GetProp_CallScripted) \
|
_(GetProp_CallScripted) \
|
||||||
_(GetProp_CallNative) \
|
_(GetProp_CallNative) \
|
||||||
|
|
Загрузка…
Ссылка в новой задаче