зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1666853 - Part 4: Remove use of ApplyGCThingTyped from Value barriers as this doesn't generate good code r=sfink
Differential Revision: https://phabricator.services.mozilla.com/D91311
This commit is contained in:
Родитель
14ae5786a0
Коммит
0bbf0e853e
|
@ -92,8 +92,13 @@ struct PropertyKey {
|
||||||
return reinterpret_cast<JS::Symbol*>(asBits ^ JSID_TYPE_SYMBOL);
|
return reinterpret_cast<JS::Symbol*>(asBits ^ JSID_TYPE_SYMBOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
js::gc::Cell* toGCThing() const {
|
||||||
|
MOZ_ASSERT(isGCThing());
|
||||||
|
return reinterpret_cast<js::gc::Cell*>(asBits & ~(size_t)JSID_TYPE_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
GCCellPtr toGCCellPtr() const {
|
GCCellPtr toGCCellPtr() const {
|
||||||
void* thing = (void*)(asBits & ~(size_t)JSID_TYPE_MASK);
|
js::gc::Cell* thing = toGCThing();
|
||||||
if (isString()) {
|
if (isString()) {
|
||||||
return JS::GCCellPtr(thing, JS::TraceKind::String);
|
return JS::GCCellPtr(thing, JS::TraceKind::String);
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,20 +103,103 @@ AutoTouchingGrayThings::~AutoTouchingGrayThings() {
|
||||||
|
|
||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
|
|
||||||
|
// Tagged pointer barriers
|
||||||
|
//
|
||||||
|
// It's tempting to use ApplyGCThingTyped to dispatch to the typed barrier
|
||||||
|
// functions (e.g. gc::ReadBarrier(JSObject*)) but this does not compile well
|
||||||
|
// (clang generates 1580 bytes on x64 versus 296 bytes for this implementation
|
||||||
|
// of ValueReadBarrier).
|
||||||
|
//
|
||||||
|
// Instead, check known special cases and call the generic barrier functions.
|
||||||
|
|
||||||
|
static MOZ_ALWAYS_INLINE bool ValueIsPermanent(const Value& value) {
|
||||||
|
gc::Cell* cell = value.toGCThing();
|
||||||
|
|
||||||
|
if (value.isString()) {
|
||||||
|
return cell->as<JSString>()->isPermanentAndMayBeShared();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.isSymbol()) {
|
||||||
|
return cell->as<JS::Symbol>()->isPermanentAndMayBeShared();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
// Using mozilla::DebugOnly here still generated code in opt builds.
|
||||||
|
bool isPermanent = MapGCThingTyped(value, [](auto t) {
|
||||||
|
return t->isPermanentAndMayBeShared();
|
||||||
|
}).value();
|
||||||
|
MOZ_ASSERT(!isPermanent);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void gc::ValueReadBarrier(const Value& v) {
|
void gc::ValueReadBarrier(const Value& v) {
|
||||||
ApplyGCThingTyped(v, [](auto t) { gc::ReadBarrier(t); });
|
MOZ_ASSERT(v.isGCThing());
|
||||||
|
|
||||||
|
if (!ValueIsPermanent(v)) {
|
||||||
|
ReadBarrierImpl(v.toGCThing());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gc::ValuePreWriteBarrier(const Value& v) {
|
void gc::ValuePreWriteBarrier(const Value& v) {
|
||||||
ApplyGCThingTyped(v, [](auto t) { gc::PreWriteBarrier(t); });
|
MOZ_ASSERT(v.isGCThing());
|
||||||
|
|
||||||
|
if (!ValueIsPermanent(v)) {
|
||||||
|
PreWriteBarrierImpl(v.toGCThing());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static MOZ_ALWAYS_INLINE bool IdIsPermanent(jsid id) {
|
||||||
|
gc::Cell* cell = id.toGCThing();
|
||||||
|
|
||||||
|
if (id.isString()) {
|
||||||
|
return cell->as<JSString>()->isPermanentAndMayBeShared();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id.isSymbol()) {
|
||||||
|
return cell->as<JS::Symbol>()->isPermanentAndMayBeShared();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
bool isPermanent = MapGCThingTyped(id, [](auto t) {
|
||||||
|
return t->isPermanentAndMayBeShared();
|
||||||
|
}).value();
|
||||||
|
MOZ_ASSERT(!isPermanent);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gc::IdPreWriteBarrier(jsid id) {
|
void gc::IdPreWriteBarrier(jsid id) {
|
||||||
ApplyGCThingTyped(id, [](auto t) { gc::PreWriteBarrier(t); });
|
MOZ_ASSERT(id.isGCThing());
|
||||||
|
|
||||||
|
if (!IdIsPermanent(id)) {
|
||||||
|
PreWriteBarrierImpl(&id.toGCThing()->asTenured());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static MOZ_ALWAYS_INLINE bool CellPtrIsPermanent(JS::GCCellPtr thing) {
|
||||||
|
if (thing.mayBeOwnedByOtherRuntime()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
bool isPermanent = MapGCThingTyped(thing, [](auto t) {
|
||||||
|
return t->isPermanentAndMayBeShared();
|
||||||
|
});
|
||||||
|
MOZ_ASSERT(!isPermanent);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gc::CellPtrPreWriteBarrier(JS::GCCellPtr thing) {
|
void gc::CellPtrPreWriteBarrier(JS::GCCellPtr thing) {
|
||||||
ApplyGCThingTyped(thing, [](auto t) { gc::PreWriteBarrier(t); });
|
MOZ_ASSERT(thing);
|
||||||
|
|
||||||
|
if (!CellPtrIsPermanent(thing)) {
|
||||||
|
PreWriteBarrierImpl(thing.asCell());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче