mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 15:25:52 +00:00
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:
parent
08e90de1af
commit
4bee254594
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -439,7 +439,7 @@
|
||||
|
||||
- name: LoadObject
|
||||
shared: true
|
||||
transpile: false
|
||||
transpile: true
|
||||
args:
|
||||
result: ObjId
|
||||
obj: ObjectField
|
||||
|
@ -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);
|
||||
|
@ -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()) {
|
||||
|
Loading…
Reference in New Issue
Block a user