зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1359952 - Add HasPropIRGenerator r=jandem
This combines InIRGenerator with HasOwnIRGenerator. MozReview-Commit-ID: 7FQX5YmVrM7 --HG-- extra : rebase_source : 9b0e735e303f6fa57d4407bec5b81bc8307d365a
This commit is contained in:
Родитель
d561466341
Коммит
43e26a60a0
|
@ -1208,8 +1208,6 @@ DoInFallback(JSContext* cx, BaselineFrame* frame, ICIn_Fallback* stub_,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RootedObject obj(cx, &objValue.toObject());
|
|
||||||
|
|
||||||
if (stub->state().maybeTransition())
|
if (stub->state().maybeTransition())
|
||||||
stub->discardStubs(cx);
|
stub->discardStubs(cx);
|
||||||
|
|
||||||
|
@ -1218,7 +1216,7 @@ DoInFallback(JSContext* cx, BaselineFrame* frame, ICIn_Fallback* stub_,
|
||||||
jsbytecode* pc = stub->icEntry()->pc(script);
|
jsbytecode* pc = stub->icEntry()->pc(script);
|
||||||
|
|
||||||
ICStubEngine engine = ICStubEngine::Baseline;
|
ICStubEngine engine = ICStubEngine::Baseline;
|
||||||
InIRGenerator gen(cx, script, pc, stub->state().mode(), key, obj);
|
HasPropIRGenerator gen(cx, script, pc, CacheKind::In, stub->state().mode(), key, objValue);
|
||||||
bool attached = false;
|
bool attached = false;
|
||||||
if (gen.tryAttachStub()) {
|
if (gen.tryAttachStub()) {
|
||||||
ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(),
|
ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(),
|
||||||
|
@ -1230,6 +1228,7 @@ DoInFallback(JSContext* cx, BaselineFrame* frame, ICIn_Fallback* stub_,
|
||||||
stub->state().trackNotAttached();
|
stub->state().trackNotAttached();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RootedObject obj(cx, &objValue.toObject());
|
||||||
bool cond = false;
|
bool cond = false;
|
||||||
if (!OperatorIn(cx, key, obj, &cond))
|
if (!OperatorIn(cx, key, obj, &cond))
|
||||||
return false;
|
return false;
|
||||||
|
@ -1284,7 +1283,8 @@ DoHasOwnFallback(JSContext* cx, BaselineFrame* frame, ICHasOwn_Fallback* stub_,
|
||||||
jsbytecode* pc = stub->icEntry()->pc(script);
|
jsbytecode* pc = stub->icEntry()->pc(script);
|
||||||
|
|
||||||
ICStubEngine engine = ICStubEngine::Baseline;
|
ICStubEngine engine = ICStubEngine::Baseline;
|
||||||
HasOwnIRGenerator gen(cx, script, pc, stub->state().mode(), keyValue, objValue);
|
HasPropIRGenerator gen(cx, script, pc, CacheKind::HasOwn,
|
||||||
|
stub->state().mode(), keyValue, objValue);
|
||||||
bool attached = false;
|
bool attached = false;
|
||||||
if (gen.tryAttachStub()) {
|
if (gen.tryAttachStub()) {
|
||||||
ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(),
|
ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(),
|
||||||
|
|
|
@ -440,7 +440,7 @@ EmitReadSlotGuard(CacheIRWriter& writer, JSObject* obj, JSObject* holder,
|
||||||
lastObjId = protoId;
|
lastObjId = protoId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (obj->is<UnboxedPlainObject>()) {
|
} else if (obj->is<UnboxedPlainObject>() && expandoId.isSome()) {
|
||||||
holderId->emplace(*expandoId);
|
holderId->emplace(*expandoId);
|
||||||
} else {
|
} else {
|
||||||
holderId->emplace(objId);
|
holderId->emplace(objId);
|
||||||
|
@ -2056,232 +2056,144 @@ BindNameIRGenerator::trackNotAttached()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
InIRGenerator::InIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
|
HasPropIRGenerator::HasPropIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
|
||||||
ICState::Mode mode, HandleValue key, HandleObject obj)
|
CacheKind cacheKind, ICState::Mode mode,
|
||||||
: IRGenerator(cx, script, pc, CacheKind::In, mode),
|
HandleValue idVal, HandleValue val)
|
||||||
key_(key), obj_(obj)
|
: IRGenerator(cx, script, pc, cacheKind, mode),
|
||||||
|
val_(val),
|
||||||
|
idVal_(idVal)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
bool
|
bool
|
||||||
InIRGenerator::tryAttachDenseIn(uint32_t index, Int32OperandId indexId,
|
HasPropIRGenerator::tryAttachDense(HandleObject obj, ObjOperandId objId,
|
||||||
HandleObject obj, ObjOperandId objId)
|
uint32_t index, Int32OperandId indexId)
|
||||||
{
|
{
|
||||||
if (!obj->isNative())
|
if (!obj->isNative())
|
||||||
return false;
|
return false;
|
||||||
if (!obj->as<NativeObject>().containsDenseElement(index))
|
if (!obj->as<NativeObject>().containsDenseElement(index))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Guard shape to ensure object class is NativeObject.
|
||||||
writer.guardShape(objId, obj->as<NativeObject>().lastProperty());
|
writer.guardShape(objId, obj->as<NativeObject>().lastProperty());
|
||||||
|
|
||||||
writer.loadDenseElementExistsResult(objId, indexId);
|
writer.loadDenseElementExistsResult(objId, indexId);
|
||||||
writer.returnFromIC();
|
writer.returnFromIC();
|
||||||
|
|
||||||
trackAttached("DenseIn");
|
trackAttached("DenseHasProp");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
InIRGenerator::tryAttachDenseInHole(uint32_t index, Int32OperandId indexId,
|
HasPropIRGenerator::tryAttachDenseHole(HandleObject obj, ObjOperandId objId,
|
||||||
HandleObject obj, ObjOperandId objId)
|
uint32_t index, Int32OperandId indexId)
|
||||||
{
|
{
|
||||||
|
bool hasOwn = (cacheKind_ == CacheKind::HasOwn);
|
||||||
|
|
||||||
if (!obj->isNative())
|
if (!obj->isNative())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (obj->as<NativeObject>().containsDenseElement(index))
|
if (obj->as<NativeObject>().containsDenseElement(index))
|
||||||
return false;
|
return false;
|
||||||
|
if (!CanAttachDenseElementHole(obj, hasOwn))
|
||||||
if (!CanAttachDenseElementHole(obj, false))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Guard on the shape, to prevent non-dense elements from appearing.
|
// Guard shape to ensure class is NativeObject and to prevent non-dense
|
||||||
|
// elements being added. Also ensures prototype doesn't change if dynamic
|
||||||
|
// checks aren't emitted.
|
||||||
writer.guardShape(objId, obj->as<NativeObject>().lastProperty());
|
writer.guardShape(objId, obj->as<NativeObject>().lastProperty());
|
||||||
|
|
||||||
GeneratePrototypeHoleGuards(writer, obj, objId);
|
// Generate prototype guards if needed. This includes monitoring that
|
||||||
|
// properties were not added in the chain.
|
||||||
|
if (!hasOwn)
|
||||||
|
GeneratePrototypeHoleGuards(writer, obj, objId);
|
||||||
|
|
||||||
writer.loadDenseElementHoleExistsResult(objId, indexId);
|
writer.loadDenseElementHoleExistsResult(objId, indexId);
|
||||||
writer.returnFromIC();
|
writer.returnFromIC();
|
||||||
|
|
||||||
trackAttached("DenseInHole");
|
trackAttached("DenseHasPropHole");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
InIRGenerator::tryAttachNativeIn(HandleId key, ValOperandId keyId,
|
HasPropIRGenerator::tryAttachNative(HandleObject obj, ObjOperandId objId,
|
||||||
HandleObject obj, ObjOperandId objId)
|
HandleId key, ValOperandId keyId)
|
||||||
{
|
{
|
||||||
|
bool hasOwn = (cacheKind_ == CacheKind::HasOwn);
|
||||||
|
|
||||||
|
JSObject* holder = nullptr;
|
||||||
PropertyResult prop;
|
PropertyResult prop;
|
||||||
JSObject* holder;
|
|
||||||
if (!LookupPropertyPure(cx_, obj, key, &holder, &prop))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!prop.isNativeProperty())
|
if (hasOwn) {
|
||||||
return false;
|
if (!LookupOwnPropertyPure(cx_, obj, key, &prop))
|
||||||
|
return false;
|
||||||
|
|
||||||
Maybe<ObjOperandId> holderId;
|
holder = obj;
|
||||||
emitIdGuard(keyId, key);
|
} else {
|
||||||
EmitReadSlotGuard(writer, obj, holder, objId, &holderId);
|
if (!LookupPropertyPure(cx_, obj, key, &holder, &prop))
|
||||||
writer.loadBooleanResult(true);
|
return false;
|
||||||
writer.returnFromIC();
|
|
||||||
|
|
||||||
trackAttached("NativeIn");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
InIRGenerator::tryAttachNativeInDoesNotExist(HandleId key, ValOperandId keyId,
|
|
||||||
HandleObject obj, ObjOperandId objId)
|
|
||||||
{
|
|
||||||
if (!CheckHasNoSuchProperty(cx_, obj, key))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Maybe<ObjOperandId> holderId;
|
|
||||||
emitIdGuard(keyId, key);
|
|
||||||
EmitReadSlotGuard(writer, obj, nullptr, objId, &holderId);
|
|
||||||
writer.loadBooleanResult(false);
|
|
||||||
writer.returnFromIC();
|
|
||||||
|
|
||||||
trackAttached("NativeInDoesNotExist");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
InIRGenerator::tryAttachStub()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(cacheKind_ == CacheKind::In);
|
|
||||||
|
|
||||||
AutoAssertNoPendingException aanpe(cx_);
|
|
||||||
|
|
||||||
ValOperandId keyId(writer.setInputOperandId(0));
|
|
||||||
ValOperandId valId(writer.setInputOperandId(1));
|
|
||||||
ObjOperandId objId = writer.guardIsObject(valId);
|
|
||||||
|
|
||||||
RootedId id(cx_);
|
|
||||||
bool nameOrSymbol;
|
|
||||||
if (!ValueToNameOrSymbolId(cx_, key_, &id, &nameOrSymbol)) {
|
|
||||||
cx_->clearPendingException();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nameOrSymbol) {
|
|
||||||
if (tryAttachNativeIn(id, keyId, obj_, objId))
|
|
||||||
return true;
|
|
||||||
if (tryAttachNativeInDoesNotExist(id, keyId, obj_, objId))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
trackNotAttached();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t index;
|
|
||||||
Int32OperandId indexId;
|
|
||||||
if (maybeGuardInt32Index(key_, keyId, &index, &indexId)) {
|
|
||||||
if (tryAttachDenseIn(index, indexId, obj_, objId))
|
|
||||||
return true;
|
|
||||||
if (tryAttachDenseInHole(index, indexId, obj_, objId))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
trackNotAttached();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
trackNotAttached();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
InIRGenerator::trackAttached(const char* name)
|
|
||||||
{
|
|
||||||
#ifdef JS_CACHEIR_SPEW
|
|
||||||
CacheIRSpewer& sp = CacheIRSpewer::singleton();
|
|
||||||
if (sp.enabled()) {
|
|
||||||
LockGuard<Mutex> guard(sp.lock());
|
|
||||||
sp.beginCache(guard, *this);
|
|
||||||
sp.valueProperty(guard, "base", ObjectValue(*obj_));
|
|
||||||
sp.valueProperty(guard, "property", key_);
|
|
||||||
sp.attached(guard, name);
|
|
||||||
sp.endCache(guard);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
InIRGenerator::trackNotAttached()
|
|
||||||
{
|
|
||||||
#ifdef JS_CACHEIR_SPEW
|
|
||||||
CacheIRSpewer& sp = CacheIRSpewer::singleton();
|
|
||||||
if (sp.enabled()) {
|
|
||||||
LockGuard<Mutex> guard(sp.lock());
|
|
||||||
sp.beginCache(guard, *this);
|
|
||||||
sp.valueProperty(guard, "base", ObjectValue(*obj_));
|
|
||||||
sp.valueProperty(guard, "property", key_);
|
|
||||||
sp.endCache(guard);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
HasOwnIRGenerator::HasOwnIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
|
|
||||||
ICState::Mode mode, HandleValue key, HandleValue value)
|
|
||||||
: IRGenerator(cx, script, pc, CacheKind::HasOwn, mode),
|
|
||||||
key_(key), val_(value)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
HasOwnIRGenerator::tryAttachNativeHasOwn(HandleId key, ValOperandId keyId,
|
|
||||||
HandleObject obj, ObjOperandId objId)
|
|
||||||
{
|
|
||||||
PropertyResult prop;
|
|
||||||
if (!LookupOwnPropertyPure(cx_, obj, key, &prop))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!prop.isFound())
|
if (!prop.isFound())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!obj->isNative() && !obj->is<UnboxedPlainObject>())
|
// Use MegamorphicHasOwnResult if applicable
|
||||||
return false;
|
if (hasOwn && mode_ == ICState::Mode::Megamorphic) {
|
||||||
|
|
||||||
if (mode_ == ICState::Mode::Megamorphic) {
|
|
||||||
writer.megamorphicHasOwnResult(objId, keyId);
|
writer.megamorphicHasOwnResult(objId, keyId);
|
||||||
writer.returnFromIC();
|
writer.returnFromIC();
|
||||||
trackAttached("MegamorphicHasOwn");
|
trackAttached("MegamorphicHasProp");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<ObjOperandId> expandoId;
|
Maybe<ObjOperandId> tempId;
|
||||||
emitIdGuard(keyId, key);
|
emitIdGuard(keyId, key);
|
||||||
TestMatchingReceiver(writer, obj, objId, &expandoId);
|
EmitReadSlotGuard(writer, obj, holder, objId, &tempId);
|
||||||
writer.loadBooleanResult(true);
|
writer.loadBooleanResult(true);
|
||||||
writer.returnFromIC();
|
writer.returnFromIC();
|
||||||
|
|
||||||
trackAttached("NativeHasOwn");
|
trackAttached("NativeHasProp");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HasOwnIRGenerator::tryAttachNativeHasOwnDoesNotExist(HandleId key, ValOperandId keyId,
|
HasPropIRGenerator::tryAttachNativeDoesNotExist(HandleObject obj, ObjOperandId objId,
|
||||||
HandleObject obj, ObjOperandId objId)
|
HandleId key, ValOperandId keyId)
|
||||||
{
|
{
|
||||||
if (!CheckHasNoSuchOwnProperty(cx_, obj, key))
|
bool hasOwn = (cacheKind_ == CacheKind::HasOwn);
|
||||||
return false;
|
|
||||||
|
|
||||||
if (mode_ == ICState::Mode::Megamorphic) {
|
if (hasOwn) {
|
||||||
|
if (!CheckHasNoSuchOwnProperty(cx_, obj, key))
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
if (!CheckHasNoSuchProperty(cx_, obj, key))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use MegamorphicHasOwnResult if applicable
|
||||||
|
if (hasOwn && mode_ == ICState::Mode::Megamorphic) {
|
||||||
writer.megamorphicHasOwnResult(objId, keyId);
|
writer.megamorphicHasOwnResult(objId, keyId);
|
||||||
writer.returnFromIC();
|
writer.returnFromIC();
|
||||||
trackAttached("MegamorphicHasOwn");
|
trackAttached("MegamorphicHasOwn");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<ObjOperandId> expandoId;
|
Maybe<ObjOperandId> tempId;
|
||||||
emitIdGuard(keyId, key);
|
emitIdGuard(keyId, key);
|
||||||
TestMatchingReceiver(writer, obj, objId, &expandoId);
|
if (hasOwn) {
|
||||||
|
TestMatchingReceiver(writer, obj, objId, &tempId);
|
||||||
|
} else {
|
||||||
|
EmitReadSlotGuard(writer, obj, nullptr, objId, &tempId);
|
||||||
|
}
|
||||||
writer.loadBooleanResult(false);
|
writer.loadBooleanResult(false);
|
||||||
writer.returnFromIC();
|
writer.returnFromIC();
|
||||||
|
|
||||||
trackAttached("NativeHasOwnDoesNotExist");
|
trackAttached("NativeDoesNotExist");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HasOwnIRGenerator::tryAttachProxyElement(ValOperandId keyId, HandleObject obj, ObjOperandId objId)
|
HasPropIRGenerator::tryAttachProxyElement(HandleObject obj, ObjOperandId objId,
|
||||||
|
ValOperandId keyId)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(cacheKind_ == CacheKind::HasOwn);
|
||||||
|
|
||||||
if (!obj->is<ProxyObject>())
|
if (!obj->is<ProxyObject>())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -2289,34 +2201,19 @@ HasOwnIRGenerator::tryAttachProxyElement(ValOperandId keyId, HandleObject obj, O
|
||||||
writer.callProxyHasOwnResult(objId, keyId);
|
writer.callProxyHasOwnResult(objId, keyId);
|
||||||
writer.returnFromIC();
|
writer.returnFromIC();
|
||||||
|
|
||||||
trackAttached("ProxyHasOwn");
|
trackAttached("ProxyHasProp");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HasOwnIRGenerator::tryAttachDenseHasOwn(uint32_t index, Int32OperandId indexId,
|
HasPropIRGenerator::tryAttachStub()
|
||||||
HandleObject obj, ObjOperandId objId)
|
|
||||||
{
|
{
|
||||||
if (!obj->isNative())
|
MOZ_ASSERT(cacheKind_ == CacheKind::In ||
|
||||||
return false;
|
cacheKind_ == CacheKind::HasOwn);
|
||||||
if (!obj->as<NativeObject>().containsDenseElement(index))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
writer.guardShape(objId, obj->as<NativeObject>().lastProperty());
|
|
||||||
writer.loadDenseElementExistsResult(objId, indexId);
|
|
||||||
writer.returnFromIC();
|
|
||||||
|
|
||||||
trackAttached("DenseHasOwn");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
HasOwnIRGenerator::tryAttachStub()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(cacheKind_ == CacheKind::HasOwn);
|
|
||||||
|
|
||||||
AutoAssertNoPendingException aanpe(cx_);
|
AutoAssertNoPendingException aanpe(cx_);
|
||||||
|
|
||||||
|
// NOTE: Argument order is PROPERTY, OBJECT
|
||||||
ValOperandId keyId(writer.setInputOperandId(0));
|
ValOperandId keyId(writer.setInputOperandId(0));
|
||||||
ValOperandId valId(writer.setInputOperandId(1));
|
ValOperandId valId(writer.setInputOperandId(1));
|
||||||
|
|
||||||
|
@ -2325,23 +2222,25 @@ HasOwnIRGenerator::tryAttachStub()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
RootedObject obj(cx_, &val_.toObject());
|
RootedObject obj(cx_, &val_.toObject());
|
||||||
|
|
||||||
ObjOperandId objId = writer.guardIsObject(valId);
|
ObjOperandId objId = writer.guardIsObject(valId);
|
||||||
|
|
||||||
if (tryAttachProxyElement(keyId, obj, objId))
|
// Optimize DOM Proxies for JSOP_HASOWN
|
||||||
return true;
|
if (cacheKind_ == CacheKind::HasOwn) {
|
||||||
|
if (tryAttachProxyElement(obj, objId, keyId))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
RootedId id(cx_);
|
RootedId id(cx_);
|
||||||
bool nameOrSymbol;
|
bool nameOrSymbol;
|
||||||
if (!ValueToNameOrSymbolId(cx_, key_, &id, &nameOrSymbol)) {
|
if (!ValueToNameOrSymbolId(cx_, idVal_, &id, &nameOrSymbol)) {
|
||||||
cx_->clearPendingException();
|
cx_->clearPendingException();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nameOrSymbol) {
|
if (nameOrSymbol) {
|
||||||
if (tryAttachNativeHasOwn(id, keyId, obj, objId))
|
if (tryAttachNative(obj, objId, id, keyId))
|
||||||
return true;
|
return true;
|
||||||
if (tryAttachNativeHasOwnDoesNotExist(id, keyId, obj, objId))
|
if (tryAttachNativeDoesNotExist(obj, objId, id, keyId))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
trackNotAttached();
|
trackNotAttached();
|
||||||
|
@ -2350,8 +2249,10 @@ HasOwnIRGenerator::tryAttachStub()
|
||||||
|
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
Int32OperandId indexId;
|
Int32OperandId indexId;
|
||||||
if (maybeGuardInt32Index(key_, keyId, &index, &indexId)) {
|
if (maybeGuardInt32Index(idVal_, keyId, &index, &indexId)) {
|
||||||
if (tryAttachDenseHasOwn(index, indexId, obj, objId))
|
if (tryAttachDense(obj, objId, index, indexId))
|
||||||
|
return true;
|
||||||
|
if (tryAttachDenseHole(obj, objId, index, indexId))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
trackNotAttached();
|
trackNotAttached();
|
||||||
|
@ -2363,7 +2264,7 @@ HasOwnIRGenerator::tryAttachStub()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HasOwnIRGenerator::trackAttached(const char* name)
|
HasPropIRGenerator::trackAttached(const char* name)
|
||||||
{
|
{
|
||||||
#ifdef JS_CACHEIR_SPEW
|
#ifdef JS_CACHEIR_SPEW
|
||||||
CacheIRSpewer& sp = CacheIRSpewer::singleton();
|
CacheIRSpewer& sp = CacheIRSpewer::singleton();
|
||||||
|
@ -2371,7 +2272,7 @@ HasOwnIRGenerator::trackAttached(const char* name)
|
||||||
LockGuard<Mutex> guard(sp.lock());
|
LockGuard<Mutex> guard(sp.lock());
|
||||||
sp.beginCache(guard, *this);
|
sp.beginCache(guard, *this);
|
||||||
sp.valueProperty(guard, "base", val_);
|
sp.valueProperty(guard, "base", val_);
|
||||||
sp.valueProperty(guard, "property", key_);
|
sp.valueProperty(guard, "property", idVal_);
|
||||||
sp.attached(guard, name);
|
sp.attached(guard, name);
|
||||||
sp.endCache(guard);
|
sp.endCache(guard);
|
||||||
}
|
}
|
||||||
|
@ -2379,7 +2280,7 @@ HasOwnIRGenerator::trackAttached(const char* name)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HasOwnIRGenerator::trackNotAttached()
|
HasPropIRGenerator::trackNotAttached()
|
||||||
{
|
{
|
||||||
#ifdef JS_CACHEIR_SPEW
|
#ifdef JS_CACHEIR_SPEW
|
||||||
CacheIRSpewer& sp = CacheIRSpewer::singleton();
|
CacheIRSpewer& sp = CacheIRSpewer::singleton();
|
||||||
|
@ -2387,7 +2288,7 @@ HasOwnIRGenerator::trackNotAttached()
|
||||||
LockGuard<Mutex> guard(sp.lock());
|
LockGuard<Mutex> guard(sp.lock());
|
||||||
sp.beginCache(guard, *this);
|
sp.beginCache(guard, *this);
|
||||||
sp.valueProperty(guard, "base", val_);
|
sp.valueProperty(guard, "base", val_);
|
||||||
sp.valueProperty(guard, "property", key_);
|
sp.valueProperty(guard, "property", idVal_);
|
||||||
sp.endCache(guard);
|
sp.endCache(guard);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1276,51 +1276,31 @@ class MOZ_RAII SetPropIRGenerator : public IRGenerator
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// InIRGenerator generates CacheIR for a In IC.
|
// HasPropIRGenerator generates CacheIR for a HasProp IC. Used for
|
||||||
class MOZ_RAII InIRGenerator : public IRGenerator
|
// CacheKind::In / CacheKind::HasOwn.
|
||||||
|
class MOZ_RAII HasPropIRGenerator : public IRGenerator
|
||||||
{
|
{
|
||||||
HandleValue key_;
|
|
||||||
HandleObject obj_;
|
|
||||||
|
|
||||||
bool tryAttachDenseIn(uint32_t index, Int32OperandId indexId,
|
|
||||||
HandleObject obj, ObjOperandId objId);
|
|
||||||
bool tryAttachDenseInHole(uint32_t index, Int32OperandId indexId,
|
|
||||||
HandleObject obj, ObjOperandId objId);
|
|
||||||
bool tryAttachNativeIn(HandleId key, ValOperandId keyId,
|
|
||||||
HandleObject obj, ObjOperandId objId);
|
|
||||||
bool tryAttachNativeInDoesNotExist(HandleId key, ValOperandId keyId,
|
|
||||||
HandleObject obj, ObjOperandId objId);
|
|
||||||
|
|
||||||
void trackAttached(const char* name);
|
|
||||||
void trackNotAttached();
|
|
||||||
|
|
||||||
public:
|
|
||||||
InIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, ICState::Mode mode, HandleValue key,
|
|
||||||
HandleObject obj);
|
|
||||||
|
|
||||||
bool tryAttachStub();
|
|
||||||
};
|
|
||||||
|
|
||||||
// HasOwnIRGenerator generates CacheIR for a HasOwn IC.
|
|
||||||
class MOZ_RAII HasOwnIRGenerator : public IRGenerator
|
|
||||||
{
|
|
||||||
HandleValue key_;
|
|
||||||
HandleValue val_;
|
HandleValue val_;
|
||||||
|
HandleValue idVal_;
|
||||||
|
|
||||||
bool tryAttachProxyElement(ValOperandId keyId, HandleObject obj, ObjOperandId objId);
|
bool tryAttachDense(HandleObject obj, ObjOperandId objId,
|
||||||
bool tryAttachDenseHasOwn(uint32_t index, Int32OperandId indexId,
|
uint32_t index, Int32OperandId indexId);
|
||||||
HandleObject obj, ObjOperandId objId);
|
bool tryAttachDenseHole(HandleObject obj, ObjOperandId objId,
|
||||||
bool tryAttachNativeHasOwn(HandleId key, ValOperandId keyId,
|
uint32_t index, Int32OperandId indexId);
|
||||||
HandleObject obj, ObjOperandId objId);
|
bool tryAttachNative(HandleObject obj, ObjOperandId objId,
|
||||||
bool tryAttachNativeHasOwnDoesNotExist(HandleId key, ValOperandId keyId,
|
HandleId key, ValOperandId keyId);
|
||||||
HandleObject obj, ObjOperandId objId);
|
bool tryAttachNativeDoesNotExist(HandleObject obj, ObjOperandId objId,
|
||||||
|
HandleId key, ValOperandId keyId);
|
||||||
|
bool tryAttachProxyElement(HandleObject obj, ObjOperandId objId,
|
||||||
|
ValOperandId keyId);
|
||||||
|
|
||||||
void trackAttached(const char* name);
|
void trackAttached(const char* name);
|
||||||
void trackNotAttached();
|
void trackNotAttached();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HasOwnIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, ICState::Mode mode, HandleValue key,
|
// NOTE: Argument order is PROPERTY, OBJECT
|
||||||
HandleValue value);
|
HasPropIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, CacheKind cacheKind,
|
||||||
|
ICState::Mode mode, HandleValue idVal, HandleValue val);
|
||||||
|
|
||||||
bool tryAttachStub();
|
bool tryAttachStub();
|
||||||
};
|
};
|
||||||
|
|
|
@ -355,7 +355,7 @@ IonHasOwnIC::update(JSContext* cx, HandleScript outerScript, IonHasOwnIC* ic,
|
||||||
if (ic->state().canAttachStub()) {
|
if (ic->state().canAttachStub()) {
|
||||||
bool attached = false;
|
bool attached = false;
|
||||||
RootedScript script(cx, ic->script());
|
RootedScript script(cx, ic->script());
|
||||||
HasOwnIRGenerator gen(cx, script, pc, ic->state().mode(), idVal, val);
|
HasPropIRGenerator gen(cx, script, pc, CacheKind::HasOwn, ic->state().mode(), idVal, val);
|
||||||
if (gen.tryAttachStub())
|
if (gen.tryAttachStub())
|
||||||
ic->attachCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), ionScript, &attached);
|
ic->attachCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), ionScript, &attached);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче