зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1661728: Remove ICScript::jitScript_ r=jandem
The bug here occurs when we: a) Trial-inline A into B, creating an ICScript owned by B with a pointer to A's JitScript. b) Perform a compacting GC, discarding the JitScript for A, but preserving the JitScript for B (because it is on the stack). c) Create a new JitScript for A. d) Warp-compile B, without hitting the B->A trial-inlined call IC. In this case, the `JitScript*` stored in the ICScript created in `a)` is dangling, and does not match the JitScript created in `c)`. The easy way to fix this is to not store a `JitScript*` here in the first place. We only use `ICScript::jitScript_` to: a) Tell whether the ICScript is inlined, which can be done more easily by looking at the depth. b) Find the `FallbackICStubSpace` for non-inlined ICScripts. If we use the depth to tell when an ICScript is inlined, then we don't need a pointer to find the owning JitScript (and therefore its stub space) for non-inlined ICScripts. Non-inlined ICScripts are embedded inside a JitScript, so we can compute the offset directly. Differential Revision: https://phabricator.services.mozilla.com/D88690
This commit is contained in:
Родитель
68abfa3c44
Коммит
d12c86aa57
|
@ -62,8 +62,8 @@ JitScript::JitScript(JSScript* script, Offset typeSetOffset,
|
|||
typeSetOffset_(typeSetOffset),
|
||||
bytecodeTypeMapOffset_(bytecodeTypeMapOffset),
|
||||
endOffset_(endOffset),
|
||||
icScript_(this, script->getWarmUpCount(),
|
||||
typeSetOffset - offsetOfICScript(), /*depth=*/0) {
|
||||
icScript_(script->getWarmUpCount(), typeSetOffset - offsetOfICScript(),
|
||||
/*depth=*/0) {
|
||||
setTypesGeneration(script->zone()->types.generation);
|
||||
|
||||
if (IsTypeInferenceEnabled()) {
|
||||
|
@ -269,8 +269,6 @@ void ICScript::trace(JSTracer* trc) {
|
|||
}
|
||||
}
|
||||
|
||||
bool ICScript::isInlined() const { return jitScript()->icScript() != this; }
|
||||
|
||||
bool ICScript::addInlinedChild(JSContext* cx, UniquePtr<ICScript> child,
|
||||
uint32_t pcOffset) {
|
||||
if (!inlinedChildren_) {
|
||||
|
@ -877,8 +875,14 @@ InliningRoot* JitScript::getOrCreateInliningRoot(JSContext* cx,
|
|||
}
|
||||
|
||||
FallbackICStubSpace* ICScript::fallbackStubSpace() {
|
||||
if (inliningRoot_) {
|
||||
if (isInlined()) {
|
||||
return inliningRoot_->fallbackStubSpace();
|
||||
}
|
||||
return jitScript_->fallbackStubSpace();
|
||||
return outerJitScript()->fallbackStubSpace();
|
||||
}
|
||||
|
||||
JitScript* ICScript::outerJitScript() {
|
||||
MOZ_ASSERT(!isInlined());
|
||||
uint8_t* ptr = reinterpret_cast<uint8_t*>(this);
|
||||
return reinterpret_cast<JitScript*>(ptr - JitScript::offsetOfICScript());
|
||||
}
|
||||
|
|
|
@ -92,17 +92,14 @@ class InliningRoot;
|
|||
|
||||
class alignas(uintptr_t) ICScript final : public TrailingArray {
|
||||
public:
|
||||
ICScript(JitScript* jitScript, uint32_t warmUpCount, Offset endOffset,
|
||||
uint32_t depth, InliningRoot* inliningRoot = nullptr)
|
||||
: jitScript_(jitScript),
|
||||
inliningRoot_(inliningRoot),
|
||||
ICScript(uint32_t warmUpCount, Offset endOffset, uint32_t depth,
|
||||
InliningRoot* inliningRoot = nullptr)
|
||||
: inliningRoot_(inliningRoot),
|
||||
warmUpCount_(warmUpCount),
|
||||
endOffset_(endOffset),
|
||||
depth_(depth) {}
|
||||
|
||||
JitScript* jitScript() const { return jitScript_; }
|
||||
|
||||
bool isInlined() const;
|
||||
bool isInlined() const { return depth_ > 0; }
|
||||
|
||||
MOZ_MUST_USE bool initICEntries(JSContext* cx, JSScript* script);
|
||||
|
||||
|
@ -157,11 +154,6 @@ class alignas(uintptr_t) ICScript final : public TrailingArray {
|
|||
uint32_t pcOffset_;
|
||||
};
|
||||
|
||||
// Pointer to the owning JitScript. If this ICScript is not
|
||||
// a clone for inlining, `this->jitScript_ + JitScript::offsetOfICScript()`
|
||||
// should equal `this`.
|
||||
JitScript* jitScript_;
|
||||
|
||||
// If this ICScript was created for trial inlining or has another
|
||||
// ICScript inlined into it, a pointer to the root of the inlining
|
||||
// tree. Otherwise, nullptr.
|
||||
|
@ -186,6 +178,8 @@ class alignas(uintptr_t) ICScript final : public TrailingArray {
|
|||
|
||||
ICEntry* icEntries() { return offsetToPointer<ICEntry>(icEntriesOffset()); }
|
||||
|
||||
JitScript* outerJitScript();
|
||||
|
||||
friend class JitScript;
|
||||
};
|
||||
|
||||
|
|
|
@ -226,7 +226,6 @@ ICScript* TrialInliner::createInlinedICScript(JSFunction* target,
|
|||
MOZ_ASSERT(target->hasJitScript());
|
||||
|
||||
JSScript* targetScript = target->baseScript()->asJSScript();
|
||||
JitScript* targetJitScript = targetScript->jitScript();
|
||||
|
||||
// We don't have to check for overflow here because we have already
|
||||
// successfully allocated an ICScript with this number of entries
|
||||
|
@ -247,8 +246,8 @@ ICScript* TrialInliner::createInlinedICScript(JSFunction* target,
|
|||
const uint32_t InitialWarmUpCount = 0;
|
||||
|
||||
uint32_t depth = icScript_->depth() + 1;
|
||||
UniquePtr<ICScript> inlinedICScript(new (raw) ICScript(
|
||||
targetJitScript, InitialWarmUpCount, allocSize, depth, root_));
|
||||
UniquePtr<ICScript> inlinedICScript(
|
||||
new (raw) ICScript(InitialWarmUpCount, allocSize, depth, root_));
|
||||
|
||||
{
|
||||
// Suppress GC. This matches the AutoEnterAnalysis in
|
||||
|
|
|
@ -969,7 +969,6 @@ AbortReasonOr<bool> WarpScriptOracle::maybeInlineCallIC(
|
|||
if (!TrialInliner::canInline(targetFunction, script_)) {
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(targetScript->jitScript() == icScript->jitScript());
|
||||
|
||||
// Add the inlined script to the inline script tree.
|
||||
LifoAlloc* lifoAlloc = alloc_.lifoAlloc();
|
||||
|
|
Загрузка…
Ссылка в новой задаче