зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1614622 part 3 - Remove optimization tracking from profiler backend, remove forEach API methods. r=djvj
Differential Revision: https://phabricator.services.mozilla.com/D62427 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
79d45d6fcb
Коммит
214eabb067
|
@ -28,9 +28,6 @@ class ProfilingFrameIterator;
|
|||
|
||||
namespace JS {
|
||||
|
||||
struct ForEachTrackedOptimizationAttemptOp;
|
||||
struct ForEachTrackedOptimizationTypeInfoOp;
|
||||
|
||||
// This iterator can be used to walk the stack of a thread suspended at an
|
||||
// arbitrary pc. To provide accurate results, profiling must have been enabled
|
||||
// (via EnableRuntimeProfilingStack) before executing the callstack being
|
||||
|
@ -193,12 +190,6 @@ class MOZ_STACK_CLASS ProfiledFrameHandle {
|
|||
void* canonicalAddress() const { return canonicalAddr_; }
|
||||
|
||||
JS_PUBLIC_API ProfilingFrameIterator::FrameKind frameKind() const;
|
||||
JS_PUBLIC_API void forEachOptimizationAttempt(
|
||||
ForEachTrackedOptimizationAttemptOp& op, JSScript** scriptOut,
|
||||
jsbytecode** pcOut) const;
|
||||
|
||||
JS_PUBLIC_API void forEachOptimizationTypeInfo(
|
||||
ForEachTrackedOptimizationTypeInfoOp& op) const;
|
||||
|
||||
JS_PUBLIC_API uint64_t realmID() const;
|
||||
};
|
||||
|
|
|
@ -202,51 +202,6 @@ JS_PUBLIC_API const char* TrackedOutcomeString(TrackedOutcome outcome);
|
|||
|
||||
JS_PUBLIC_API const char* TrackedTypeSiteString(TrackedTypeSite site);
|
||||
|
||||
struct ForEachTrackedOptimizationAttemptOp {
|
||||
virtual void operator()(TrackedStrategy strategy, TrackedOutcome outcome) = 0;
|
||||
};
|
||||
|
||||
struct ForEachTrackedOptimizationTypeInfoOp {
|
||||
// Called 0+ times per entry, once for each type in the type set that Ion
|
||||
// saw during MIR construction. readType is always called _before_
|
||||
// operator() on the same entry.
|
||||
//
|
||||
// The keyedBy parameter describes how the type is keyed:
|
||||
// - "primitive" for primitive types
|
||||
// - "constructor" for object types tied to a scripted constructor
|
||||
// function.
|
||||
// - "alloc site" for object types tied to an allocation site.
|
||||
// - "prototype" for object types tied neither to a constructor nor
|
||||
// to an allocation site, but to a prototype.
|
||||
// - "singleton" for object types which only has a single value.
|
||||
// - "function" for object types referring to scripted functions.
|
||||
// - "native" for object types referring to native functions.
|
||||
//
|
||||
// The name parameter is the string representation of the type. If the
|
||||
// type is keyed by "constructor", or if the type itself refers to a
|
||||
// scripted function, the name is the function's displayAtom. If the type
|
||||
// is keyed by "native", this is nullptr.
|
||||
//
|
||||
// The location parameter is the filename if the type is keyed by
|
||||
// "constructor", "alloc site", or if the type itself refers to a scripted
|
||||
// function. If the type is keyed by "native", it is the offset of the
|
||||
// native function, suitable for use with addr2line on Linux or atos on OS
|
||||
// X. Otherwise it is nullptr.
|
||||
//
|
||||
// The lineno parameter is the line number if the type is keyed by
|
||||
// "constructor", "alloc site", or if the type itself refers to a scripted
|
||||
// function. Otherwise it is Nothing().
|
||||
//
|
||||
// The location parameter is the only one that may need escaping if being
|
||||
// quoted.
|
||||
virtual void readType(const char* keyedBy, const char* name,
|
||||
const char* location,
|
||||
const mozilla::Maybe<unsigned>& lineno) = 0;
|
||||
|
||||
// Called once per entry.
|
||||
virtual void operator()(TrackedTypeSite site, const char* mirType) = 0;
|
||||
};
|
||||
|
||||
} // namespace JS
|
||||
|
||||
#endif // js_TrackedOptimizationInfo_h
|
||||
|
|
|
@ -358,11 +358,6 @@ class JitcodeGlobalEntry {
|
|||
mozilla::Maybe<uint8_t> trackedOptimizationIndexAtAddr(
|
||||
void* ptr, uint32_t* entryOffsetOut);
|
||||
|
||||
void forEachOptimizationAttempt(
|
||||
uint8_t index, JS::ForEachTrackedOptimizationAttemptOp& op);
|
||||
void forEachOptimizationTypeInfo(
|
||||
uint8_t index, IonTrackedOptimizationsTypeInfo::ForEachOpAdapter& op);
|
||||
|
||||
template <class ShouldTraceProvider>
|
||||
bool trace(JSTracer* trc);
|
||||
void sweepChildren();
|
||||
|
@ -789,47 +784,6 @@ class JitcodeGlobalEntry {
|
|||
return mozilla::Nothing();
|
||||
}
|
||||
|
||||
void forEachOptimizationAttempt(JSRuntime* rt, uint8_t index,
|
||||
JS::ForEachTrackedOptimizationAttemptOp& op) {
|
||||
switch (kind()) {
|
||||
case Ion:
|
||||
ionEntry().forEachOptimizationAttempt(index, op);
|
||||
return;
|
||||
case Baseline:
|
||||
case Dummy:
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Invalid JitcodeGlobalEntry kind.");
|
||||
}
|
||||
}
|
||||
|
||||
void forEachOptimizationTypeInfo(
|
||||
JSRuntime* rt, uint8_t index,
|
||||
IonTrackedOptimizationsTypeInfo::ForEachOpAdapter& op) {
|
||||
switch (kind()) {
|
||||
case Ion:
|
||||
ionEntry().forEachOptimizationTypeInfo(index, op);
|
||||
return;
|
||||
case Baseline:
|
||||
case Dummy:
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Invalid JitcodeGlobalEntry kind.");
|
||||
}
|
||||
}
|
||||
|
||||
IonTrackedOptimizationsAttempts trackedOptimizationAttempts(uint8_t index) {
|
||||
return ionEntry().trackedOptimizationAttempts(index);
|
||||
}
|
||||
|
||||
IonTrackedOptimizationsTypeInfo trackedOptimizationTypeInfo(uint8_t index) {
|
||||
return ionEntry().trackedOptimizationTypeInfo(index);
|
||||
}
|
||||
|
||||
const IonTrackedTypeVector* allTrackedTypes() {
|
||||
return ionEntry().allTrackedTypes();
|
||||
}
|
||||
|
||||
Zone* zone() { return baseEntry().jitcode()->zone(); }
|
||||
|
||||
template <class ShouldTraceProvider>
|
||||
|
|
|
@ -23,8 +23,6 @@ using mozilla::Maybe;
|
|||
using mozilla::Nothing;
|
||||
using mozilla::Some;
|
||||
|
||||
using JS::ForEachTrackedOptimizationAttemptOp;
|
||||
using JS::ForEachTrackedOptimizationTypeInfoOp;
|
||||
using JS::TrackedOutcome;
|
||||
using JS::TrackedStrategy;
|
||||
using JS::TrackedTypeSite;
|
||||
|
@ -419,49 +417,6 @@ Maybe<uint8_t> JitcodeGlobalEntry::IonEntry::trackedOptimizationIndexAtAddr(
|
|||
return region->findIndex(ptrOffset, entryOffsetOut);
|
||||
}
|
||||
|
||||
void JitcodeGlobalEntry::IonEntry::forEachOptimizationAttempt(
|
||||
uint8_t index, ForEachTrackedOptimizationAttemptOp& op) {
|
||||
trackedOptimizationAttempts(index).forEach(op);
|
||||
}
|
||||
|
||||
void JitcodeGlobalEntry::IonEntry::forEachOptimizationTypeInfo(
|
||||
uint8_t index, IonTrackedOptimizationsTypeInfo::ForEachOpAdapter& op) {
|
||||
trackedOptimizationTypeInfo(index).forEach(op, allTrackedTypes());
|
||||
}
|
||||
|
||||
void IonTrackedOptimizationsAttempts::forEach(
|
||||
ForEachTrackedOptimizationAttemptOp& op) {
|
||||
CompactBufferReader reader(start_, end_);
|
||||
const uint8_t* cur = start_;
|
||||
while (cur != end_) {
|
||||
TrackedStrategy strategy = TrackedStrategy(reader.readUnsigned());
|
||||
TrackedOutcome outcome = TrackedOutcome(reader.readUnsigned());
|
||||
MOZ_ASSERT(strategy < TrackedStrategy::Count);
|
||||
MOZ_ASSERT(outcome < TrackedOutcome::Count);
|
||||
op(strategy, outcome);
|
||||
cur = reader.currentPosition();
|
||||
MOZ_ASSERT(cur <= end_);
|
||||
}
|
||||
}
|
||||
|
||||
void IonTrackedOptimizationsTypeInfo::forEach(
|
||||
ForEachOp& op, const IonTrackedTypeVector* allTypes) {
|
||||
CompactBufferReader reader(start_, end_);
|
||||
const uint8_t* cur = start_;
|
||||
while (cur != end_) {
|
||||
TrackedTypeSite site = JS::TrackedTypeSite(reader.readUnsigned());
|
||||
MOZ_ASSERT(site < JS::TrackedTypeSite::Count);
|
||||
MIRType mirType = MIRType(reader.readUnsigned());
|
||||
uint32_t length = reader.readUnsigned();
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
op.readType((*allTypes)[reader.readByte()]);
|
||||
}
|
||||
op(site, mirType);
|
||||
cur = reader.currentPosition();
|
||||
MOZ_ASSERT(cur <= end_);
|
||||
}
|
||||
}
|
||||
|
||||
Maybe<uint8_t> IonTrackedOptimizationsRegion::findIndex(
|
||||
uint32_t offset, uint32_t* entryOffsetOut) const {
|
||||
if (offset <= startOffset_ || offset > endOffset_) {
|
||||
|
@ -1131,91 +1086,6 @@ static JSFunction* FunctionFromTrackedType(
|
|||
return ty.group()->maybeInterpretedFunction();
|
||||
}
|
||||
|
||||
void IonTrackedOptimizationsTypeInfo::ForEachOpAdapter::readType(
|
||||
const IonTrackedTypeWithAddendum& tracked) {
|
||||
TypeSet::Type ty = tracked.type;
|
||||
|
||||
if (ty.isPrimitive() || ty.isUnknown() || ty.isAnyObject()) {
|
||||
op_.readType("primitive", TypeSet::NonObjectTypeString(ty), nullptr,
|
||||
Nothing());
|
||||
return;
|
||||
}
|
||||
|
||||
char buf[512];
|
||||
const uint32_t bufsize = mozilla::ArrayLength(buf);
|
||||
|
||||
if (JSFunction* fun = FunctionFromTrackedType(tracked)) {
|
||||
// The displayAtom is useful for identifying both native and
|
||||
// interpreted functions.
|
||||
char* name = nullptr;
|
||||
if (fun->displayAtom()) {
|
||||
PutEscapedString(buf, bufsize, fun->displayAtom(), 0);
|
||||
name = buf;
|
||||
}
|
||||
|
||||
if (fun->isNative()) {
|
||||
//
|
||||
// Try printing out the displayAtom of the native function and the
|
||||
// absolute address of the native function pointer.
|
||||
//
|
||||
// Note that this address is not usable without knowing the
|
||||
// starting address at which our shared library is loaded. Shared
|
||||
// library information is exposed by the profiler. If this address
|
||||
// needs to be symbolicated manually (e.g., when it is gotten via
|
||||
// debug spewing of all optimization information), it needs to be
|
||||
// converted to an offset from the beginning of the shared library
|
||||
// for use with utilities like `addr2line` on Linux and `atos` on
|
||||
// OS X. Converting to an offset may be done via dladdr():
|
||||
//
|
||||
// void* addr = JS_FUNC_TO_DATA_PTR(void*, fun->native());
|
||||
// uintptr_t offset;
|
||||
// Dl_info info;
|
||||
// if (dladdr(addr, &info) != 0) {
|
||||
// offset = uintptr_t(addr) - uintptr_t(info.dli_fbase);
|
||||
// }
|
||||
//
|
||||
char locationBuf[20];
|
||||
if (!name) {
|
||||
uintptr_t addr = JS_FUNC_TO_DATA_PTR(uintptr_t, fun->native());
|
||||
snprintf(locationBuf, mozilla::ArrayLength(locationBuf), "%" PRIxPTR,
|
||||
addr);
|
||||
}
|
||||
op_.readType("native", name, name ? nullptr : locationBuf, Nothing());
|
||||
return;
|
||||
}
|
||||
|
||||
const char* filename;
|
||||
Maybe<unsigned> lineno;
|
||||
InterpretedFunctionFilenameAndLineNumber(fun, &filename, &lineno);
|
||||
op_.readType(tracked.hasConstructor() ? "constructor" : "function", name,
|
||||
filename, lineno);
|
||||
return;
|
||||
}
|
||||
|
||||
const char* className = ty.objectKey()->clasp()->name;
|
||||
snprintf(buf, bufsize, "[object %s]", className);
|
||||
|
||||
if (tracked.hasAllocationSite()) {
|
||||
JSScript* script = tracked.script;
|
||||
op_.readType(
|
||||
"alloc site", buf, script->maybeForwardedScriptSource()->filename(),
|
||||
Some(PCToLineNumber(script, script->offsetToPC(tracked.offset))));
|
||||
return;
|
||||
}
|
||||
|
||||
if (ty.isGroup()) {
|
||||
op_.readType("prototype", buf, nullptr, Nothing());
|
||||
return;
|
||||
}
|
||||
|
||||
op_.readType("singleton", buf, nullptr, Nothing());
|
||||
}
|
||||
|
||||
void IonTrackedOptimizationsTypeInfo::ForEachOpAdapter::operator()(
|
||||
JS::TrackedTypeSite site, MIRType mirType) {
|
||||
op_(site, StringFromMIRType(mirType));
|
||||
}
|
||||
|
||||
typedef JS::ProfiledFrameHandle FrameHandle;
|
||||
|
||||
void FrameHandle::updateHasTrackedOptimizations() {
|
||||
|
@ -1236,18 +1106,3 @@ void FrameHandle::updateHasTrackedOptimizations() {
|
|||
(void*)(((uint8_t*)entry_.nativeStartAddr()) + entryOffset);
|
||||
}
|
||||
}
|
||||
|
||||
JS_PUBLIC_API void FrameHandle::forEachOptimizationAttempt(
|
||||
ForEachTrackedOptimizationAttemptOp& op, JSScript** scriptOut,
|
||||
jsbytecode** pcOut) const {
|
||||
MOZ_ASSERT(optsIndex_.isSome());
|
||||
entry_.forEachOptimizationAttempt(rt_, *optsIndex_, op);
|
||||
entry_.youngestFrameLocationAtAddr(rt_, addr_, scriptOut, pcOut);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API void FrameHandle::forEachOptimizationTypeInfo(
|
||||
ForEachTrackedOptimizationTypeInfoOp& op) const {
|
||||
MOZ_ASSERT(optsIndex_.isSome());
|
||||
IonTrackedOptimizationsTypeInfo::ForEachOpAdapter adapter(op);
|
||||
entry_.forEachOptimizationTypeInfo(rt_, *optsIndex_, adapter);
|
||||
}
|
||||
|
|
|
@ -427,8 +427,6 @@ class IonTrackedOptimizationsAttempts {
|
|||
// Cannot be empty.
|
||||
MOZ_ASSERT(start < end);
|
||||
}
|
||||
|
||||
void forEach(JS::ForEachTrackedOptimizationAttemptOp& op);
|
||||
};
|
||||
|
||||
struct IonTrackedTypeWithAddendum {
|
||||
|
@ -479,30 +477,6 @@ class IonTrackedOptimizationsTypeInfo {
|
|||
}
|
||||
|
||||
bool empty() const { return start_ == end_; }
|
||||
|
||||
// Unlike IonTrackedOptimizationAttempts,
|
||||
// JS::ForEachTrackedOptimizationTypeInfoOp cannot be used directly. The
|
||||
// internal API needs to deal with engine-internal data structures (e.g.,
|
||||
// TypeSet::Type) directly.
|
||||
//
|
||||
// An adapter is provided below.
|
||||
struct ForEachOp {
|
||||
virtual void readType(const IonTrackedTypeWithAddendum& tracked) = 0;
|
||||
virtual void operator()(JS::TrackedTypeSite site, MIRType mirType) = 0;
|
||||
};
|
||||
|
||||
class ForEachOpAdapter : public ForEachOp {
|
||||
JS::ForEachTrackedOptimizationTypeInfoOp& op_;
|
||||
|
||||
public:
|
||||
explicit ForEachOpAdapter(JS::ForEachTrackedOptimizationTypeInfoOp& op)
|
||||
: op_(op) {}
|
||||
|
||||
void readType(const IonTrackedTypeWithAddendum& tracked) override;
|
||||
void operator()(JS::TrackedTypeSite site, MIRType mirType) override;
|
||||
};
|
||||
|
||||
void forEach(ForEachOp& op, const IonTrackedTypeVector* allTypes);
|
||||
};
|
||||
|
||||
template <class Entry>
|
||||
|
|
|
@ -959,61 +959,6 @@ bool CodeGeneratorShared::generateCompactTrackedOptimizationsMap(
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
class ReadTempAttemptsVectorOp
|
||||
: public JS::ForEachTrackedOptimizationAttemptOp {
|
||||
TempOptimizationAttemptsVector* attempts_;
|
||||
bool oom_;
|
||||
|
||||
public:
|
||||
explicit ReadTempAttemptsVectorOp(TempOptimizationAttemptsVector* attempts)
|
||||
: attempts_(attempts), oom_(false) {}
|
||||
|
||||
bool oom() { return oom_; }
|
||||
|
||||
void operator()(JS::TrackedStrategy strategy,
|
||||
JS::TrackedOutcome outcome) override {
|
||||
if (!attempts_->append(OptimizationAttempt(strategy, outcome))) {
|
||||
oom_ = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct ReadTempTypeInfoVectorOp
|
||||
: public IonTrackedOptimizationsTypeInfo::ForEachOp {
|
||||
TempAllocator& alloc_;
|
||||
TempOptimizationTypeInfoVector* types_;
|
||||
TempTypeList accTypes_;
|
||||
bool oom_;
|
||||
|
||||
public:
|
||||
ReadTempTypeInfoVectorOp(TempAllocator& alloc,
|
||||
TempOptimizationTypeInfoVector* types)
|
||||
: alloc_(alloc), types_(types), accTypes_(alloc), oom_(false) {}
|
||||
|
||||
bool oom() { return oom_; }
|
||||
|
||||
void readType(const IonTrackedTypeWithAddendum& tracked) override {
|
||||
if (!accTypes_.append(tracked.type)) {
|
||||
oom_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(JS::TrackedTypeSite site, MIRType mirType) override {
|
||||
OptimizationTypeInfo ty(alloc_, site, mirType);
|
||||
for (uint32_t i = 0; i < accTypes_.length(); i++) {
|
||||
if (!ty.trackType(accTypes_[i])) {
|
||||
oom_ = true;
|
||||
}
|
||||
}
|
||||
if (!types_->append(std::move(ty))) {
|
||||
oom_ = true;
|
||||
}
|
||||
accTypes_.clear();
|
||||
}
|
||||
};
|
||||
#endif // DEBUG
|
||||
|
||||
void CodeGeneratorShared::verifyCompactTrackedOptimizationsMap(
|
||||
JitCode* code, uint32_t numRegions,
|
||||
const UniqueTrackedOptimizations& unique,
|
||||
|
@ -1082,16 +1027,10 @@ void CodeGeneratorShared::verifyCompactTrackedOptimizationsMap(
|
|||
if (!rt->gc.storeBuffer().cancelIonCompilations()) {
|
||||
IonTrackedOptimizationsTypeInfo typeInfo = typesTable->entry(index);
|
||||
TempOptimizationTypeInfoVector tvec(alloc());
|
||||
ReadTempTypeInfoVectorOp top(alloc(), &tvec);
|
||||
typeInfo.forEach(top, allTypes);
|
||||
MOZ_ASSERT_IF(!top.oom(), entry.optimizations->matchTypes(tvec));
|
||||
}
|
||||
|
||||
IonTrackedOptimizationsAttempts attempts = attemptsTable->entry(index);
|
||||
TempOptimizationAttemptsVector avec(alloc());
|
||||
ReadTempAttemptsVectorOp aop(&avec);
|
||||
attempts.forEach(aop);
|
||||
MOZ_ASSERT_IF(!aop.oom(), entry.optimizations->matchAttempts(avec));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -116,44 +116,6 @@ struct TypeInfo {
|
|||
Maybe<unsigned> mLineNumber;
|
||||
};
|
||||
|
||||
template <typename LambdaT>
|
||||
class ForEachTrackedOptimizationTypeInfoLambdaOp
|
||||
: public JS::ForEachTrackedOptimizationTypeInfoOp {
|
||||
public:
|
||||
// aLambda needs to be a function with the following signature:
|
||||
// void lambda(JS::TrackedTypeSite site, const char* mirType,
|
||||
// const nsTArray<TypeInfo>& typeset)
|
||||
// aLambda will be called once per entry.
|
||||
explicit ForEachTrackedOptimizationTypeInfoLambdaOp(LambdaT&& aLambda)
|
||||
: mLambda(aLambda) {}
|
||||
|
||||
// This is called 0 or more times per entry, *before* operator() is called
|
||||
// for that entry.
|
||||
void readType(const char* keyedBy, const char* name, const char* location,
|
||||
const Maybe<unsigned>& lineno) override {
|
||||
TypeInfo info = {keyedBy ? Some(nsCString(keyedBy)) : Nothing(),
|
||||
name ? Some(nsCString(name)) : Nothing(),
|
||||
location ? Some(nsCString(location)) : Nothing(), lineno};
|
||||
mTypesetForUpcomingEntry.AppendElement(std::move(info));
|
||||
}
|
||||
|
||||
void operator()(JS::TrackedTypeSite site, const char* mirType) override {
|
||||
nsTArray<TypeInfo> typeset(std::move(mTypesetForUpcomingEntry));
|
||||
mLambda(site, mirType, typeset);
|
||||
}
|
||||
|
||||
private:
|
||||
nsTArray<TypeInfo> mTypesetForUpcomingEntry;
|
||||
LambdaT mLambda;
|
||||
};
|
||||
|
||||
template <typename LambdaT>
|
||||
ForEachTrackedOptimizationTypeInfoLambdaOp<LambdaT>
|
||||
MakeForEachTrackedOptimizationTypeInfoLambdaOp(LambdaT&& aLambda) {
|
||||
return ForEachTrackedOptimizationTypeInfoLambdaOp<LambdaT>(
|
||||
std::forward<LambdaT>(aLambda));
|
||||
}
|
||||
|
||||
// As mentioned in ProfileBufferEntry.h, the JSON format contains many
|
||||
// arrays whose elements are laid out according to various schemas to help
|
||||
// de-duplication. This RAII class helps write these arrays by keeping track of
|
||||
|
@ -243,28 +205,6 @@ class MOZ_RAII AutoArraySchemaWriter {
|
|||
uint32_t mNextFreeIndex;
|
||||
};
|
||||
|
||||
template <typename LambdaT>
|
||||
class ForEachTrackedOptimizationAttemptsLambdaOp
|
||||
: public JS::ForEachTrackedOptimizationAttemptOp {
|
||||
public:
|
||||
explicit ForEachTrackedOptimizationAttemptsLambdaOp(LambdaT&& aLambda)
|
||||
: mLambda(std::move(aLambda)) {}
|
||||
void operator()(JS::TrackedStrategy aStrategy,
|
||||
JS::TrackedOutcome aOutcome) override {
|
||||
mLambda(aStrategy, aOutcome);
|
||||
}
|
||||
|
||||
private:
|
||||
LambdaT mLambda;
|
||||
};
|
||||
|
||||
template <typename LambdaT>
|
||||
ForEachTrackedOptimizationAttemptsLambdaOp<LambdaT>
|
||||
MakeForEachTrackedOptimizationAttemptsLambdaOp(LambdaT&& aLambda) {
|
||||
return ForEachTrackedOptimizationAttemptsLambdaOp<LambdaT>(
|
||||
std::move(aLambda));
|
||||
}
|
||||
|
||||
UniqueJSONStrings::UniqueJSONStrings() { mStringTableWriter.StartBareList(); }
|
||||
|
||||
UniqueJSONStrings::UniqueJSONStrings(const UniqueJSONStrings& aOther) {
|
||||
|
@ -496,94 +436,6 @@ void UniqueStacks::StreamNonJITFrame(const FrameKey& aFrame) {
|
|||
}
|
||||
}
|
||||
|
||||
static void StreamJITFrameOptimizations(
|
||||
SpliceableJSONWriter& aWriter, UniqueJSONStrings& aUniqueStrings,
|
||||
JSContext* aContext, const JS::ProfiledFrameHandle& aJITFrame) {
|
||||
aWriter.StartObjectElement();
|
||||
{
|
||||
aWriter.StartArrayProperty("types");
|
||||
{
|
||||
auto op = MakeForEachTrackedOptimizationTypeInfoLambdaOp(
|
||||
[&](JS::TrackedTypeSite site, const char* mirType,
|
||||
const nsTArray<TypeInfo>& typeset) {
|
||||
aWriter.StartObjectElement();
|
||||
{
|
||||
aUniqueStrings.WriteProperty(aWriter, "site",
|
||||
JS::TrackedTypeSiteString(site));
|
||||
aUniqueStrings.WriteProperty(aWriter, "mirType", mirType);
|
||||
|
||||
if (!typeset.IsEmpty()) {
|
||||
aWriter.StartArrayProperty("typeset");
|
||||
for (const TypeInfo& typeInfo : typeset) {
|
||||
aWriter.StartObjectElement();
|
||||
{
|
||||
aUniqueStrings.WriteProperty(aWriter, "keyedBy",
|
||||
typeInfo.mKeyedBy->get());
|
||||
if (typeInfo.mName) {
|
||||
aUniqueStrings.WriteProperty(aWriter, "name",
|
||||
typeInfo.mName->get());
|
||||
}
|
||||
if (typeInfo.mLocation) {
|
||||
aUniqueStrings.WriteProperty(aWriter, "location",
|
||||
typeInfo.mLocation->get());
|
||||
}
|
||||
if (typeInfo.mLineNumber.isSome()) {
|
||||
aWriter.IntProperty("line", *typeInfo.mLineNumber);
|
||||
}
|
||||
}
|
||||
aWriter.EndObject();
|
||||
}
|
||||
aWriter.EndArray();
|
||||
}
|
||||
}
|
||||
aWriter.EndObject();
|
||||
});
|
||||
aJITFrame.forEachOptimizationTypeInfo(op);
|
||||
}
|
||||
aWriter.EndArray();
|
||||
|
||||
JS::Rooted<JSScript*> script(aContext);
|
||||
jsbytecode* pc;
|
||||
aWriter.StartObjectProperty("attempts");
|
||||
{
|
||||
{
|
||||
JSONSchemaWriter schema(aWriter);
|
||||
schema.WriteField("strategy");
|
||||
schema.WriteField("outcome");
|
||||
}
|
||||
|
||||
aWriter.StartArrayProperty("data");
|
||||
{
|
||||
auto op = MakeForEachTrackedOptimizationAttemptsLambdaOp(
|
||||
[&](JS::TrackedStrategy strategy, JS::TrackedOutcome outcome) {
|
||||
enum Schema : uint32_t { STRATEGY = 0, OUTCOME = 1 };
|
||||
|
||||
AutoArraySchemaWriter writer(aWriter, aUniqueStrings);
|
||||
writer.StringElement(STRATEGY,
|
||||
JS::TrackedStrategyString(strategy));
|
||||
writer.StringElement(OUTCOME, JS::TrackedOutcomeString(outcome));
|
||||
});
|
||||
aJITFrame.forEachOptimizationAttempt(op, script.address(), &pc);
|
||||
}
|
||||
aWriter.EndArray();
|
||||
}
|
||||
aWriter.EndObject();
|
||||
|
||||
if (JSAtom* name = js::GetPropertyNameFromPC(script, pc)) {
|
||||
char buf[512];
|
||||
JS_PutEscapedLinearString(buf, ArrayLength(buf),
|
||||
js::AtomToLinearString(name), 0);
|
||||
aUniqueStrings.WriteProperty(aWriter, "propertyName", buf);
|
||||
}
|
||||
|
||||
unsigned line, column;
|
||||
line = JS_PCToLineNumber(script, pc, &column);
|
||||
aWriter.IntProperty("line", line);
|
||||
aWriter.IntProperty("column", column);
|
||||
}
|
||||
aWriter.EndObject();
|
||||
}
|
||||
|
||||
static void StreamJITFrame(JSContext* aContext, SpliceableJSONWriter& aWriter,
|
||||
UniqueJSONStrings& aUniqueStrings,
|
||||
const JS::ProfiledFrameHandle& aJITFrame) {
|
||||
|
@ -616,15 +468,6 @@ static void StreamJITFrame(JSContext* aContext, SpliceableJSONWriter& aWriter,
|
|||
IMPLEMENTATION,
|
||||
frameKind == JS::ProfilingFrameIterator::Frame_Ion ? "ion" : "baseline");
|
||||
|
||||
if (aJITFrame.hasTrackedOptimizations()) {
|
||||
writer.FreeFormElement(
|
||||
OPTIMIZATIONS,
|
||||
[&](SpliceableJSONWriter& aWriter, UniqueJSONStrings& aUniqueStrings) {
|
||||
StreamJITFrameOptimizations(aWriter, aUniqueStrings, aContext,
|
||||
aJITFrame);
|
||||
});
|
||||
}
|
||||
|
||||
const JS::ProfilingCategoryPairInfo& info =
|
||||
JS::GetProfilingCategoryPairInfo(JS::ProfilingCategoryPair::JS);
|
||||
writer.IntElement(CATEGORY, uint32_t(info.mCategory));
|
||||
|
|
Загрузка…
Ссылка в новой задаче