Bug 1234985 - Odin: make names optional and supplied at the end (r=bbouvier)

This commit is contained in:
Luke Wagner 2016-01-21 20:48:58 -06:00
parent e9a675dbb6
commit 84a3c0a3e6
7 changed files with 162 additions and 133 deletions

View File

@ -2274,6 +2274,13 @@ class MOZ_STACK_CLASS ModuleValidator
return false;
}
CacheableCharsVector funcNames;
for (const Func* func : functions_) {
CacheableChars funcName = StringToNewUTF8CharsZ(cx_, *func->name());
if (!funcName || !funcNames.emplaceBack(Move(funcName)))
return false;
}
uint32_t endBeforeCurly = tokenStream().currentToken().pos.end;
module_->srcLength = endBeforeCurly - module_->srcStart;
@ -2284,7 +2291,7 @@ class MOZ_STACK_CLASS ModuleValidator
UniqueModuleData base;
UniqueStaticLinkData link;
if (!mg_.finish(heap, Move(filename), &base, &link, slowFuncs))
if (!mg_.finish(heap, Move(filename), Move(funcNames), &base, &link, slowFuncs))
return false;
moduleObj.set(WasmModuleObject::create(cx_));
@ -2633,11 +2640,11 @@ class MOZ_STACK_CLASS FunctionValidator
ExclusiveContext* cx() const { return m_.cx(); }
ParseNode* fn() const { return fn_; }
bool init(PropertyName* name, unsigned line, unsigned column) {
bool init(PropertyName* name, unsigned line) {
if (!locals_.init() || !labels_.init())
return false;
if (!m_.mg().startFuncDef(name, line, column, &fg_))
if (!m_.mg().startFuncDef(line, &fg_))
return false;
encoder_.emplace(fg_.bytecode());
@ -6706,12 +6713,12 @@ CheckStatement(FunctionValidator& f, ParseNode* stmt)
}
static bool
ParseFunction(ModuleValidator& m, ParseNode** fnOut, unsigned* line, unsigned* column)
ParseFunction(ModuleValidator& m, ParseNode** fnOut, unsigned* line)
{
TokenStream& tokenStream = m.tokenStream();
tokenStream.consumeKnownToken(TOK_FUNCTION, TokenStream::Operand);
tokenStream.srcCoords.lineNumAndColumnIndex(tokenStream.currentToken().pos.end, line, column);
*line = tokenStream.srcCoords.lineNum(tokenStream.currentToken().pos.end);
RootedPropertyName name(m.cx());
@ -6778,15 +6785,15 @@ CheckFunction(ModuleValidator& m)
int64_t before = PRMJ_Now();
ParseNode* fn = nullptr;
unsigned line = 0, column = 0;
if (!ParseFunction(m, &fn, &line, &column))
unsigned line = 0;
if (!ParseFunction(m, &fn, &line))
return false;
if (!CheckFunctionHead(m, fn))
return false;
FunctionValidator f(m, fn);
if (!f.init(FunctionName(fn), line, column))
if (!f.init(FunctionName(fn), line))
return m.fail(fn, "internal compiler failure (probably out of memory)");
ParseNode* stmtIter = ListHead(FunctionStatementList(fn));
@ -8279,12 +8286,11 @@ BuildConsoleMessage(ExclusiveContext* cx, AsmJSModule& module, unsigned time,
for (unsigned i = 0; i < slowFuncs.length(); i++) {
const SlowFunction& func = slowFuncs[i];
JSAutoByteString name;
if (!AtomToPrintableString(cx, func.name, &name))
return nullptr;
slowText.reset(JS_smprintf("%s%s:%u:%u (%ums)%s", slowText.get(),
name.ptr(), func.line, func.column, func.ms,
slowText.reset(JS_smprintf("%s%s:%u (%ums)%s",
slowText.get(),
module.prettyFuncName(func.index),
func.lineOrBytecode,
func.ms,
i+1 < slowFuncs.length() ? ", " : ""));
if (!slowText)
return nullptr;

View File

@ -603,15 +603,10 @@ typedef Vector<SourceCoords, 0, SystemAllocPolicy> SourceCoordsVector;
class FuncBytecode
{
// Function metadata
SourceCoordsVector callSourceCoords_;
const DeclaredSig& sig_;
ValTypeVector locals_;
// Note: this unrooted field assumes AutoKeepAtoms via TokenStream via
// asm.js compilation.
PropertyName* name_;
unsigned line_;
unsigned column_;
uint32_t lineOrBytecode_;
SourceCoordsVector callSourceCoords_;
// Compilation bookkeeping
uint32_t index_;
@ -620,21 +615,17 @@ class FuncBytecode
UniqueBytecode bytecode_;
public:
FuncBytecode(PropertyName* name,
unsigned line,
unsigned column,
SourceCoordsVector&& sourceCoords,
uint32_t index,
FuncBytecode(uint32_t index,
const DeclaredSig& sig,
UniqueBytecode bytecode,
ValTypeVector&& locals,
uint32_t lineOrBytecode,
SourceCoordsVector&& sourceCoords,
unsigned generateTime)
: callSourceCoords_(Move(sourceCoords)),
sig_(sig),
: sig_(sig),
locals_(Move(locals)),
name_(name),
line_(line),
column_(column),
lineOrBytecode_(lineOrBytecode),
callSourceCoords_(Move(sourceCoords)),
index_(index),
generateTime_(generateTime),
bytecode_(Move(bytecode))
@ -642,9 +633,7 @@ class FuncBytecode
UniqueBytecode recycleBytecode() { return Move(bytecode_); }
PropertyName* name() const { return name_; }
unsigned line() const { return line_; }
unsigned column() const { return column_; }
uint32_t lineOrBytecode() const { return lineOrBytecode_; }
const SourceCoords& sourceCoords(size_t i) const { return callSourceCoords_[i]; }
uint32_t index() const { return index_; }

View File

@ -106,7 +106,13 @@ FrameIterator::functionDisplayAtom() const
{
MOZ_ASSERT(!done());
const char* chars = module_->functionName(codeRange_->funcNameIndex());
UniqueChars owner;
const char* chars = module_->getFuncName(cx_, codeRange_->funcIndex(), &owner);
if (!chars) {
cx_->clearPendingException();
return cx_->names().empty;
}
JSAtom* atom = AtomizeUTF8Chars(cx_, chars, strlen(chars));
if (!atom) {
cx_->clearPendingException();
@ -693,7 +699,7 @@ ProfilingFrameIterator::label() const
}
switch (codeRange_->kind()) {
case CodeRange::Function: return module_->profilingLabel(codeRange_->funcNameIndex());
case CodeRange::Function: return module_->profilingLabel(codeRange_->funcIndex());
case CodeRange::Entry: return "entry trampoline (in asm.js)";
case CodeRange::ImportJitExit: return importJitDescription;
case CodeRange::ImportInterpExit: return importInterpDescription;

View File

@ -38,7 +38,6 @@ ModuleGenerator::ModuleGenerator(ExclusiveContext* cx)
jcx_(CompileRuntime::get(cx->compartment()->runtimeFromAnyThread())),
slowFuncs_(cx),
numSigs_(0),
numFuncSigs_(0),
lifo_(GENERATOR_LIFO_DEFAULT_CHUNK_SIZE),
alloc_(&lifo_),
masm_(MacroAssembler::AsmJSToken(), alloc_),
@ -125,7 +124,7 @@ ModuleGenerator::init(UniqueModuleGeneratorData shared, ModuleKind kind)
shared_ = Move(shared);
if (kind == ModuleKind::Wasm) {
numSigs_ = shared_->sigs.length();
numFuncSigs_ = shared_->funcSigs.length();
module_->numFuncs = shared_->funcSigs.length();
for (uint32_t i = 0; i < shared_->imports.length(); i++) {
if (!addImport(*shared_->imports[i].sig, shared_->imports[i].globalDataOffset))
return false;
@ -189,19 +188,13 @@ ModuleGenerator::finishTask(IonCompileTask* task)
MOZ_ASSERT(masm_.size() == offsetInWhole + results.masm().size());
// Add the CodeRange for this function.
CacheableChars funcName = StringToNewUTF8CharsZ(cx_, *func.name());
if (!funcName)
return false;
uint32_t nameIndex = module_->funcNames.length();
if (!module_->funcNames.emplaceBack(Move(funcName)))
return false;
if (!module_->codeRanges.emplaceBack(nameIndex, func.line(), results.offsets()))
if (!module_->codeRanges.emplaceBack(func.index(), func.lineOrBytecode(), results.offsets()))
return false;
// Keep a record of slow functions for printing in the final console message.
unsigned totalTime = func.generateTime() + results.compileTime();
if (totalTime >= SlowFunction::msThreshold) {
if (!slowFuncs_.emplaceBack(func.name(), totalTime, func.line(), func.column()))
if (!slowFuncs_.emplaceBack(func.index(), totalTime, func.lineOrBytecode()))
return false;
}
@ -287,10 +280,10 @@ bool
ModuleGenerator::initFuncSig(uint32_t funcIndex, uint32_t sigIndex)
{
MOZ_ASSERT(module_->kind == ModuleKind::AsmJS);
MOZ_ASSERT(funcIndex == numFuncSigs_);
MOZ_ASSERT(funcIndex == module_->numFuncs);
MOZ_ASSERT(!shared_->funcSigs[funcIndex]);
numFuncSigs_++;
module_->numFuncs++;
shared_->funcSigs[funcIndex] = &shared_->sigs[sigIndex];
return true;
}
@ -430,8 +423,7 @@ ModuleGenerator::startFuncDefs()
}
bool
ModuleGenerator::startFuncDef(PropertyName* name, unsigned line, unsigned column,
FunctionGenerator* fg)
ModuleGenerator::startFuncDef(uint32_t lineOrBytecode, FunctionGenerator* fg)
{
MOZ_ASSERT(startedFuncDefs());
MOZ_ASSERT(!activeFunc_);
@ -451,9 +443,7 @@ ModuleGenerator::startFuncDef(PropertyName* name, unsigned line, unsigned column
return false;
}
fg->name_= name;
fg->line_ = line;
fg->column_ = column;
fg->lineOrBytecode_ = lineOrBytecode;
fg->m_ = this;
fg->task_ = task;
activeFunc_ = fg;
@ -466,14 +456,12 @@ ModuleGenerator::finishFuncDef(uint32_t funcIndex, unsigned generateTime, Functi
MOZ_ASSERT(activeFunc_ == fg);
UniqueFuncBytecode func =
js::MakeUnique<FuncBytecode>(fg->name_,
fg->line_,
fg->column_,
Move(fg->callSourceCoords_),
funcIndex,
js::MakeUnique<FuncBytecode>(funcIndex,
funcSig(funcIndex),
Move(fg->bytecode_),
Move(fg->localVars_),
fg->lineOrBytecode_,
Move(fg->callSourceCoords_),
generateTime);
if (!func)
return false;
@ -607,6 +595,7 @@ ModuleGenerator::defineOutOfBoundsStub(Offsets offsets)
bool
ModuleGenerator::finish(HeapUsage heapUsage,
CacheableChars filename,
CacheableCharsVector&& prettyFuncNames,
UniqueModuleData* module,
UniqueStaticLinkData* linkData,
SlowFunctionVector* slowFuncs)
@ -616,6 +605,7 @@ ModuleGenerator::finish(HeapUsage heapUsage,
module_->heapUsage = heapUsage;
module_->filename = Move(filename);
module_->prettyFuncNames = Move(prettyFuncNames);
if (!GenerateStubs(*this, UsesHeap(heapUsage)))
return false;

View File

@ -35,16 +35,15 @@ typedef Vector<uint32_t, 0, SystemAllocPolicy> Uint32Vector;
struct SlowFunction
{
SlowFunction(PropertyName* name, unsigned ms, unsigned line, unsigned column)
: name(name), ms(ms), line(line), column(column)
SlowFunction(uint32_t index, unsigned ms, unsigned lineOrBytecode)
: index(index), ms(ms), lineOrBytecode(lineOrBytecode)
{}
static const unsigned msThreshold = 250;
PropertyName* name;
uint32_t index;
unsigned ms;
unsigned line;
unsigned column;
unsigned lineOrBytecode;
};
typedef Vector<SlowFunction> SlowFunctionVector;
@ -138,7 +137,6 @@ class MOZ_STACK_CLASS ModuleGenerator
// Data scoped to the ModuleGenerator's lifetime
UniqueModuleGeneratorData shared_;
uint32_t numSigs_;
uint32_t numFuncSigs_;
LifoAlloc lifo_;
jit::TempAllocator alloc_;
jit::MacroAssembler masm_;
@ -160,6 +158,7 @@ class MOZ_STACK_CLASS ModuleGenerator
bool finishOutstandingTask();
bool finishTask(IonCompileTask* task);
bool addImport(const Sig& sig, uint32_t globalDataOffset);
bool startedFuncDefs() const { return !!threadView_; }
public:
explicit ModuleGenerator(ExclusiveContext* cx);
@ -183,7 +182,7 @@ class MOZ_STACK_CLASS ModuleGenerator
// Function declarations:
bool initFuncSig(uint32_t funcIndex, uint32_t sigIndex);
uint32_t numFuncSigs() const { return numFuncSigs_; }
uint32_t numFuncSigs() const { return module_->numFuncs; }
const DeclaredSig& funcSig(uint32_t funcIndex) const;
// Imports:
@ -201,8 +200,7 @@ class MOZ_STACK_CLASS ModuleGenerator
// Function definitions:
bool startFuncDefs();
bool startedFuncDefs() const { return !!threadView_; }
bool startFuncDef(PropertyName* name, unsigned line, unsigned column, FunctionGenerator* fg);
bool startFuncDef(uint32_t lineOrBytecode, FunctionGenerator* fg);
bool finishFuncDef(uint32_t funcIndex, unsigned generateTime, FunctionGenerator* fg);
bool finishFuncDefs();
@ -222,6 +220,7 @@ class MOZ_STACK_CLASS ModuleGenerator
// functions that took a long time to compile.
bool finish(HeapUsage heapUsage,
CacheableChars filename,
CacheableCharsVector&& prettyFuncNames,
UniqueModuleData* module,
UniqueStaticLinkData* staticLinkData,
SlowFunctionVector* slowFuncs);
@ -246,19 +245,11 @@ class MOZ_STACK_CLASS FunctionGenerator
SourceCoordsVector callSourceCoords_;
ValTypeVector localVars_;
// Note: this unrooted field assumes AutoKeepAtoms via TokenStream via
// asm.js compilation.
PropertyName* name_;
unsigned line_;
unsigned column_;
uint32_t lineOrBytecode_;
public:
FunctionGenerator()
: m_(nullptr),
task_(nullptr),
name_(nullptr),
line_(0),
column_(0)
: m_(nullptr), task_(nullptr), lineOrBytecode_(0)
{}
Bytecode& bytecode() const {

View File

@ -351,8 +351,8 @@ Import::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const
}
CodeRange::CodeRange(Kind kind, Offsets offsets)
: nameIndex_(0),
lineNumber_(0),
: funcIndex_(0),
funcLineOrBytecode_(0),
begin_(offsets.begin),
profilingReturn_(0),
end_(offsets.end)
@ -365,8 +365,8 @@ CodeRange::CodeRange(Kind kind, Offsets offsets)
}
CodeRange::CodeRange(Kind kind, ProfilingOffsets offsets)
: nameIndex_(0),
lineNumber_(0),
: funcIndex_(0),
funcLineOrBytecode_(0),
begin_(offsets.begin),
profilingReturn_(offsets.profilingReturn),
end_(offsets.end)
@ -379,9 +379,9 @@ CodeRange::CodeRange(Kind kind, ProfilingOffsets offsets)
MOZ_ASSERT(u.kind_ == ImportJitExit || u.kind_ == ImportInterpExit || u.kind_ == Interrupt);
}
CodeRange::CodeRange(uint32_t nameIndex, uint32_t lineNumber, FuncOffsets offsets)
: nameIndex_(nameIndex),
lineNumber_(lineNumber)
CodeRange::CodeRange(uint32_t funcIndex, uint32_t funcLineOrBytecode, FuncOffsets offsets)
: funcIndex_(funcIndex),
funcLineOrBytecode_(funcLineOrBytecode)
{
PodZero(&u); // zero padding for Valgrind
u.kind_ = Function;
@ -509,7 +509,7 @@ ModuleData::serializedSize() const
SerializedPodVectorSize(heapAccesses) +
SerializedPodVectorSize(codeRanges) +
SerializedPodVectorSize(callSites) +
SerializedVectorSize(funcNames) +
SerializedVectorSize(prettyFuncNames) +
filename.serializedSize();
}
@ -523,7 +523,7 @@ ModuleData::serialize(uint8_t* cursor) const
cursor = SerializePodVector(cursor, heapAccesses);
cursor = SerializePodVector(cursor, codeRanges);
cursor = SerializePodVector(cursor, callSites);
cursor = SerializeVector(cursor, funcNames);
cursor = SerializeVector(cursor, prettyFuncNames);
cursor = filename.serialize(cursor);
return cursor;
}
@ -543,7 +543,7 @@ ModuleData::deserialize(ExclusiveContext* cx, const uint8_t* cursor)
(cursor = DeserializePodVector(cx, cursor, &heapAccesses)) &&
(cursor = DeserializePodVector(cx, cursor, &codeRanges)) &&
(cursor = DeserializePodVector(cx, cursor, &callSites)) &&
(cursor = DeserializeVector(cx, cursor, &funcNames)) &&
(cursor = DeserializeVector(cx, cursor, &prettyFuncNames)) &&
(cursor = filename.deserialize(cx, cursor));
return cursor;
}
@ -563,7 +563,7 @@ ModuleData::clone(JSContext* cx, ModuleData* out) const
ClonePodVector(cx, heapAccesses, &out->heapAccesses) &&
ClonePodVector(cx, codeRanges, &out->codeRanges) &&
ClonePodVector(cx, callSites, &out->callSites) &&
CloneVector(cx, funcNames, &out->funcNames) &&
CloneVector(cx, prettyFuncNames, &out->prettyFuncNames) &&
filename.clone(cx, &out->filename);
}
@ -576,7 +576,7 @@ ModuleData::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const
heapAccesses.sizeOfExcludingThis(mallocSizeOf) +
codeRanges.sizeOfExcludingThis(mallocSizeOf) +
callSites.sizeOfExcludingThis(mallocSizeOf) +
funcNames.sizeOfExcludingThis(mallocSizeOf) +
prettyFuncNames.sizeOfExcludingThis(mallocSizeOf) +
filename.sizeOfExcludingThis(mallocSizeOf);
}
@ -680,41 +680,50 @@ Module::despecializeFromHeap(ArrayBufferObjectMaybeShared* heap)
rawHeapPtr() = nullptr;
}
void
bool
Module::sendCodeRangesToProfiler(JSContext* cx)
{
bool enabled = false;
#ifdef JS_ION_PERF
if (PerfFuncEnabled()) {
for (const CodeRange& codeRange : module_->codeRanges) {
if (!codeRange.isFunction())
continue;
uintptr_t start = uintptr_t(code() + codeRange.begin());
uintptr_t end = uintptr_t(code() + codeRange.end());
uintptr_t size = end - start;
const char* file = module_->filename.get();
unsigned line = codeRange.funcLineNumber();
unsigned column = 0;
const char* name = module_->funcNames[codeRange.funcNameIndex()].get();
writePerfSpewerAsmJSFunctionMap(start, size, file, line, column, name);
}
}
enabled |= PerfFuncEnabled();
#endif
#ifdef MOZ_VTUNE
if (IsVTuneProfilingActive()) {
for (const CodeRange& codeRange : module_->codeRanges) {
if (!codeRange.isFunction())
continue;
enabled |= IsVTuneProfilingActive();
#endif
if (!enabled)
return true;
uintptr_t start = uintptr_t(code() + codeRange.begin());
uintptr_t end = uintptr_t(code() + codeRange.end());
uintptr_t size = end - start;
const char* name = module_->funcNames[codeRange.funcNameIndex()].get();
for (const CodeRange& codeRange : module_->codeRanges) {
if (!codeRange.isFunction())
continue;
uintptr_t start = uintptr_t(code() + codeRange.begin());
uintptr_t end = uintptr_t(code() + codeRange.end());
uintptr_t size = end - start;
UniqueChars owner;
const char* name = getFuncName(cx, codeRange.funcIndex(), &owner);
if (!name)
return false;
// Avoid "unused" warnings
(void)start;
(void)size;
(void)name;
#ifdef JS_ION_PERF
if (PerfFuncEnabled()) {
const char* file = module_->filename.get();
unsigned line = codeRange.funcLineOrBytecode();
unsigned column = 0;
writePerfSpewerAsmJSFunctionMap(start, size, file, line, column, name);
}
#endif
#ifdef MOZ_VTUNE
if (IsVTuneProfilingActive()) {
unsigned method_id = iJIT_GetNewMethodID();
if (method_id == 0)
return;
return true;
iJIT_Method_Load method;
method.method_id = method_id;
method.method_name = const_cast<char*>(name);
@ -727,8 +736,10 @@ Module::sendCodeRangesToProfiler(JSContext* cx)
method.source_file_name = nullptr;
iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&method);
}
}
#endif
}
return true;
}
bool
@ -745,21 +756,29 @@ Module::setProfilingEnabled(JSContext* cx, bool enabled)
// do it now since, once we start sampling, we'll be in a signal-handing
// context where we cannot malloc.
if (enabled) {
if (!funcLabels_.resize(module_->funcNames.length())) {
if (!funcLabels_.resize(module_->numFuncs)) {
ReportOutOfMemory(cx);
return false;
}
for (const CodeRange& codeRange : module_->codeRanges) {
if (!codeRange.isFunction())
continue;
unsigned lineno = codeRange.funcLineNumber();
const char* name = module_->funcNames[codeRange.funcNameIndex()].get();
UniqueChars label(JS_smprintf("%s (%s:%u)", name, module_->filename.get(), lineno));
UniqueChars owner;
const char* funcName = getFuncName(cx, codeRange.funcIndex(), &owner);
if (!funcName)
return false;
UniqueChars label(JS_smprintf("%s (%s:%u)",
funcName,
module_->filename.get(),
codeRange.funcLineOrBytecode()));
if (!label) {
ReportOutOfMemory(cx);
return false;
}
funcLabels_[codeRange.funcNameIndex()] = Move(label);
funcLabels_[codeRange.funcIndex()] = Move(label);
}
} else {
funcLabels_.clear();
@ -1082,8 +1101,7 @@ Module::dynamicallyLink(JSContext* cx, Handle<ArrayBufferObjectMaybeShared*> hea
return false;
}
sendCodeRangesToProfiler(cx);
return true;
return sendCodeRangesToProfiler(cx);
}
static bool
@ -1408,6 +1426,28 @@ Module::callImport(JSContext* cx, uint32_t importIndex, unsigned argc, const Val
return true;
}
const char*
Module::prettyFuncName(uint32_t funcIndex) const
{
return module_->prettyFuncNames[funcIndex].get();
}
const char*
Module::getFuncName(JSContext* cx, uint32_t funcIndex, UniqueChars* owner) const
{
if (!module_->prettyFuncNames.empty())
return prettyFuncName(funcIndex);
char* chars = JS_smprintf("wasm-function[%u]", funcIndex);
if (!chars) {
ReportOutOfMemory(cx);
return nullptr;
}
owner->reset(chars);
return chars;
}
const char*
Module::profilingLabel(uint32_t funcIndex) const
{

View File

@ -197,8 +197,8 @@ typedef Vector<Import, 0, SystemAllocPolicy> ImportVector;
class CodeRange
{
// All fields are treated as cacheable POD:
uint32_t nameIndex_;
uint32_t lineNumber_;
uint32_t funcIndex_;
uint32_t funcLineOrBytecode_;
uint32_t begin_;
uint32_t profilingReturn_;
uint32_t end_;
@ -220,7 +220,7 @@ class CodeRange
CodeRange() = default;
CodeRange(Kind kind, Offsets offsets);
CodeRange(Kind kind, ProfilingOffsets offsets);
CodeRange(uint32_t nameIndex, uint32_t lineNumber, FuncOffsets offsets);
CodeRange(uint32_t funcIndex, uint32_t lineOrBytecode, FuncOffsets offsets);
// All CodeRanges have a begin and end.
@ -265,13 +265,13 @@ class CodeRange
MOZ_ASSERT(isFunction());
return profilingReturn_ - u.func.profilingEpilogueToProfilingReturn_;
}
uint32_t funcNameIndex() const {
uint32_t funcIndex() const {
MOZ_ASSERT(isFunction());
return nameIndex_;
return funcIndex_;
}
uint32_t funcLineNumber() const {
uint32_t funcLineOrBytecode() const {
MOZ_ASSERT(isFunction());
return lineNumber_;
return funcLineOrBytecode_;
}
// A sorted array of CodeRanges can be looked up via BinarySearch and PC.
@ -366,6 +366,7 @@ struct ModuleCacheablePod
uint32_t functionBytes;
uint32_t codeBytes;
uint32_t globalBytes;
uint32_t numFuncs;
ModuleKind kind;
HeapUsage heapUsage;
CompileArgs compileArgs;
@ -389,7 +390,7 @@ struct ModuleData : ModuleCacheablePod
HeapAccessVector heapAccesses;
CodeRangeVector codeRanges;
CallSiteVector callSites;
CacheableCharsVector funcNames;
CacheableCharsVector prettyFuncNames;
CacheableChars filename;
bool loadedFromCache;
@ -466,7 +467,7 @@ class Module
WasmActivation*& activation();
void specializeToHeap(ArrayBufferObjectMaybeShared* heap);
void despecializeFromHeap(ArrayBufferObjectMaybeShared* heap);
void sendCodeRangesToProfiler(JSContext* cx);
bool sendCodeRangesToProfiler(JSContext* cx);
MOZ_WARN_UNUSED_RESULT bool setProfilingEnabled(JSContext* cx, bool enabled);
ImportExit& importToExit(const Import& import);
@ -496,7 +497,6 @@ class Module
CompileArgs compileArgs() const { return module_->compileArgs; }
const ImportVector& imports() const { return module_->imports; }
const ExportVector& exports() const { return module_->exports; }
const char* functionName(uint32_t i) const { return module_->funcNames[i].get(); }
const char* filename() const { return module_->filename.get(); }
bool loadedFromCache() const { return module_->loadedFromCache; }
bool staticallyLinked() const { return staticallyLinked_; }
@ -573,6 +573,13 @@ class Module
uint8_t* interrupt() const { MOZ_ASSERT(staticallyLinked_); return interrupt_; }
uint8_t* outOfBounds() const { MOZ_ASSERT(staticallyLinked_); return outOfBounds_; }
// Every function has an associated display atom which is either the pretty
// name given by the asm.js function name or wasm symbols or something
// generated from the function index.
const char* prettyFuncName(uint32_t funcIndex) const;
const char* getFuncName(JSContext* cx, uint32_t funcIndex, UniqueChars* owner) const;
// Each Module has a profilingEnabled state which is updated to match
// SPSProfiler::enabled() on the next Module::callExport when there are no
// frames from the Module on the stack. The ProfilingFrameIterator only