зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1342273 - Improve frontend tracelogging. (r=h4writer)
This commit is contained in:
Родитель
11db464a8a
Коммит
08c7d6f388
|
@ -31,19 +31,6 @@ using namespace js::frontend;
|
|||
using mozilla::Maybe;
|
||||
using mozilla::Nothing;
|
||||
|
||||
class MOZ_STACK_CLASS AutoCompilationTraceLogger
|
||||
{
|
||||
public:
|
||||
AutoCompilationTraceLogger(JSContext* cx, const TraceLoggerTextId id,
|
||||
const ReadOnlyCompileOptions& options);
|
||||
|
||||
private:
|
||||
TraceLoggerThread* logger;
|
||||
TraceLoggerEvent event;
|
||||
AutoTraceLog scriptLogger;
|
||||
AutoTraceLog typeLogger;
|
||||
};
|
||||
|
||||
// The BytecodeCompiler class contains resources common to compiling scripts and
|
||||
// function bodies.
|
||||
class MOZ_STACK_CLASS BytecodeCompiler
|
||||
|
@ -54,8 +41,7 @@ class MOZ_STACK_CLASS BytecodeCompiler
|
|||
LifoAlloc& alloc,
|
||||
const ReadOnlyCompileOptions& options,
|
||||
SourceBufferHolder& sourceBuffer,
|
||||
HandleScope enclosingScope,
|
||||
TraceLoggerTextId logId);
|
||||
HandleScope enclosingScope);
|
||||
|
||||
// Call setters for optional arguments.
|
||||
void maybeSetSourceCompressor(SourceCompressionTask* sourceCompressor);
|
||||
|
@ -83,7 +69,6 @@ class MOZ_STACK_CLASS BytecodeCompiler
|
|||
bool deoptimizeArgumentsInEnclosingScripts(JSContext* cx, HandleObject environment);
|
||||
bool maybeCompleteCompressSource();
|
||||
|
||||
AutoCompilationTraceLogger traceLogger;
|
||||
AutoKeepAtoms keepAtoms;
|
||||
|
||||
JSContext* cx;
|
||||
|
@ -109,22 +94,77 @@ class MOZ_STACK_CLASS BytecodeCompiler
|
|||
RootedScript script;
|
||||
};
|
||||
|
||||
AutoCompilationTraceLogger::AutoCompilationTraceLogger(JSContext* cx,
|
||||
const TraceLoggerTextId id, const ReadOnlyCompileOptions& options)
|
||||
: logger(TraceLoggerForCurrentThread(cx)),
|
||||
event(TraceLogger_AnnotateScripts, options),
|
||||
scriptLogger(logger, event),
|
||||
typeLogger(logger, id)
|
||||
{}
|
||||
AutoFrontendTraceLog::AutoFrontendTraceLog(JSContext* cx, const TraceLoggerTextId id,
|
||||
const char* filename, size_t line, size_t column)
|
||||
#ifdef JS_TRACE_LOGGING
|
||||
: logger_(TraceLoggerForCurrentThread(cx))
|
||||
{
|
||||
frontendEvent_.emplace(TraceLogger_Frontend, filename, line, column);
|
||||
frontendLog_.emplace(logger_, *frontendEvent_);
|
||||
typeLog_.emplace(logger_, id);
|
||||
}
|
||||
#else
|
||||
{ }
|
||||
#endif
|
||||
|
||||
AutoFrontendTraceLog::AutoFrontendTraceLog(JSContext* cx, const TraceLoggerTextId id,
|
||||
const TokenStream& tokenStream)
|
||||
#ifdef JS_TRACE_LOGGING
|
||||
: logger_(TraceLoggerForCurrentThread(cx))
|
||||
{
|
||||
// If the tokenizer hasn't yet gotten any tokens, use the line and column
|
||||
// numbers from CompileOptions.
|
||||
uint32_t line, column;
|
||||
if (tokenStream.isCurrentTokenType(TOK_EOF) && !tokenStream.isEOF()) {
|
||||
line = tokenStream.options().lineno;
|
||||
column = tokenStream.options().column;
|
||||
} else {
|
||||
uint32_t offset = tokenStream.currentToken().pos.begin;
|
||||
tokenStream.srcCoords.lineNumAndColumnIndex(offset, &line, &column);
|
||||
}
|
||||
frontendEvent_.emplace(TraceLogger_Frontend, tokenStream.getFilename(), line, column);
|
||||
frontendLog_.emplace(logger_, *frontendEvent_);
|
||||
typeLog_.emplace(logger_, id);
|
||||
}
|
||||
#else
|
||||
{ }
|
||||
#endif
|
||||
|
||||
AutoFrontendTraceLog::AutoFrontendTraceLog(JSContext* cx, const TraceLoggerTextId id,
|
||||
const TokenStream& tokenStream, FunctionBox* funbox)
|
||||
#ifdef JS_TRACE_LOGGING
|
||||
: logger_(TraceLoggerForCurrentThread(cx))
|
||||
{
|
||||
frontendEvent_.emplace(TraceLogger_Frontend, tokenStream.getFilename(),
|
||||
funbox->startLine, funbox->startColumn);
|
||||
frontendLog_.emplace(logger_, *frontendEvent_);
|
||||
typeLog_.emplace(logger_, id);
|
||||
}
|
||||
#else
|
||||
{ }
|
||||
#endif
|
||||
|
||||
AutoFrontendTraceLog::AutoFrontendTraceLog(JSContext* cx, const TraceLoggerTextId id,
|
||||
const TokenStream& tokenStream, ParseNode* pn)
|
||||
#ifdef JS_TRACE_LOGGING
|
||||
: logger_(TraceLoggerForCurrentThread(cx))
|
||||
{
|
||||
uint32_t line, column;
|
||||
tokenStream.srcCoords.lineNumAndColumnIndex(pn->pn_pos.begin, &line, &column);
|
||||
frontendEvent_.emplace(TraceLogger_Frontend, tokenStream.getFilename(), line, column);
|
||||
frontendLog_.emplace(logger_, *frontendEvent_);
|
||||
typeLog_.emplace(logger_, id);
|
||||
}
|
||||
#else
|
||||
{ }
|
||||
#endif
|
||||
|
||||
BytecodeCompiler::BytecodeCompiler(JSContext* cx,
|
||||
LifoAlloc& alloc,
|
||||
const ReadOnlyCompileOptions& options,
|
||||
SourceBufferHolder& sourceBuffer,
|
||||
HandleScope enclosingScope,
|
||||
TraceLoggerTextId logId)
|
||||
: traceLogger(cx, logId, options),
|
||||
keepAtoms(cx),
|
||||
HandleScope enclosingScope)
|
||||
: keepAtoms(cx),
|
||||
cx(cx),
|
||||
alloc(alloc),
|
||||
options(options),
|
||||
|
@ -556,8 +596,7 @@ frontend::CompileGlobalScript(JSContext* cx, LifoAlloc& alloc, ScopeKind scopeKi
|
|||
ScriptSourceObject** sourceObjectOut)
|
||||
{
|
||||
MOZ_ASSERT(scopeKind == ScopeKind::Global || scopeKind == ScopeKind::NonSyntactic);
|
||||
BytecodeCompiler compiler(cx, alloc, options, srcBuf, /* enclosingScope = */ nullptr,
|
||||
TraceLogger_ParserCompileScript);
|
||||
BytecodeCompiler compiler(cx, alloc, options, srcBuf, /* enclosingScope = */ nullptr);
|
||||
AutoInitializeSourceObject autoSSO(compiler, sourceObjectOut);
|
||||
compiler.maybeSetSourceCompressor(extraSct);
|
||||
return compiler.compileGlobalScript(scopeKind);
|
||||
|
@ -571,8 +610,7 @@ frontend::CompileEvalScript(JSContext* cx, LifoAlloc& alloc,
|
|||
SourceCompressionTask* extraSct,
|
||||
ScriptSourceObject** sourceObjectOut)
|
||||
{
|
||||
BytecodeCompiler compiler(cx, alloc, options, srcBuf, enclosingScope,
|
||||
TraceLogger_ParserCompileScript);
|
||||
BytecodeCompiler compiler(cx, alloc, options, srcBuf, enclosingScope);
|
||||
AutoInitializeSourceObject autoSSO(compiler, sourceObjectOut);
|
||||
compiler.maybeSetSourceCompressor(extraSct);
|
||||
return compiler.compileEvalScript(environment, enclosingScope);
|
||||
|
@ -592,8 +630,7 @@ frontend::CompileModule(JSContext* cx, const ReadOnlyCompileOptions& optionsInpu
|
|||
options.allowHTMLComments = false;
|
||||
|
||||
RootedScope emptyGlobalScope(cx, &cx->global()->emptyGlobalScope());
|
||||
BytecodeCompiler compiler(cx, alloc, options, srcBuf, emptyGlobalScope,
|
||||
TraceLogger_ParserCompileModule);
|
||||
BytecodeCompiler compiler(cx, alloc, options, srcBuf, emptyGlobalScope);
|
||||
AutoInitializeSourceObject autoSSO(compiler, sourceObjectOut);
|
||||
return compiler.compileModule();
|
||||
}
|
||||
|
@ -630,8 +667,6 @@ frontend::CompileLazyFunction(JSContext* cx, Handle<LazyScript*> lazy, const cha
|
|||
.setNoScriptRval(false)
|
||||
.setSelfHostingMode(false);
|
||||
|
||||
AutoCompilationTraceLogger traceLogger(cx, TraceLogger_ParserCompileLazy, options);
|
||||
|
||||
UsedNameTracker usedNames(cx);
|
||||
if (!usedNames.init())
|
||||
return false;
|
||||
|
@ -692,8 +727,7 @@ frontend::CompileStandaloneFunction(JSContext* cx, MutableHandleFunction fun,
|
|||
if (!scope)
|
||||
scope = &cx->global()->emptyGlobalScope();
|
||||
|
||||
BytecodeCompiler compiler(cx, cx->tempLifoAlloc(), options, srcBuf, scope,
|
||||
TraceLogger_ParserCompileFunction);
|
||||
BytecodeCompiler compiler(cx, cx->tempLifoAlloc(), options, srcBuf, scope);
|
||||
return compiler.compileStandaloneFunction(fun, NotGenerator, SyncFunction, parameterListEnd);
|
||||
}
|
||||
|
||||
|
@ -705,8 +739,7 @@ frontend::CompileStandaloneGenerator(JSContext* cx, MutableHandleFunction fun,
|
|||
{
|
||||
RootedScope emptyGlobalScope(cx, &cx->global()->emptyGlobalScope());
|
||||
|
||||
BytecodeCompiler compiler(cx, cx->tempLifoAlloc(), options, srcBuf, emptyGlobalScope,
|
||||
TraceLogger_ParserCompileFunction);
|
||||
BytecodeCompiler compiler(cx, cx->tempLifoAlloc(), options, srcBuf, emptyGlobalScope);
|
||||
return compiler.compileStandaloneFunction(fun, StarGenerator, SyncFunction, parameterListEnd);
|
||||
}
|
||||
|
||||
|
@ -718,7 +751,6 @@ frontend::CompileStandaloneAsyncFunction(JSContext* cx, MutableHandleFunction fu
|
|||
{
|
||||
RootedScope emptyGlobalScope(cx, &cx->global()->emptyGlobalScope());
|
||||
|
||||
BytecodeCompiler compiler(cx, cx->tempLifoAlloc(), options, srcBuf, emptyGlobalScope,
|
||||
TraceLogger_ParserCompileFunction);
|
||||
BytecodeCompiler compiler(cx, cx->tempLifoAlloc(), options, srcBuf, emptyGlobalScope);
|
||||
return compiler.compileStandaloneFunction(fun, StarGenerator, AsyncFunction, parameterListEnd);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "vm/Scope.h"
|
||||
#include "vm/String.h"
|
||||
#include "vm/TraceLogging.h"
|
||||
|
||||
class JSLinearString;
|
||||
|
||||
|
@ -26,6 +27,10 @@ struct SourceCompressionTask;
|
|||
|
||||
namespace frontend {
|
||||
|
||||
class TokenStream;
|
||||
class FunctionBox;
|
||||
class ParseNode;
|
||||
|
||||
JSScript*
|
||||
CompileGlobalScript(JSContext* cx, LifoAlloc& alloc, ScopeKind scopeKind,
|
||||
const ReadOnlyCompileOptions& options,
|
||||
|
@ -119,6 +124,29 @@ IsKeyword(JSLinearString* str);
|
|||
void
|
||||
TraceParser(JSTracer* trc, JS::AutoGCRooter* parser);
|
||||
|
||||
class MOZ_STACK_CLASS AutoFrontendTraceLog
|
||||
{
|
||||
#ifdef JS_TRACE_LOGGING
|
||||
TraceLoggerThread* logger_;
|
||||
mozilla::Maybe<TraceLoggerEvent> frontendEvent_;
|
||||
mozilla::Maybe<AutoTraceLog> frontendLog_;
|
||||
mozilla::Maybe<AutoTraceLog> typeLog_;
|
||||
#endif
|
||||
|
||||
public:
|
||||
AutoFrontendTraceLog(JSContext* cx, const TraceLoggerTextId id,
|
||||
const char* filename, size_t line, size_t column);
|
||||
|
||||
AutoFrontendTraceLog(JSContext* cx, const TraceLoggerTextId id,
|
||||
const TokenStream& tokenStream);
|
||||
|
||||
AutoFrontendTraceLog(JSContext* cx, const TraceLoggerTextId id,
|
||||
const TokenStream& tokenStream, FunctionBox* funbox);
|
||||
|
||||
AutoFrontendTraceLog(JSContext* cx, const TraceLoggerTextId id,
|
||||
const TokenStream& tokenStream, ParseNode* pn);
|
||||
};
|
||||
|
||||
} /* namespace frontend */
|
||||
} /* namespace js */
|
||||
|
||||
|
|
|
@ -580,6 +580,8 @@ class BytecodeEmitter::EmitterScope : public Nestable<BytecodeEmitter::EmitterSc
|
|||
}
|
||||
|
||||
NameLocation lookup(BytecodeEmitter* bce, JSAtom* name) {
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(bce->cx),
|
||||
TraceLogger_FrontendNameAnalysis);
|
||||
if (Maybe<NameLocation> loc = lookupInCache(bce, name))
|
||||
return *loc;
|
||||
return searchAndCache(bce, name);
|
||||
|
@ -866,6 +868,8 @@ Maybe<NameLocation>
|
|||
BytecodeEmitter::EmitterScope::locationBoundInScope(BytecodeEmitter* bce, JSAtom* name,
|
||||
EmitterScope* target)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(bce->cx), TraceLogger_FrontendNameAnalysis);
|
||||
|
||||
// The target scope must be an intra-frame enclosing scope of this
|
||||
// one. Count the number of extra hops to reach it.
|
||||
uint8_t extraHops = 0;
|
||||
|
@ -923,6 +927,8 @@ bool
|
|||
BytecodeEmitter::EmitterScope::enterLexical(BytecodeEmitter* bce, ScopeKind kind,
|
||||
Handle<LexicalScope::Data*> bindings)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(bce->cx), TraceLogger_FrontendNameAnalysis);
|
||||
|
||||
MOZ_ASSERT(kind != ScopeKind::NamedLambda && kind != ScopeKind::StrictNamedLambda);
|
||||
MOZ_ASSERT(this == bce->innermostEmitterScope);
|
||||
|
||||
|
@ -993,6 +999,8 @@ BytecodeEmitter::EmitterScope::enterLexical(BytecodeEmitter* bce, ScopeKind kind
|
|||
bool
|
||||
BytecodeEmitter::EmitterScope::enterNamedLambda(BytecodeEmitter* bce, FunctionBox* funbox)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(bce->cx), TraceLogger_FrontendNameAnalysis);
|
||||
|
||||
MOZ_ASSERT(this == bce->innermostEmitterScope);
|
||||
MOZ_ASSERT(funbox->namedLambdaBindings());
|
||||
|
||||
|
@ -1060,6 +1068,8 @@ BytecodeEmitter::EmitterScope::enterComprehensionFor(BytecodeEmitter* bce,
|
|||
bool
|
||||
BytecodeEmitter::EmitterScope::enterParameterExpressionVar(BytecodeEmitter* bce)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(bce->cx), TraceLogger_FrontendNameAnalysis);
|
||||
|
||||
MOZ_ASSERT(this == bce->innermostEmitterScope);
|
||||
|
||||
if (!ensureCache(bce))
|
||||
|
@ -1181,6 +1191,8 @@ BytecodeEmitter::EmitterScope::enterFunction(BytecodeEmitter* bce, FunctionBox*
|
|||
bool
|
||||
BytecodeEmitter::EmitterScope::enterFunctionExtraBodyVar(BytecodeEmitter* bce, FunctionBox* funbox)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(bce->cx), TraceLogger_FrontendNameAnalysis);
|
||||
|
||||
MOZ_ASSERT(funbox->hasParameterExprs);
|
||||
MOZ_ASSERT(funbox->extraVarScopeBindings() ||
|
||||
funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings());
|
||||
|
@ -1270,6 +1282,8 @@ class DynamicBindingIter : public BindingIter
|
|||
bool
|
||||
BytecodeEmitter::EmitterScope::enterGlobal(BytecodeEmitter* bce, GlobalSharedContext* globalsc)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(bce->cx), TraceLogger_FrontendNameAnalysis);
|
||||
|
||||
MOZ_ASSERT(this == bce->innermostEmitterScope);
|
||||
|
||||
bce->setVarEmitterScope(this);
|
||||
|
@ -1330,6 +1344,8 @@ BytecodeEmitter::EmitterScope::enterGlobal(BytecodeEmitter* bce, GlobalSharedCon
|
|||
bool
|
||||
BytecodeEmitter::EmitterScope::enterEval(BytecodeEmitter* bce, EvalSharedContext* evalsc)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(bce->cx), TraceLogger_FrontendNameAnalysis);
|
||||
|
||||
MOZ_ASSERT(this == bce->innermostEmitterScope);
|
||||
|
||||
bce->setVarEmitterScope(this);
|
||||
|
@ -1385,6 +1401,8 @@ BytecodeEmitter::EmitterScope::enterEval(BytecodeEmitter* bce, EvalSharedContext
|
|||
bool
|
||||
BytecodeEmitter::EmitterScope::enterModule(BytecodeEmitter* bce, ModuleSharedContext* modulesc)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(bce->cx), TraceLogger_FrontendNameAnalysis);
|
||||
|
||||
MOZ_ASSERT(this == bce->innermostEmitterScope);
|
||||
|
||||
bce->setVarEmitterScope(this);
|
||||
|
@ -1442,6 +1460,8 @@ BytecodeEmitter::EmitterScope::enterModule(BytecodeEmitter* bce, ModuleSharedCon
|
|||
bool
|
||||
BytecodeEmitter::EmitterScope::enterWith(BytecodeEmitter* bce)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(bce->cx), TraceLogger_FrontendNameAnalysis);
|
||||
|
||||
MOZ_ASSERT(this == bce->innermostEmitterScope);
|
||||
|
||||
if (!ensureCache(bce))
|
||||
|
@ -1468,6 +1488,8 @@ BytecodeEmitter::EmitterScope::enterWith(BytecodeEmitter* bce)
|
|||
bool
|
||||
BytecodeEmitter::EmitterScope::leave(BytecodeEmitter* bce, bool nonLocal)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(bce->cx), TraceLogger_FrontendNameAnalysis);
|
||||
|
||||
// If we aren't leaving the scope due to a non-local jump (e.g., break),
|
||||
// we must be the innermost scope.
|
||||
MOZ_ASSERT_IF(!nonLocal, this == bce->innermostEmitterScope);
|
||||
|
@ -1525,6 +1547,8 @@ BytecodeEmitter::EmitterScope::leave(BytecodeEmitter* bce, bool nonLocal)
|
|||
Maybe<MaybeCheckTDZ>
|
||||
BytecodeEmitter::TDZCheckCache::needsTDZCheck(BytecodeEmitter* bce, JSAtom* name)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(bce->cx), TraceLogger_FrontendTDZAnalysis);
|
||||
|
||||
if (!ensureCache(bce))
|
||||
return Nothing();
|
||||
|
||||
|
@ -1554,6 +1578,8 @@ bool
|
|||
BytecodeEmitter::TDZCheckCache::noteTDZCheck(BytecodeEmitter* bce, JSAtom* name,
|
||||
MaybeCheckTDZ check)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(bce->cx), TraceLogger_FrontendTDZAnalysis);
|
||||
|
||||
if (!ensureCache(bce))
|
||||
return false;
|
||||
|
||||
|
@ -3448,8 +3474,8 @@ BytecodeEmitter::needsImplicitThis()
|
|||
bool
|
||||
BytecodeEmitter::maybeSetDisplayURL()
|
||||
{
|
||||
if (tokenStream()->hasDisplayURL()) {
|
||||
if (!parser->ss->setDisplayURL(cx, tokenStream()->displayURL()))
|
||||
if (tokenStream().hasDisplayURL()) {
|
||||
if (!parser->ss->setDisplayURL(cx, tokenStream().displayURL()))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -3458,9 +3484,9 @@ BytecodeEmitter::maybeSetDisplayURL()
|
|||
bool
|
||||
BytecodeEmitter::maybeSetSourceMap()
|
||||
{
|
||||
if (tokenStream()->hasSourceMapURL()) {
|
||||
if (tokenStream().hasSourceMapURL()) {
|
||||
MOZ_ASSERT(!parser->ss->hasSourceMapURL());
|
||||
if (!parser->ss->setSourceMapURL(cx, tokenStream()->sourceMapURL()))
|
||||
if (!parser->ss->setSourceMapURL(cx, tokenStream().sourceMapURL()))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3499,20 +3525,20 @@ BytecodeEmitter::tellDebuggerAboutCompiledScript(JSContext* cx)
|
|||
Debugger::onNewScript(cx, script);
|
||||
}
|
||||
|
||||
inline TokenStream*
|
||||
inline TokenStream&
|
||||
BytecodeEmitter::tokenStream()
|
||||
{
|
||||
return &parser->tokenStream;
|
||||
return parser->tokenStream;
|
||||
}
|
||||
|
||||
bool
|
||||
BytecodeEmitter::reportError(ParseNode* pn, unsigned errorNumber, ...)
|
||||
{
|
||||
TokenPos pos = pn ? pn->pn_pos : tokenStream()->currentToken().pos;
|
||||
TokenPos pos = pn ? pn->pn_pos : tokenStream().currentToken().pos;
|
||||
|
||||
va_list args;
|
||||
va_start(args, errorNumber);
|
||||
bool result = tokenStream()->reportCompileErrorNumberVA(nullptr, pos.begin, JSREPORT_ERROR,
|
||||
bool result = tokenStream().reportCompileErrorNumberVA(nullptr, pos.begin, JSREPORT_ERROR,
|
||||
errorNumber, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
|
@ -3521,11 +3547,11 @@ BytecodeEmitter::reportError(ParseNode* pn, unsigned errorNumber, ...)
|
|||
bool
|
||||
BytecodeEmitter::reportExtraWarning(ParseNode* pn, unsigned errorNumber, ...)
|
||||
{
|
||||
TokenPos pos = pn ? pn->pn_pos : tokenStream()->currentToken().pos;
|
||||
TokenPos pos = pn ? pn->pn_pos : tokenStream().currentToken().pos;
|
||||
|
||||
va_list args;
|
||||
va_start(args, errorNumber);
|
||||
bool result = tokenStream()->reportExtraWarningErrorNumberVA(nullptr, pos.begin,
|
||||
bool result = tokenStream().reportExtraWarningErrorNumberVA(nullptr, pos.begin,
|
||||
errorNumber, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
|
@ -3534,11 +3560,11 @@ BytecodeEmitter::reportExtraWarning(ParseNode* pn, unsigned errorNumber, ...)
|
|||
bool
|
||||
BytecodeEmitter::reportStrictModeError(ParseNode* pn, unsigned errorNumber, ...)
|
||||
{
|
||||
TokenPos pos = pn ? pn->pn_pos : tokenStream()->currentToken().pos;
|
||||
TokenPos pos = pn ? pn->pn_pos : tokenStream().currentToken().pos;
|
||||
|
||||
va_list args;
|
||||
va_start(args, errorNumber);
|
||||
bool result = tokenStream()->reportStrictModeErrorNumberVA(nullptr, pos.begin, sc->strict(),
|
||||
bool result = tokenStream().reportStrictModeErrorNumberVA(nullptr, pos.begin, sc->strict(),
|
||||
errorNumber, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
|
@ -4789,6 +4815,8 @@ BytecodeEmitter::emitSetThis(ParseNode* pn)
|
|||
bool
|
||||
BytecodeEmitter::emitScript(ParseNode* body)
|
||||
{
|
||||
AutoFrontendTraceLog traceLog(cx, TraceLogger_BytecodeEmission, tokenStream(), body);
|
||||
|
||||
TDZCheckCache tdzCache(this);
|
||||
EmitterScope emitterScope(this);
|
||||
if (sc->isGlobalContext()) {
|
||||
|
@ -4856,6 +4884,7 @@ bool
|
|||
BytecodeEmitter::emitFunctionScript(ParseNode* body)
|
||||
{
|
||||
FunctionBox* funbox = sc->asFunctionBox();
|
||||
AutoFrontendTraceLog traceLog(cx, TraceLogger_BytecodeEmission, tokenStream(), funbox);
|
||||
|
||||
// The ordering of these EmitterScopes is important. The named lambda
|
||||
// scope needs to enclose the function scope needs to enclose the extra
|
||||
|
|
|
@ -352,7 +352,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
|
|||
MOZ_MUST_USE bool maybeSetSourceMap();
|
||||
void tellDebuggerAboutCompiledScript(JSContext* cx);
|
||||
|
||||
inline TokenStream* tokenStream();
|
||||
inline TokenStream& tokenStream();
|
||||
|
||||
BytecodeVector& code() const { return current->code; }
|
||||
jsbytecode* code(ptrdiff_t offset) const { return current->code.begin() + offset; }
|
||||
|
|
|
@ -1928,5 +1928,6 @@ frontend::FoldConstants(JSContext* cx, ParseNode** pnp, Parser<FullParseHandler>
|
|||
if (parser->pc->useAsmOrInsideUseAsm())
|
||||
return true;
|
||||
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(cx), TraceLogger_BytecodeFoldConstants);
|
||||
return Fold(cx, pnp, *parser, false);
|
||||
}
|
||||
|
|
|
@ -835,6 +835,7 @@ class NameResolver
|
|||
bool
|
||||
frontend::NameFunctions(JSContext* cx, ParseNode* pn)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(cx), TraceLogger_BytecodeNameFunctions);
|
||||
NameResolver nr(cx);
|
||||
return nr.resolve(pn);
|
||||
}
|
||||
|
|
|
@ -1018,6 +1018,8 @@ Parser<ParseHandler>::notePositionalFormalParameter(Node fn, HandlePropertyName
|
|||
bool disallowDuplicateParams,
|
||||
bool* duplicatedParam)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(context), TraceLogger_FrontendNameAnalysis);
|
||||
|
||||
if (AddDeclaredNamePtr p = pc->functionScope().lookupDeclaredNameForAdd(name)) {
|
||||
if (disallowDuplicateParams) {
|
||||
error(JSMSG_BAD_DUP_ARGS);
|
||||
|
@ -1243,6 +1245,8 @@ bool
|
|||
Parser<ParseHandler>::tryDeclareVarForAnnexBLexicalFunction(HandlePropertyName name,
|
||||
bool* tryAnnexB)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(context), TraceLogger_FrontendNameAnalysis);
|
||||
|
||||
Maybe<DeclarationKind> redeclaredKind;
|
||||
if (!tryDeclareVar(name, DeclarationKind::VarForAnnexBLexicalFunction, &redeclaredKind))
|
||||
return false;
|
||||
|
@ -1307,6 +1311,8 @@ bool
|
|||
Parser<ParseHandler>::noteDeclaredName(HandlePropertyName name, DeclarationKind kind,
|
||||
TokenPos pos)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(context), TraceLogger_FrontendNameAnalysis);
|
||||
|
||||
// The asm.js validator does all its own symbol-table management so, as an
|
||||
// optimization, avoid doing any work here.
|
||||
if (pc->useAsmOrInsideUseAsm())
|
||||
|
@ -1459,6 +1465,8 @@ template <typename ParseHandler>
|
|||
bool
|
||||
Parser<ParseHandler>::noteUsedName(HandlePropertyName name)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(context), TraceLogger_FrontendNameAnalysis);
|
||||
|
||||
// If the we are delazifying, the LazyScript already has all the
|
||||
// closed-over info for bindings and there's no need to track used names.
|
||||
if (handler.canSkipLazyClosedOverBindings())
|
||||
|
@ -1484,6 +1492,8 @@ template <typename ParseHandler>
|
|||
bool
|
||||
Parser<ParseHandler>::hasUsedName(HandlePropertyName name)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(context), TraceLogger_FrontendNameAnalysis);
|
||||
|
||||
if (UsedNamePtr p = usedNames.lookup(name))
|
||||
return p->value().isUsedInScript(pc->scriptId());
|
||||
return false;
|
||||
|
@ -1493,6 +1503,8 @@ template <typename ParseHandler>
|
|||
bool
|
||||
Parser<ParseHandler>::propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope)
|
||||
{
|
||||
AutoTraceLog traceLog(TraceLoggerForCurrentThread(context), TraceLogger_FrontendNameAnalysis);
|
||||
|
||||
if (handler.canSkipLazyClosedOverBindings()) {
|
||||
// Scopes are nullptr-delimited in the LazyScript closed over bindings
|
||||
// array.
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "mozilla/Array.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#include "jspubtd.h"
|
||||
|
||||
|
@ -255,6 +256,9 @@ class ParseContext : public Nestable<ParseContext>
|
|||
};
|
||||
|
||||
private:
|
||||
// Trace logging of parsing time.
|
||||
AutoFrontendTraceLog traceLog_;
|
||||
|
||||
// Context shared between parsing and bytecode generation.
|
||||
SharedContext* sc_;
|
||||
|
||||
|
@ -351,6 +355,11 @@ class ParseContext : public Nestable<ParseContext>
|
|||
template <typename ParseHandler>
|
||||
ParseContext(Parser<ParseHandler>* prs, SharedContext* sc, Directives* newDirectives)
|
||||
: Nestable<ParseContext>(&prs->pc),
|
||||
traceLog_(sc->context,
|
||||
mozilla::IsSame<ParseHandler, FullParseHandler>::value
|
||||
? TraceLogger_ParsingFull
|
||||
: TraceLogger_ParsingSyntax,
|
||||
prs->tokenStream),
|
||||
sc_(sc),
|
||||
tokenStream_(prs->tokenStream),
|
||||
innermostStatement_(nullptr),
|
||||
|
|
|
@ -1296,6 +1296,10 @@ static_assert(LastCharKind < (1 << (sizeof(firstCharKinds[0]) * 8)),
|
|||
bool
|
||||
TokenStream::getTokenInternal(TokenKind* ttp, Modifier modifier)
|
||||
{
|
||||
// The assumption is that the cost of other tokenizer code is dwarfed by
|
||||
// this one.
|
||||
AutoTraceLog tokenizerLog(TraceLoggerForCurrentThread(cx), TraceLogger_Tokenizing);
|
||||
|
||||
int c;
|
||||
uint32_t qc;
|
||||
Token* tp;
|
||||
|
|
|
@ -427,7 +427,7 @@ TraceLoggerThreadState::getOrCreateEventPayload(TraceLoggerTextId type, const ch
|
|||
size_t lineno, size_t colno, const void* ptr)
|
||||
{
|
||||
MOZ_ASSERT(type == TraceLogger_Scripts || type == TraceLogger_AnnotateScripts ||
|
||||
type == TraceLogger_InlinedScripts);
|
||||
type == TraceLogger_InlinedScripts || type == TraceLogger_Frontend);
|
||||
|
||||
if (!filename)
|
||||
filename = "<unknown>";
|
||||
|
@ -500,13 +500,6 @@ TraceLoggerThreadState::getOrCreateEventPayload(TraceLoggerTextId type, JSScript
|
|||
nullptr);
|
||||
}
|
||||
|
||||
TraceLoggerEventPayload*
|
||||
TraceLoggerThreadState::getOrCreateEventPayload(TraceLoggerTextId type,
|
||||
const JS::ReadOnlyCompileOptions& script)
|
||||
{
|
||||
return getOrCreateEventPayload(type, script.filename(), script.lineno, script.column, nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
TraceLoggerThreadState::purgeUnusedPayloads()
|
||||
{
|
||||
|
@ -736,9 +729,9 @@ TraceLoggerThreadState::init()
|
|||
" Default Output all default. It includes:\n"
|
||||
" AnnotateScripts, Bailout, Baseline, BaselineCompilation, GC,\n"
|
||||
" GCAllocation, GCSweeping, Interpreter, IonAnalysis, IonCompilation,\n"
|
||||
" IonLinking, IonMonkey, MinorGC, ParserCompileFunction,\n"
|
||||
" ParserCompileScript, ParserCompileLazy, ParserCompileModule,\n"
|
||||
" IrregexpCompile, IrregexpExecute, Scripts, Engine, WasmCompilation\n"
|
||||
" IonLinking, IonMonkey, MinorGC, Frontend, ParsingFull,\n"
|
||||
" ParsingSyntax, BytecodeEmission, IrregexpCompile, IrregexpExecute,\n"
|
||||
" Scripts, Engine, WasmCompilation\n"
|
||||
"\n"
|
||||
" IonCompiler Output all information about compilation. It includes:\n"
|
||||
" IonCompilation, IonLinking, PruneUnusedBranches, FoldTests,\n"
|
||||
|
@ -751,8 +744,11 @@ TraceLoggerThreadState::init()
|
|||
" AddKeepAliveInstructions, GenerateLIR, RegisterAllocation, \n"
|
||||
" GenerateCode, Scripts, IonBuilderRestartLoop\n"
|
||||
"\n"
|
||||
" VMSpecific Output the specific name of the VM call"
|
||||
" VMSpecific Output the specific name of the VM call\n"
|
||||
"\n"
|
||||
" Frontend Output all information about frontend compilation. It includes:\n"
|
||||
" Frontend, ParsingFull, ParsingSyntax, Tokenizing,\n"
|
||||
" BytecodeEmission, BytecodeFoldConstants, BytecodeNameFunctions\n"
|
||||
"Specific log items:\n"
|
||||
);
|
||||
for (uint32_t i = 1; i < TraceLogger_Last; i++) {
|
||||
|
@ -788,10 +784,10 @@ TraceLoggerThreadState::init()
|
|||
enabledTextIds[TraceLogger_IonLinking] = true;
|
||||
enabledTextIds[TraceLogger_IonMonkey] = true;
|
||||
enabledTextIds[TraceLogger_MinorGC] = true;
|
||||
enabledTextIds[TraceLogger_ParserCompileFunction] = true;
|
||||
enabledTextIds[TraceLogger_ParserCompileLazy] = true;
|
||||
enabledTextIds[TraceLogger_ParserCompileScript] = true;
|
||||
enabledTextIds[TraceLogger_ParserCompileModule] = true;
|
||||
enabledTextIds[TraceLogger_Frontend] = true;
|
||||
enabledTextIds[TraceLogger_ParsingFull] = true;
|
||||
enabledTextIds[TraceLogger_ParsingSyntax] = true;
|
||||
enabledTextIds[TraceLogger_BytecodeEmission] = true;
|
||||
enabledTextIds[TraceLogger_IrregexpCompile] = true;
|
||||
enabledTextIds[TraceLogger_IrregexpExecute] = true;
|
||||
enabledTextIds[TraceLogger_Scripts] = true;
|
||||
|
@ -833,6 +829,18 @@ TraceLoggerThreadState::init()
|
|||
enabledTextIds[TraceLogger_IonBuilderRestartLoop] = true;
|
||||
}
|
||||
|
||||
if (ContainsFlag(env, "Frontend")) {
|
||||
enabledTextIds[TraceLogger_Frontend] = true;
|
||||
enabledTextIds[TraceLogger_FrontendNameAnalysis] = true;
|
||||
enabledTextIds[TraceLogger_FrontendTDZAnalysis] = true;
|
||||
enabledTextIds[TraceLogger_ParsingFull] = true;
|
||||
enabledTextIds[TraceLogger_ParsingSyntax] = true;
|
||||
enabledTextIds[TraceLogger_Tokenizing] = true;
|
||||
enabledTextIds[TraceLogger_BytecodeEmission] = true;
|
||||
enabledTextIds[TraceLogger_BytecodeFoldConstants] = true;
|
||||
enabledTextIds[TraceLogger_BytecodeNameFunctions] = true;
|
||||
}
|
||||
|
||||
enabledTextIds[TraceLogger_Interpreter] = enabledTextIds[TraceLogger_Engine];
|
||||
enabledTextIds[TraceLogger_Baseline] = enabledTextIds[TraceLogger_Engine];
|
||||
enabledTextIds[TraceLogger_IonMonkey] = enabledTextIds[TraceLogger_Engine];
|
||||
|
@ -1014,10 +1022,13 @@ TraceLoggerEvent::TraceLoggerEvent(TraceLoggerTextId type, JSScript* script)
|
|||
payload_ = traceLoggerState ? traceLoggerState->getOrCreateEventPayload(type, script) : nullptr;
|
||||
}
|
||||
|
||||
TraceLoggerEvent::TraceLoggerEvent(TraceLoggerTextId type,
|
||||
const JS::ReadOnlyCompileOptions& compileOptions)
|
||||
TraceLoggerEvent::TraceLoggerEvent(TraceLoggerTextId type, const char* filename, size_t line,
|
||||
size_t column)
|
||||
|
||||
{
|
||||
payload_ = traceLoggerState ? traceLoggerState->getOrCreateEventPayload(type, compileOptions) : nullptr;
|
||||
payload_ = traceLoggerState
|
||||
? traceLoggerState->getOrCreateEventPayload(type, filename, line, column, nullptr)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
TraceLoggerEvent::TraceLoggerEvent(const char* text)
|
||||
|
|
|
@ -88,8 +88,7 @@ class TraceLoggerEvent {
|
|||
#ifdef JS_TRACE_LOGGING
|
||||
explicit TraceLoggerEvent(TraceLoggerTextId textId);
|
||||
TraceLoggerEvent(TraceLoggerTextId type, JSScript* script);
|
||||
TraceLoggerEvent(TraceLoggerTextId type,
|
||||
const JS::ReadOnlyCompileOptions& compileOptions);
|
||||
TraceLoggerEvent(TraceLoggerTextId type, const char* filename, size_t line, size_t column);
|
||||
explicit TraceLoggerEvent(const char* text);
|
||||
TraceLoggerEvent(const TraceLoggerEvent& event);
|
||||
TraceLoggerEvent& operator=(const TraceLoggerEvent& other);
|
||||
|
@ -97,8 +96,7 @@ class TraceLoggerEvent {
|
|||
#else
|
||||
explicit TraceLoggerEvent(TraceLoggerTextId textId) {}
|
||||
TraceLoggerEvent(TraceLoggerTextId type, JSScript* script) {}
|
||||
TraceLoggerEvent(TraceLoggerTextId type,
|
||||
const JS::ReadOnlyCompileOptions& compileOptions) {}
|
||||
TraceLoggerEvent(TraceLoggerTextId type, const char* filename, size_t line, size_t column) {}
|
||||
explicit TraceLoggerEvent(const char* text) {}
|
||||
TraceLoggerEvent(const TraceLoggerEvent& event) {}
|
||||
TraceLoggerEvent& operator=(const TraceLoggerEvent& other) { return *this; };
|
||||
|
@ -383,9 +381,6 @@ class TraceLoggerThreadState
|
|||
TraceLoggerEventPayload* getOrCreateEventPayload(TraceLoggerTextId textId);
|
||||
TraceLoggerEventPayload* getOrCreateEventPayload(const char* text);
|
||||
TraceLoggerEventPayload* getOrCreateEventPayload(TraceLoggerTextId type, JSScript* script);
|
||||
TraceLoggerEventPayload* getOrCreateEventPayload(TraceLoggerTextId type,
|
||||
const JS::ReadOnlyCompileOptions& script);
|
||||
private:
|
||||
TraceLoggerEventPayload* getOrCreateEventPayload(TraceLoggerTextId type, const char* filename,
|
||||
size_t lineno, size_t colno, const void* p);
|
||||
#endif
|
||||
|
|
|
@ -29,10 +29,15 @@
|
|||
_(IrregexpCompile) \
|
||||
_(IrregexpExecute) \
|
||||
_(MinorGC) \
|
||||
_(ParserCompileFunction) \
|
||||
_(ParserCompileLazy) \
|
||||
_(ParserCompileScript) \
|
||||
_(ParserCompileModule) \
|
||||
_(Frontend) \
|
||||
_(FrontendNameAnalysis) \
|
||||
_(FrontendTDZAnalysis) \
|
||||
_(ParsingFull) \
|
||||
_(ParsingSyntax) \
|
||||
_(Tokenizing) \
|
||||
_(BytecodeEmission) \
|
||||
_(BytecodeFoldConstants) \
|
||||
_(BytecodeNameFunctions) \
|
||||
_(DecodeScript) \
|
||||
_(DecodeFunction) \
|
||||
_(EncodeScript) \
|
||||
|
|
Загрузка…
Ссылка в новой задаче