зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1524499 part 1 - Move active flag from BaselineScript to TypeScript. r=tcampbell
Baseline interpreter frames will have a TypeScript/ICScript we want to keep around on GC. The JSScript::typesDontCheckGeneration method will be removed in the next patch. Differential Revision: https://phabricator.services.mozilla.com/D18548 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
0598a8a3b9
Коммит
15b5b64c02
|
@ -206,17 +206,18 @@ void Zone::discardJitCode(FreeOp* fop,
|
|||
return;
|
||||
}
|
||||
|
||||
if (discardBaselineCode) {
|
||||
if (discardBaselineCode || releaseTypes) {
|
||||
#ifdef DEBUG
|
||||
/* Assert no baseline scripts are marked as active. */
|
||||
// Assert no TypeScripts are marked as active.
|
||||
for (auto script = cellIter<JSScript>(); !script.done(); script.next()) {
|
||||
MOZ_ASSERT_IF(script->hasBaselineScript(),
|
||||
!script->baselineScript()->active());
|
||||
if (TypeScript* types = script->typesDontCheckGeneration()) {
|
||||
MOZ_ASSERT(!types->active());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Mark baseline scripts on the stack as active. */
|
||||
jit::MarkActiveBaselineScripts(this);
|
||||
// Mark TypeScripts on the stack as active.
|
||||
jit::MarkActiveTypeScripts(this);
|
||||
}
|
||||
|
||||
/* Only mark OSI points if code is being discarded. */
|
||||
|
@ -262,6 +263,11 @@ void Zone::discardJitCode(FreeOp* fop,
|
|||
if (discardBaselineCode && script->hasICScript()) {
|
||||
script->icScript()->purgeOptimizedStubs(script);
|
||||
}
|
||||
|
||||
// Finally, reset the active flag.
|
||||
if (TypeScript* types = script->typesDontCheckGeneration()) {
|
||||
types->resetActive();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1142,11 +1142,7 @@ void jit::FinishDiscardBaselineScript(FreeOp* fop, JSScript* script) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (script->baselineScript()->active()) {
|
||||
// Reset |active| flag so that we don't need a separate script
|
||||
// iteration to unmark them.
|
||||
script->baselineScript()->resetActive();
|
||||
|
||||
if (script->typesDontCheckGeneration()->active()) {
|
||||
// The baseline caches have been wiped out, so the script will need to
|
||||
// warm back up before it can be inlined during Ion compilation.
|
||||
script->baselineScript()->clearIonCompiledOrInlined();
|
||||
|
@ -1216,31 +1212,31 @@ void jit::ToggleBaselineTraceLoggerEngine(JSRuntime* runtime, bool enable) {
|
|||
}
|
||||
#endif
|
||||
|
||||
static void MarkActiveBaselineScripts(JSContext* cx,
|
||||
const JitActivationIterator& activation) {
|
||||
static void MarkActiveTypeScripts(JSContext* cx,
|
||||
const JitActivationIterator& activation) {
|
||||
for (OnlyJSJitFrameIter iter(activation); !iter.done(); ++iter) {
|
||||
const JSJitFrameIter& frame = iter.frame();
|
||||
switch (frame.type()) {
|
||||
case FrameType::BaselineJS:
|
||||
frame.script()->baselineScript()->setActive();
|
||||
frame.script()->typesDontCheckGeneration()->setActive();
|
||||
break;
|
||||
case FrameType::Exit:
|
||||
if (frame.exitFrame()->is<LazyLinkExitFrameLayout>()) {
|
||||
LazyLinkExitFrameLayout* ll =
|
||||
frame.exitFrame()->as<LazyLinkExitFrameLayout>();
|
||||
ScriptFromCalleeToken(ll->jsFrame()->calleeToken())
|
||||
->baselineScript()
|
||||
->setActive();
|
||||
JSScript* script =
|
||||
ScriptFromCalleeToken(ll->jsFrame()->calleeToken());
|
||||
script->typesDontCheckGeneration()->setActive();
|
||||
}
|
||||
break;
|
||||
case FrameType::Bailout:
|
||||
case FrameType::IonJS: {
|
||||
// Keep the baseline script around, since bailouts from the ion
|
||||
// jitcode might need to re-enter into the baseline jitcode.
|
||||
frame.script()->baselineScript()->setActive();
|
||||
// Keep the TypeScript and BaselineScript around, since bailouts from
|
||||
// the ion jitcode need to re-enter into the Baseline code.
|
||||
frame.script()->typesDontCheckGeneration()->setActive();
|
||||
for (InlineFrameIterator inlineIter(cx, &frame); inlineIter.more();
|
||||
++inlineIter) {
|
||||
inlineIter.script()->baselineScript()->setActive();
|
||||
inlineIter.script()->typesDontCheckGeneration()->setActive();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1249,14 +1245,14 @@ static void MarkActiveBaselineScripts(JSContext* cx,
|
|||
}
|
||||
}
|
||||
|
||||
void jit::MarkActiveBaselineScripts(Zone* zone) {
|
||||
void jit::MarkActiveTypeScripts(Zone* zone) {
|
||||
if (zone->isAtomsZone()) {
|
||||
return;
|
||||
}
|
||||
JSContext* cx = TlsContext.get();
|
||||
for (JitActivationIterator iter(cx); !iter.done(); ++iter) {
|
||||
if (iter->compartment()->zone() == zone) {
|
||||
MarkActiveBaselineScripts(cx, iter);
|
||||
MarkActiveTypeScripts(cx, iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -252,11 +252,7 @@ struct BaselineScript final {
|
|||
|
||||
public:
|
||||
enum Flag {
|
||||
// (1 << 0) is unused.
|
||||
|
||||
// Flag set when discarding JIT code, to indicate this script is
|
||||
// on the stack and should not be discarded.
|
||||
ACTIVE = 1 << 1,
|
||||
// (1 << 0) and (1 << 1) are unused.
|
||||
|
||||
// Flag set when the script contains any writes to its on-stack
|
||||
// (rather than call object stored) arguments.
|
||||
|
@ -354,10 +350,6 @@ struct BaselineScript final {
|
|||
*data += mallocSizeOf(this);
|
||||
}
|
||||
|
||||
bool active() const { return flags_ & ACTIVE; }
|
||||
void setActive() { flags_ |= ACTIVE; }
|
||||
void resetActive() { flags_ &= ~ACTIVE; }
|
||||
|
||||
void setModifiesArguments() { flags_ |= MODIFIES_ARGUMENTS; }
|
||||
bool modifiesArguments() { return flags_ & MODIFIES_ARGUMENTS; }
|
||||
|
||||
|
@ -632,9 +624,9 @@ MOZ_MUST_USE bool BailoutIonToBaseline(
|
|||
bool invalidate, BaselineBailoutInfo** bailoutInfo,
|
||||
const ExceptionBailoutInfo* exceptionInfo);
|
||||
|
||||
// Mark baseline scripts on the stack as active, so that they are not discarded
|
||||
// Mark TypeScripts on the stack as active, so that they are not discarded
|
||||
// during GC.
|
||||
void MarkActiveBaselineScripts(Zone* zone);
|
||||
void MarkActiveTypeScripts(Zone* zone);
|
||||
|
||||
MethodStatus BaselineCompile(JSContext* cx, JSScript* script,
|
||||
bool forceDebugInstrumentation = false);
|
||||
|
|
|
@ -2705,10 +2705,10 @@ class MOZ_RAII ExecutionObservableScript
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline void MarkBaselineScriptActiveIfObservable(
|
||||
static inline void MarkTypeScriptActiveIfObservable(
|
||||
JSScript* script, const Debugger::ExecutionObservableSet& obs) {
|
||||
if (obs.shouldRecompileOrInvalidate(script)) {
|
||||
script->baselineScript()->setActive();
|
||||
script->typesDontCheckGeneration()->setActive();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2772,13 +2772,13 @@ static bool UpdateExecutionObservabilityOfScriptsInZone(
|
|||
const JSJitFrameIter& frame = iter.frame();
|
||||
switch (frame.type()) {
|
||||
case FrameType::BaselineJS:
|
||||
MarkBaselineScriptActiveIfObservable(frame.script(), obs);
|
||||
MarkTypeScriptActiveIfObservable(frame.script(), obs);
|
||||
break;
|
||||
case FrameType::IonJS:
|
||||
MarkBaselineScriptActiveIfObservable(frame.script(), obs);
|
||||
MarkTypeScriptActiveIfObservable(frame.script(), obs);
|
||||
for (InlineFrameIterator inlineIter(cx, &frame); inlineIter.more();
|
||||
++inlineIter) {
|
||||
MarkBaselineScriptActiveIfObservable(inlineIter.script(), obs);
|
||||
MarkTypeScriptActiveIfObservable(inlineIter.script(), obs);
|
||||
}
|
||||
break;
|
||||
default:;
|
||||
|
@ -2792,6 +2792,7 @@ static bool UpdateExecutionObservabilityOfScriptsInZone(
|
|||
for (size_t i = 0; i < scripts.length(); i++) {
|
||||
MOZ_ASSERT_IF(scripts[i]->isDebuggee(), observing);
|
||||
FinishDiscardBaselineScript(fop, scripts[i]);
|
||||
scripts[i]->typesDontCheckGeneration()->resetActive();
|
||||
}
|
||||
|
||||
// Iterate through all wasm instances to find ones that need to be updated.
|
||||
|
|
|
@ -2423,6 +2423,8 @@ class JSScript : public js::gc::TenuredCell {
|
|||
inline js::TypeScript* types(const js::AutoSweepTypeScript& sweep);
|
||||
inline bool typesNeedsSweep() const;
|
||||
|
||||
js::TypeScript* typesDontCheckGeneration() { return types_; }
|
||||
|
||||
void maybeReleaseTypes();
|
||||
void sweepTypes(const js::AutoSweepTypeScript& sweep);
|
||||
|
||||
|
|
|
@ -3596,7 +3596,8 @@ TypeScript::TypeScript(JSScript* script, ICScriptPtr&& icScript,
|
|||
uint32_t numTypeSets)
|
||||
: icScript_(std::move(icScript)),
|
||||
numTypeSets_(numTypeSets),
|
||||
bytecodeTypeMapHint_(0) {
|
||||
bytecodeTypeMapHint_(0),
|
||||
active_(false) {
|
||||
StackTypeSet* array = typeArray();
|
||||
for (unsigned i = 0; i < numTypeSets; i++) {
|
||||
new (&array[i]) StackTypeSet();
|
||||
|
@ -4743,7 +4744,8 @@ void ObjectGroup::sweep(const AutoSweepObjectGroup& sweep) {
|
|||
}
|
||||
|
||||
void JSScript::maybeReleaseTypes() {
|
||||
if (!types_ || zone()->types.keepTypeScripts || hasBaselineScript()) {
|
||||
if (!types_ || zone()->types.keepTypeScripts || hasBaselineScript() ||
|
||||
types_->active()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -220,6 +220,10 @@ class TypeScript {
|
|||
// bytecode map queries are in linear order.
|
||||
uint32_t bytecodeTypeMapHint_;
|
||||
|
||||
// Flag set when discarding JIT code to indicate this script is on the stack
|
||||
// and type information and JIT code should not be discarded.
|
||||
bool active_;
|
||||
|
||||
// Variable-size array. This is followed by the bytecode type map.
|
||||
StackTypeSet typeArray_[1];
|
||||
|
||||
|
@ -238,6 +242,10 @@ class TypeScript {
|
|||
|
||||
uint32_t* bytecodeTypeMapHint() { return &bytecodeTypeMapHint_; }
|
||||
|
||||
bool active() const { return active_; }
|
||||
void setActive() { active_ = true; }
|
||||
void resetActive() { active_ = false; }
|
||||
|
||||
jit::ICScript* icScript() const {
|
||||
MOZ_ASSERT(icScript_);
|
||||
return icScript_.get();
|
||||
|
|
Загрузка…
Ссылка в новой задаче