Bug 1631267 part 1 - Support LoadObject in the transpiler. r=iain

We don't transpile CacheIR if the stub data contains nursery pointers. We will
probably need to support that at some point, but this lets us improve our
coverage for now.

Differential Revision: https://phabricator.services.mozilla.com/D73221
This commit is contained in:
Jan de Mooij 2020-05-01 14:04:48 +00:00
parent 08e90de1af
commit 4bee254594
5 changed files with 84 additions and 2 deletions

View File

@ -699,6 +699,68 @@ void ICStub::trace(JSTracer* trc) {
}
}
bool ICStub::stubDataHasNurseryPointers(const CacheIRStubInfo* stubInfo) {
MOZ_ASSERT(IsCacheIRKind(kind()));
uint32_t field = 0;
size_t offset = 0;
while (true) {
StubField::Type fieldType = stubInfo->fieldType(field);
switch (fieldType) {
case StubField::Type::RawWord:
case StubField::Type::RawInt64:
case StubField::Type::DOMExpandoGeneration:
break;
case StubField::Type::Shape:
static_assert(std::is_convertible_v<Shape*, gc::TenuredCell*>,
"Code assumes shapes are tenured");
break;
case StubField::Type::ObjectGroup:
static_assert(std::is_convertible_v<ObjectGroup*, gc::TenuredCell*>,
"Code assumes groups are tenured");
break;
case StubField::Type::Symbol:
static_assert(std::is_convertible_v<JS::Symbol*, gc::TenuredCell*>,
"Code assumes symbols are tenured");
break;
case StubField::Type::JSObject: {
JSObject* obj = stubInfo->getStubField<ICStub, JSObject*>(this, offset);
if (IsInsideNursery(obj)) {
return true;
}
break;
}
case StubField::Type::String: {
JSString* str = stubInfo->getStubField<ICStub, JSString*>(this, offset);
if (IsInsideNursery(str)) {
return true;
}
break;
}
case StubField::Type::Id: {
#ifdef DEBUG
// jsid never contains nursery-allocated things.
jsid id = stubInfo->getStubField<ICStub, jsid>(this, offset);
MOZ_ASSERT_IF(id.isGCThing(),
!IsInsideNursery(id.toGCCellPtr().asCell()));
#endif
break;
}
case StubField::Type::Value: {
Value v = stubInfo->getStubField<ICStub, JS::Value>(this, offset);
if (v.isGCThing() && IsInsideNursery(v.toGCThing())) {
return true;
}
break;
}
case StubField::Type::Limit:
return false; // Done. Didn't find any nursery pointers.
}
field++;
offset += StubField::sizeInBytes(fieldType);
}
}
// This helper handles ICState updates/transitions while attaching CacheIR
// stubs.
template <typename IRGenerator, typename... Args>

View File

@ -420,6 +420,8 @@ class ICStub {
void updateCode(JitCode* stubCode);
void trace(JSTracer* trc);
bool stubDataHasNurseryPointers(const CacheIRStubInfo* stubInfo);
static const uint16_t EXPECTED_TRACE_MAGIC = 0b1100011;
template <typename T, typename... Args>

View File

@ -439,7 +439,7 @@
- name: LoadObject
shared: true
transpile: false
transpile: true
args:
result: ObjId
obj: ObjectField

View File

@ -55,6 +55,9 @@ class MOZ_RAII WarpCacheIRTranspiler {
Shape* shapeStubField(uint32_t offset) {
return reinterpret_cast<Shape*>(readStubWord(offset));
}
JSObject* objectStubField(uint32_t offset) {
return reinterpret_cast<JSObject*>(readStubWord(offset));
}
int32_t int32StubField(uint32_t offset) {
return static_cast<int32_t>(readStubWord(offset));
}
@ -216,6 +219,16 @@ bool WarpCacheIRTranspiler::emitLoadEnclosingEnvironment(
return defineOperand(resultId, ins);
}
bool WarpCacheIRTranspiler::emitLoadObject(ObjOperandId resultId,
uint32_t objOffset) {
JSObject* obj = objectStubField(objOffset);
auto* ins = MConstant::NewConstraintlessObject(alloc(), obj);
current->add(ins);
return defineOperand(resultId, ins);
}
bool WarpCacheIRTranspiler::emitLoadDynamicSlotResult(ObjOperandId objId,
uint32_t offsetOffset) {
int32_t offset = int32StubField(offsetOffset);

View File

@ -632,7 +632,6 @@ AbortReasonOr<Ok> WarpOracle::maybeInlineIC(WarpOpSnapshotList& snapshots,
}
// TODO: check stub's hit count if we're not doing eager compilation.
// TODO: check stub data for nursery pointers.
// TODO: don't inline if the IC had unhandled cases => CacheIR is incomplete.
// TOOD: have a consistent bailout => invalidate story. Set a flag on the IC?
@ -655,6 +654,12 @@ AbortReasonOr<Ok> WarpOracle::maybeInlineIC(WarpOpSnapshotList& snapshots,
MOZ_CRASH("Unexpected stub");
}
// TODO: we don't support stubs with nursery pointers for now. Handling this
// well requires special machinery. See bug 1631267.
if (stub->stubDataHasNurseryPointers(stubInfo)) {
return Ok();
}
// Only create a snapshots if all opcodes are supported by the transpiler.
CacheIRReader reader(stubInfo);
while (reader.more()) {