Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/js/src/jit/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 13 kB image not shown  

Quellcode-Bibliothek WarpSnapshot.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: set ts=8 sts=2 et sw=2 tw=80:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "jit/WarpSnapshot.h"

#include "mozilla/DebugOnly.h"

#include <type_traits>

#include "jit/CacheIRCompiler.h"
#include "jit/CacheIRSpewer.h"
#include "js/Printer.h"
#include "vm/EnvironmentObject.h"
#include "vm/GetterSetter.h"
#include "vm/GlobalObject.h"
#include "vm/JSContext.h"

using namespace js;
using namespace js::jit;

static_assert(!std::is_polymorphic_v<WarpOpSnapshot>,
              "WarpOpSnapshot should not have any virtual methods");

WarpSnapshot::WarpSnapshot(JSContext* cx, TempAllocator& alloc,
                           WarpScriptSnapshotList&& scriptSnapshots,
                           const WarpZoneStubsSnapshot& zoneStubs,
                           const WarpBailoutInfo& bailoutInfo,
                           bool needsFinalWarmUpCount)
    : scriptSnapshots_(std::move(scriptSnapshots)),
      zoneStubs_(zoneStubs),
      globalLexicalEnv_(&cx->global()->lexicalEnvironment()),
      globalLexicalEnvThis_(globalLexicalEnv_->thisObject()),
      bailoutInfo_(bailoutInfo),
      nurseryObjects_(alloc) {
#ifdef JS_CACHEIR_SPEW
  needsFinalWarmUpCount_ = needsFinalWarmUpCount;
#endif
}

WarpScriptSnapshot::WarpScriptSnapshot(JSScript* script,
                                       const WarpEnvironment& env,
                                       WarpOpSnapshotList&& opSnapshots,
                                       ModuleObject* moduleObject)
    : script_(script),
      environment_(env),
      opSnapshots_(std::move(opSnapshots)),
      moduleObject_(moduleObject),
      isArrowFunction_(script->isFunction() && script->function()->isArrow()) {}

#ifdef JS_JITSPEW
void WarpSnapshot::dump() const {
  Fprinter out(stderr);
  dump(out);
}

void WarpSnapshot::dump(GenericPrinter& out) const {
  out.printf("WarpSnapshot (0x%p)\n"this);
  out.printf("------------------------------\n");
  out.printf("globalLexicalEnv: 0x%p\n", globalLexicalEnv());
  out.printf("globalLexicalEnvThis: 0x%p\n", globalLexicalEnvThis());
  out.printf("failedBoundsCheck: %u\n", bailoutInfo().failedBoundsCheck());
  out.printf("failedLexicalCheck: %u\n", bailoutInfo().failedLexicalCheck());
  out.printf("\n");

  out.printf("JitZone stubs:\n");
  for (const auto& stub : zoneStubs_) {
    unsigned index = &stub - zoneStubs_.begin();
    out.printf("Stub %u: 0x%p\n", index, stub);
  }
  out.printf("\n");

  out.printf("Nursery objects (%u):\n"unsigned(nurseryObjects_.length()));
  for (size_t i = 0; i < nurseryObjects_.length(); i++) {
    out.printf(" %u: 0x%p\n"unsigned(i), nurseryObjects_[i]);
  }
  out.printf("\n");

  for (auto* scriptSnapshot : scriptSnapshots_) {
    scriptSnapshot->dump(out);
  }
}

void WarpScriptSnapshot::dump(GenericPrinter& out) const {
  out.printf("WarpScriptSnapshot (0x%p)\n"this);
  out.printf("------------------------------\n");
  out.printf("Script: %s:%u:%u (0x%p)\n", script_->filename(),
             script_->lineno(), script_->column().oneOriginValue(),
             static_cast<JSScript*>(script_));
  out.printf(" moduleObject: 0x%p\n", moduleObject());
  out.printf(" isArrowFunction: %u\n", isArrowFunction());

  out.printf(" environment: ");
  environment_.match(
      [&](const NoEnvironment&) { out.printf("None\n"); },
      [&](JSObject* obj) { out.printf("Object: 0x%p\n", obj); },
      [&](const FunctionEnvironment& env) {
        out.printf(
            "Function: callobject template 0x%p, named lambda template: 0x%p\n",
            static_cast<JSObject*>(env.callObjectTemplate),
            static_cast<JSObject*>(env.namedLambdaTemplate));
      });

  out.printf("\n");
  for (const WarpOpSnapshot* snapshot : opSnapshots()) {
    snapshot->dump(out, script_);
    out.printf("\n");
  }
}

static const char* OpSnapshotKindString(WarpOpSnapshot::Kind kind) {
  static const charconst names[] = {
#  define NAME(x) #x,
      WARP_OP_SNAPSHOT_LIST(NAME)
#  undef NAME
  };
  return names[unsigned(kind)];
}

void WarpOpSnapshot::dump(GenericPrinter& out, JSScript* script) const {
  jsbytecode* pc = script->offsetToPC(offset_);
  out.printf(" %s (offset %u, JSOp::%s)\n", OpSnapshotKindString(kind_),
             offset_, CodeName(JSOp(*pc)));

  // Dispatch to dumpData() methods.
  switch (kind_) {
#  define DUMP(kind)             \
    case Kind::kind:             \
      as<kind>()->dumpData(out); \
      break;
    WARP_OP_SNAPSHOT_LIST(DUMP)
#  undef DUMP
  }
}

void WarpArguments::dumpData(GenericPrinter& out) const {
  out.printf(" template: 0x%p\n", templateObj());
}

void WarpRegExp::dumpData(GenericPrinter& out) const {
  out.printf(" hasShared: %u\n", hasShared());
}

void WarpBuiltinObject::dumpData(GenericPrinter& out) const {
  out.printf(" builtin: 0x%p\n", builtin());
}

void WarpGetIntrinsic::dumpData(GenericPrinter& out) const {
  out.printf(" intrinsic: 0x%016" PRIx64 "\n", intrinsic().asRawBits());
}

void WarpGetImport::dumpData(GenericPrinter& out) const {
  out.printf(" targetEnv: 0x%p\n", targetEnv());
  out.printf(" numFixedSlots: %u\n", numFixedSlots());
  out.printf(" slot: %u\n", slot());
  out.printf(" needsLexicalCheck: %u\n", needsLexicalCheck());
}

void WarpRest::dumpData(GenericPrinter& out) const {
  out.printf(" shape: 0x%p\n", shape());
}

void WarpBindUnqualifiedGName::dumpData(GenericPrinter& out) const {
  out.printf(" globalEnv: 0x%p\n", globalEnv());
}

void WarpVarEnvironment::dumpData(GenericPrinter& out) const {
  out.printf(" template: 0x%p\n", templateObj());
}

void WarpLexicalEnvironment::dumpData(GenericPrinter& out) const {
  out.printf(" template: 0x%p\n", templateObj());
}

void WarpClassBodyEnvironment::dumpData(GenericPrinter& out) const {
  out.printf(" template: 0x%p\n", templateObj());
}

void WarpBailout::dumpData(GenericPrinter& out) const {
  // No fields.
}

void WarpCacheIR::dumpData(GenericPrinter& out) const {
  out.printf(" stubCode: 0x%p\n"static_cast<JitCode*>(stubCode_));
  out.printf(" stubInfo: 0x%p\n", stubInfo_);
  out.printf(" stubData: 0x%p\n", stubData_);
#  ifdef JS_CACHEIR_SPEW
  out.printf(" IR:\n");
  SpewCacheIROps(out, " ", stubInfo_);
#  else
  out.printf("(CacheIR spew unavailable)\n");
#  endif
}

void WarpInlinedCall::dumpData(GenericPrinter& out) const {
  out.printf(" scriptSnapshot: 0x%p\n", scriptSnapshot_);
  out.printf(" info: 0x%p\n", info_);
  cacheIRSnapshot_->dumpData(out);
}

void WarpPolymorphicTypes::dumpData(GenericPrinter& out) const {
  out.printf(" types:\n");
  for (auto& typeData : list_) {
    out.printf(" %s\n", ValTypeToString(typeData.type()));
  }
}

#endif  // JS_JITSPEW

void WarpSnapshot::trace(JSTracer* trc) {
  // Nursery objects can be tenured in parallel with Warp compilation.
  // Note: don't use TraceOffthreadGCPtr here as that asserts non-moving.
  for (size_t i = 0; i < nurseryObjects_.length(); i++) {
    TraceManuallyBarrieredEdge(trc, &nurseryObjects_[i], "warp-nursery-object");
  }

  // Other GC things are not in the nursery.
  if (trc->runtime()->heapState() == JS::HeapState::MinorCollecting) {
    return;
  }

  for (auto* script : scriptSnapshots_) {
    script->trace(trc);
  }
  for (JitCode* stub : zoneStubs_) {
    if (stub) {
      OffthreadGCPtr<JitCode*> ptr(stub);
      TraceOffthreadGCPtr(trc, ptr, "warp-zone-stub");
    }
  }
  TraceOffthreadGCPtr(trc, globalLexicalEnv_, "warp-lexical");
  TraceOffthreadGCPtr(trc, globalLexicalEnvThis_, "warp-lexicalthis");
}

void WarpScriptSnapshot::trace(JSTracer* trc) {
  TraceOffthreadGCPtr(trc, script_, "warp-script");

  environment_.match([](const NoEnvironment&) {},
                     [trc](OffthreadGCPtr<JSObject*>& obj) {
                       TraceOffthreadGCPtr(trc, obj, "warp-env-object");
                     },
                     [trc](FunctionEnvironment& env) {
                       if (env.callObjectTemplate) {
                         TraceOffthreadGCPtr(trc, env.callObjectTemplate,
                                             "warp-env-callobject");
                       }
                       if (env.namedLambdaTemplate) {
                         TraceOffthreadGCPtr(trc, env.namedLambdaTemplate,
                                             "warp-env-namedlambda");
                       }
                     });

  for (WarpOpSnapshot* snapshot : opSnapshots_) {
    snapshot->trace(trc);
  }

  if (moduleObject_) {
    TraceOffthreadGCPtr(trc, moduleObject_, "warp-module-obj");
  }
}

void WarpOpSnapshot::trace(JSTracer* trc) {
  // Dispatch to traceData() methods.
  switch (kind_) {
#define TRACE(kind)             \
  case Kind::kind:              \
    as<kind>()->traceData(trc); \
    break;
    WARP_OP_SNAPSHOT_LIST(TRACE)
#undef TRACE
  }
}

void WarpArguments::traceData(JSTracer* trc) {
  if (templateObj_) {
    TraceOffthreadGCPtr(trc, templateObj_, "warp-args-template");
  }
}

void WarpRegExp::traceData(JSTracer* trc) {
  // No GC pointers.
}

void WarpBuiltinObject::traceData(JSTracer* trc) {
  TraceOffthreadGCPtr(trc, builtin_, "warp-builtin-object");
}

void WarpGetIntrinsic::traceData(JSTracer* trc) {
  TraceOffthreadGCPtr(trc, intrinsic_, "warp-intrinsic");
}

void WarpGetImport::traceData(JSTracer* trc) {
  TraceOffthreadGCPtr(trc, targetEnv_, "warp-import-env");
}

void WarpRest::traceData(JSTracer* trc) {
  TraceOffthreadGCPtr(trc, shape_, "warp-rest-shape");
}

void WarpBindUnqualifiedGName::traceData(JSTracer* trc) {
  TraceOffthreadGCPtr(trc, globalEnv_, "warp-bindunqualifiedgname-globalenv");
}

void WarpVarEnvironment::traceData(JSTracer* trc) {
  TraceOffthreadGCPtr(trc, templateObj_, "warp-varenv-template");
}

void WarpLexicalEnvironment::traceData(JSTracer* trc) {
  TraceOffthreadGCPtr(trc, templateObj_, "warp-lexenv-template");
}

void WarpClassBodyEnvironment::traceData(JSTracer* trc) {
  TraceOffthreadGCPtr(trc, templateObj_, "warp-classbodyenv-template");
}

void WarpBailout::traceData(JSTracer* trc) {
  // No GC pointers.
}

void WarpPolymorphicTypes::traceData(JSTracer* trc) {
  // No GC pointers.
}

template <typename T>
static void TraceWarpStubPtr(JSTracer* trc, uintptr_t word, const char* name) {
  T* ptr = reinterpret_cast<T*>(word);
  TraceOffthreadGCPtr(trc, OffthreadGCPtr<T*>(ptr), name);
}

void WarpCacheIR::traceData(JSTracer* trc) {
  TraceOffthreadGCPtr(trc, stubCode_, "warp-stub-code");
  if (stubData_) {
    uint32_t field = 0;
    size_t offset = 0;
    while (true) {
      StubField::Type fieldType = stubInfo_->fieldType(field);
      switch (fieldType) {
        case StubField::Type::RawInt32:
        case StubField::Type::RawPointer:
        case StubField::Type::RawInt64:
        case StubField::Type::Double:
          break;
        case StubField::Type::Shape:
        case StubField::Type::WeakShape: {
          // WeakShape pointers are traced strongly in this context.
          uintptr_t word = stubInfo_->getStubRawWord(stubData_, offset);
          TraceWarpStubPtr<Shape>(trc, word, "warp-cacheir-shape");
          break;
        }
        case StubField::Type::WeakGetterSetter: {
          // WeakGetterSetter pointers are traced strongly in this context.
          uintptr_t word = stubInfo_->getStubRawWord(stubData_, offset);
          TraceWarpStubPtr<GetterSetter>(trc, word,
                                         "warp-cacheir-getter-setter");
          break;
        }
        case StubField::Type::JSObject:
        case StubField::Type::WeakObject: {
          // WeakObject pointers are traced strongly in this context.
          uintptr_t word = stubInfo_->getStubRawWord(stubData_, offset);
          WarpObjectField field = WarpObjectField::fromData(word);
          if (!field.isNurseryIndex()) {
            TraceWarpStubPtr<JSObject>(trc, word, "warp-cacheir-object");
          }
          break;
        }
        case StubField::Type::Symbol: {
          uintptr_t word = stubInfo_->getStubRawWord(stubData_, offset);
          TraceWarpStubPtr<JS::Symbol>(trc, word, "warp-cacheir-symbol");
          break;
        }
        case StubField::Type::String: {
          uintptr_t word = stubInfo_->getStubRawWord(stubData_, offset);
          TraceWarpStubPtr<JSString>(trc, word, "warp-cacheir-string");
          break;
        }
        case StubField::Type::WeakBaseScript: {
          // WeakBaseScript pointers are traced strongly in this context.
          uintptr_t word = stubInfo_->getStubRawWord(stubData_, offset);
          TraceWarpStubPtr<BaseScript>(trc, word, "warp-cacheir-script");
          break;
        }
        case StubField::Type::JitCode: {
          uintptr_t word = stubInfo_->getStubRawWord(stubData_, offset);
          TraceWarpStubPtr<JitCode>(trc, word, "warp-cacheir-jitcode");
          break;
        }
        case StubField::Type::Id: {
          uintptr_t word = stubInfo_->getStubRawWord(stubData_, offset);
          jsid id = jsid::fromRawBits(word);
          TraceOffthreadGCPtr(trc, OffthreadGCPtr<jsid>(id),
                              "warp-cacheir-jsid");
          break;
        }
        case StubField::Type::Value: {
          uint64_t data = stubInfo_->getStubRawInt64(stubData_, offset);
          Value val = Value::fromRawBits(data);
          TraceOffthreadGCPtr(trc, OffthreadGCPtr<Value>(val),
                              "warp-cacheir-value");
          break;
        }
        case StubField::Type::AllocSite: {
          mozilla::DebugOnly<uintptr_t> word =
              stubInfo_->getStubRawWord(stubData_, offset);
          MOZ_ASSERT(word == uintptr_t(gc::Heap::Default) ||
                     word == uintptr_t(gc::Heap::Tenured));
          break;
        }
        case StubField::Type::Limit:
          return;  // Done.
      }
      field++;
      offset += StubField::sizeInBytes(fieldType);
    }
  }
}

void WarpInlinedCall::traceData(JSTracer* trc) {
  // Note: scriptSnapshot_ is traced through WarpSnapshot.
  cacheIRSnapshot_->trace(trc);
}

Messung V0.5
C=97 H=96 G=96

¤ Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.0.12Bemerkung:  (vorverarbeitet)  ¤

*Bot Zugriff






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.