Commit 72207a27 authored by Jan de Mooij's avatar Jan de Mooij
Browse files

Bug 1571446 part 3 - Combine JSScript's jitScript_ and warmUpCount_ fields in...

Bug 1571446 part 3 - Combine JSScript's jitScript_ and warmUpCount_ fields in a single warmUpData_ field. r=tcampbell

The warm-up count is stored in ScriptWarmUpData until the script is warm
enough for the Baseline Interpreter and the JitScript is created. At that point
we use the warm-up count stored in JitScript.

ScriptWarmUpData uses pointer tagging. This should make it easy to add new
types for LazyScript data in the future.

Differential Revision: https://phabricator.services.mozilla.com/D42319

--HG--
extra : moz-landing-system : lando
parent 49cb992e
Loading
Loading
Loading
Loading
+15 −13
Original line number Diff line number Diff line
@@ -1126,7 +1126,7 @@ void BaselineInterpreterCodeGen::emitInitFrameFields(Register nonFunctionEnv) {
  masm.storePtr(scratch1, frame.addressOfInterpreterScript());

  // Initialize interpreterICEntry.
  masm.loadPtr(Address(scratch1, JSScript::offsetOfJitScript()), scratch2);
  masm.loadJitScript(scratch1, scratch2);
  masm.computeEffectiveAddress(
      Address(scratch2, JitScript::offsetOfICEntries()), scratch2);
  masm.storePtr(scratch2, frame.addressOfInterpreterICEntry());
@@ -1284,9 +1284,12 @@ bool BaselineCompilerCodeGen::emitWarmUpCounterIncrement() {

  Register scriptReg = R2.scratchReg();
  Register countReg = R0.scratchReg();
  Address warmUpCounterAddr(scriptReg, JSScript::offsetOfWarmUpCounter());

  masm.movePtr(ImmGCPtr(script), scriptReg);
  // Load the JitScript* in scriptReg.
  masm.movePtr(ImmPtr(script->jitScript()), scriptReg);

  // Bump warm-up counter.
  Address warmUpCounterAddr(scriptReg, JitScript::offsetOfWarmUpCount());
  masm.load32(warmUpCounterAddr, countReg);
  masm.add32(Imm32(1), countReg);
  masm.store32(countReg, warmUpCounterAddr);
@@ -1313,7 +1316,6 @@ bool BaselineCompilerCodeGen::emitWarmUpCounterIncrement() {

  // Do nothing if Ion is already compiling this script off-thread or if Ion has
  // been disabled for this script.
  masm.movePtr(ImmPtr(script->jitScript()), scriptReg);
  masm.loadPtr(Address(scriptReg, JitScript::offsetOfIonScript()), scriptReg);
  masm.branchPtr(Assembler::Equal, scriptReg, ImmPtr(IonCompilingScriptPtr),
                 &done);
@@ -1419,9 +1421,12 @@ bool BaselineInterpreterCodeGen::emitWarmUpCounterIncrement() {
  Register scriptReg = R2.scratchReg();
  Register countReg = R0.scratchReg();

  // Bump warm-up counter.
  Address warmUpCounterAddr(scriptReg, JSScript::offsetOfWarmUpCounter());
  // Load the JitScript* in scriptReg.
  loadScript(scriptReg);
  masm.loadJitScript(scriptReg, scriptReg);

  // Bump warm-up counter.
  Address warmUpCounterAddr(scriptReg, JitScript::offsetOfWarmUpCount());
  masm.load32(warmUpCounterAddr, countReg);
  masm.add32(Imm32(1), countReg);
  masm.store32(countReg, warmUpCounterAddr);
@@ -1431,7 +1436,6 @@ bool BaselineInterpreterCodeGen::emitWarmUpCounterIncrement() {
  Label done;
  masm.branch32(Assembler::BelowOrEqual, countReg,
                Imm32(JitOptions.baselineJitWarmUpThreshold), &done);
  masm.loadPtr(Address(scriptReg, JSScript::offsetOfJitScript()), scriptReg);
  masm.branchPtr(Assembler::Equal,
                 Address(scriptReg, JitScript::offsetOfBaselineScript()),
                 ImmPtr(BaselineDisabledScriptPtr), &done);
@@ -6051,7 +6055,7 @@ bool BaselineCodeGen<Handler>::emitEnterGeneratorCode(Register script,
                "Comparison below requires specific sentinel encoding");

  Label noBaselineScript;
  masm.loadPtr(Address(script, JSScript::offsetOfJitScript()), scratch);
  masm.loadJitScript(script, scratch);
  masm.loadPtr(Address(scratch, JitScript::offsetOfBaselineScript()), scratch);
  masm.branchPtr(Assembler::BelowOrEqual, scratch,
                 ImmPtr(BaselineDisabledScriptPtr), &noBaselineScript);
@@ -6109,15 +6113,13 @@ bool BaselineCodeGen<Handler>::emitGeneratorResume(
  Label interpret;
  Register scratch1 = regs.takeAny();
  masm.loadPtr(Address(callee, JSFunction::offsetOfScript()), scratch1);
  masm.branchPtr(Assembler::Equal,
                 Address(scratch1, JSScript::offsetOfJitScript()),
                 ImmPtr(nullptr), &interpret);
  masm.branchIfScriptHasNoJitScript(scratch1, &interpret);

#ifdef JS_TRACE_LOGGING
  if (JS::TraceLoggerSupported()) {
    // TODO (bug 1565788): add Baseline Interpreter support.
    MOZ_CRASH("Unimplemented Baseline Interpreter TraceLogger support");
    masm.loadPtr(Address(scratch1, JSScript::offsetOfJitScript()), scratch1);
    masm.loadJitScript(scratch1, scratch1);
    Address baselineAddr(scratch1, JitScript::offsetOfBaselineScript());
    masm.loadPtr(baselineAddr, scratch1);
    if (!emitTraceLoggerResume(scratch1, regs)) {
@@ -6432,7 +6434,7 @@ bool BaselineInterpreterCodeGen::emit_JSOP_JUMPTARGET() {

  // Compute ICEntry* and store to frame->interpreterICEntry.
  loadScript(scratch2);
  masm.loadPtr(Address(scratch2, JSScript::offsetOfJitScript()), scratch2);
  masm.loadJitScript(scratch2, scratch2);
  masm.computeEffectiveAddress(
      BaseIndex(scratch2, scratch1, TimesOne, JitScript::offsetOfICEntries()),
      scratch2);
+14 −1
Original line number Diff line number Diff line
@@ -13331,9 +13331,22 @@ void CodeGenerator::visitRecompileCheck(LRecompileCheck* ins) {
    }
  }

  JitScript* jitScript = ins->mir()->script()->jitScript();

  // The code depends on the JitScript* not being discarded without also
  // invalidating Ion code. Assert this.
#ifdef DEBUG
  Label ok;
  masm.movePtr(ImmGCPtr(ins->mir()->script()), tmp);
  masm.loadJitScript(tmp, tmp);
  masm.branchPtr(Assembler::Equal, tmp, ImmPtr(jitScript), &ok);
  masm.assumeUnreachable("Didn't find JitScript?");
  masm.bind(&ok);
#endif

  // Check if warm-up counter is high enough.
  AbsoluteAddress warmUpCount =
      AbsoluteAddress(ins->mir()->script()->addressOfWarmUpCounter());
      AbsoluteAddress(jitScript->addressOfWarmUpCount());
  if (ins->mir()->increaseWarmUpCounter()) {
    masm.load32(warmUpCount, tmp);
    masm.add32(Imm32(1), tmp);
+2 −0
Original line number Diff line number Diff line
@@ -9,6 +9,8 @@
#include "jit/Ion.h"
#include "vm/JSScript.h"

#include "vm/JSScript-inl.h"

using namespace js;
using namespace js::jit;

+5 −2
Original line number Diff line number Diff line
@@ -55,6 +55,9 @@ JitScript::JitScript(JSScript* script, uint32_t typeSetOffset,
  uint8_t* base = reinterpret_cast<uint8_t*>(this);
  DefaultInitializeElements<StackTypeSet>(base + typeSetOffset, numTypeSets());

  // Initialize the warm-up count from the count stored in the script.
  warmUpCount_ = script->getWarmUpCount();

  // Ensure the baselineScript_ and ionScript_ fields match the BaselineDisabled
  // and IonDisabled script flags.
  if (!script->canBaselineCompile()) {
@@ -142,7 +145,7 @@ bool JSScript::createJitScript(JSContext* cx) {

  MOZ_ASSERT(!hasJitScript());
  prepareForDestruction.release();
  jitScript_ = jitScript.release();
  warmUpData_.setJitScript(jitScript.release());
  AddCellMemory(this, allocSize.value(), MemoryUse::JitScript);

  // We have a JitScript so we can set the script's jitCodeRaw_ pointer to the
@@ -191,7 +194,7 @@ void JSScript::releaseJitScript(JSFreeOp* fop) {
  fop->removeCellMemory(this, jitScript()->allocBytes(), MemoryUse::JitScript);

  JitScript::Destroy(zone(), jitScript());
  jitScript_ = nullptr;
  warmUpData_.clearJitScript();
  updateJitCodeRaw(fop->runtime());
}

+21 −2
Original line number Diff line number Diff line
@@ -7,6 +7,8 @@
#ifndef jit_JitScript_h
#define jit_JitScript_h

#include "mozilla/Atomics.h"

#include "jit/BaselineIC.h"
#include "js/UniquePtr.h"
#include "vm/TypeInference.h"
@@ -178,6 +180,13 @@ class alignas(uintptr_t) JitScript final {
  // IonCompilingScriptPtr or a valid IonScript*.
  IonScript* ionScript_ = nullptr;

  // Number of times the script has been called or has had backedges taken.
  // Reset if the script's JIT code is forcibly discarded. See also the
  // ScriptWarmUpData class.
  mozilla::Atomic<uint32_t, mozilla::Relaxed,
                  mozilla::recordreplay::Behavior::DontPreserve>
      warmUpCount_ = {};

  // Offset of the StackTypeSet array.
  uint32_t typeSetOffset_ = 0;

@@ -392,10 +401,20 @@ class alignas(uintptr_t) JitScript final {
  static constexpr size_t offsetOfJitCodeSkipArgCheck() {
    return offsetof(JitScript, jitCodeSkipArgCheck_);
  }
  static size_t offsetOfBaselineScript() {
  static constexpr size_t offsetOfBaselineScript() {
    return offsetof(JitScript, baselineScript_);
  }
  static size_t offsetOfIonScript() { return offsetof(JitScript, ionScript_); }
  static constexpr size_t offsetOfIonScript() {
    return offsetof(JitScript, ionScript_);
  }
  static constexpr size_t offsetOfWarmUpCount() {
    return offsetof(JitScript, warmUpCount_);
  }

  uint32_t warmUpCount() const { return warmUpCount_; }
  uint32_t* addressOfWarmUpCount() {
    return reinterpret_cast<uint32_t*>(&warmUpCount_);
  }

#ifdef DEBUG
  void printTypes(JSContext* cx, HandleScript script);
Loading