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:
Jan de Mooij 2019-02-06 07:56:17 +00:00
Родитель 0598a8a3b9
Коммит 15b5b64c02
7 изменённых файлов: 48 добавлений и 41 удалений

Просмотреть файл

@ -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();